DYTSrouce/Tool/matlab/include/MatlabDataArray/Reference.hpp

310 lines
12 KiB
C++
Raw Normal View History

2024-11-22 15:19:31 +00:00
/* Copyright 2016-2020 The MathWorks, Inc. */
#ifndef MATLAB_EXTDATA_REFERENCE_HPP
#define MATLAB_EXTDATA_REFERENCE_HPP
#include "Enumeration.hpp"
#include "String.hpp"
#include "ReferenceHolder.hpp"
#include "ArrayReferenceExt.hpp"
#include "MATLABStringReferenceExt.hpp"
#include "Exception.hpp"
#include "GetArrayType.hpp"
#include "detail/publish_util.hpp"
#include "detail/FunctionType.hpp"
#include "detail/HelperFunctions.hpp"
#include "detail/ReferenceHelpers.hpp"
#include <memory>
#include <type_traits>
namespace matlab {
namespace data {
namespace detail {
class Access;
}
template <typename T> struct GetReferenceExt { using type = ReferenceHolder; };
template <> struct GetReferenceExt<Array> { using type = IndexableArrayRef<false>; };
template <> struct GetReferenceExt<MATLABString> { using type = MATLABStringReferenceExt; };
template <typename T>
class Reference : public GetReferenceExt<T>::type {
public:
typedef typename std::remove_const<T>::type ref_type;
using Parent = typename GetReferenceExt<T>::type;
using Parent::pImpl;
/**
* Cast to element from the array. Makes a copy of the element from the array
*
* @code
* Reference<Array> ref = cell_arr[0];
* Array cpy(ref);
* @endcode
*
* @return ref_type the element being referred to
* @throw ObjectNotAccessibleException - if iterating through an object array and the object in the array cannot be accessed
*/
operator ref_type() const {
return detail::getElement<ref_type>(pImpl);
}
/**
* Assign a value into an Array. The Array being indexed must be non-const.
*
* @code
* Reference<Array> ref = cell_arr[0];
* ref = factory.createScalar(false);
* @endcode
*
* @param rhs - value to be assigned into the Array
*
* @return Reference<T>& - this
* @throw InvalidHeterogeneousArrayException - if assigning an object to an ObjectArray that is not valid
*/
Reference<T>& operator= (T rhs) {
static_assert(!std::is_const<T>::value, "Can't modify a Reference to const data");
detail::setElement(pImpl.get(), std::move(rhs), static_cast<int>(GetArrayType<T>::type));
return *this;
}
/**
* Cast to std::string from the array. Makes a copy of the std::string. Only
* valid for types that can be cast to a std::string
*
* @code
* Reference<String> ref = str_arr[0];
* std::string cpy(ref);
* @endcode
*
* @return std::string - a string representation of the value
*
* @throw std::runtime_error - for a Reference<MATLABString> if the MATLABString is missing
* @throw NonAsciiCharInInputDataException for a Reference<MATLABString> if the MATLABString contains non-ascii characters
*/
operator std::string() const {
static_assert(std::is_same<ref_type, Enumeration>::value ||
std::is_same<ref_type, MATLABString>::value,
"Invalid Reference to get a string");
return detail::getString<ref_type>(pImpl.get());
}
/**
* Assign a std::string into an Array. The Array being indexed must be non-const and allow strings to be assigned
*
* @code
* Reference<String> ref = str_arr[0];
* ref = "MyString";
* @endcode
*
* @param rhs - std::string to be assigned into the Array
*
* @return Reference<T>& - this
* @throw none
*/
Reference<T>& operator=(std::string rhs) MW_NOEXCEPT {
static_assert(!std::is_const<T>::value, "Can't modify a Reference to const data");
static_assert(std::is_same<ref_type, Enumeration>::value ||
std::is_same<ref_type, MATLABString>::value,
"Invalid Reference to set a string");
detail::setString<ref_type>(pImpl.get(), std::move(rhs));
return *this;
}
/**
* Assign a String value into a MATLABString Array. The Array being indexed must be non-const.
*
* @code
* Reference<MATLABString> ref = string_arr[0];
* ref = String(u"hello");
* @endcode
*
* @param rhs - value to be assigned into the Array
*
* @return Reference<T>& - this
*
* @throw none
*/
Reference<T>& operator= (String rhs) MW_NOEXCEPT {
static_assert(!std::is_const<T>::value, "Can't modify a Reference to const data");
static_assert(std::is_same<ref_type, MATLABString>::value,
"Invalid Reference to set a String");
detail::setElement(pImpl.get(), std::move(rhs), static_cast<int>(ArrayType::MATLAB_STRING));
return *this;
}
/**
* Move constructor
*
* @param - rhs Reference value to be moved
* @return - newly constructed Reference
* @throw none
*/
Reference(Reference<T>&& rhs) MW_NOEXCEPT :
Parent(std::move(rhs)) {}
/**
* Move assignment
*
* @param - rhs Reference value to be moved
* @return - updated Reference
* @throw none
*/
Reference<T>& operator= (Reference<T>&& rhs) MW_NOEXCEPT {
Parent::operator= (std::move(rhs));
return *this;
}
/**
* Copy constructor
*
* @param - rhs Reference value to be copied
* @return - newly constructed Reference
* @throw none
*/
Reference(const Reference<T>& rhs) MW_NOEXCEPT :
Parent(rhs) {}
/**
* Copy assignment
*
* @param - rhs Reference value to be copied
* @return - updated Reference
* @throw none
*/
Reference<T>& operator= (const Reference<T>& rhs) MW_NOEXCEPT {
Parent::operator= (rhs);
return *this;
}
protected:
Reference(std::shared_ptr<detail::ReferenceImpl> impl) MW_NOEXCEPT :
Parent(impl) {}
Reference(detail::ReferenceImpl* impl) MW_NOEXCEPT :
Parent(impl) {}
private:
friend class detail::Access;
Reference() = delete;
};
inline bool operator ==(Reference<MATLABString> const& lhs, std::string const& rhs) MW_NOEXCEPT {
typedef bool(*ReferenceMATLABStringEqualStringFcnPtr)(detail::ReferenceImpl*, const char*, size_t idx);
static const ReferenceMATLABStringEqualStringFcnPtr fcn = detail::resolveFunction<ReferenceMATLABStringEqualStringFcnPtr>
(detail::FunctionType::REFERENCE_MATLAB_STRING_EQUAL_STRING);
return fcn(detail::Access::getImpl<detail::ReferenceImpl>(lhs), rhs.c_str(), rhs.size());
}
inline bool operator ==(std::string const& lhs, Reference<MATLABString> const& rhs) MW_NOEXCEPT {
typedef bool(*ReferenceMATLABStringEqualStringFcnPtr)(detail::ReferenceImpl*, const char*, size_t idx);
static const ReferenceMATLABStringEqualStringFcnPtr fcn = detail::resolveFunction<ReferenceMATLABStringEqualStringFcnPtr>
(detail::FunctionType::REFERENCE_MATLAB_STRING_EQUAL_STRING);
return fcn(detail::Access::getImpl<detail::ReferenceImpl>(rhs), lhs.c_str(), lhs.size());
}
inline bool operator ==(Reference<MATLABString> const& lhs, String const& rhs) MW_NOEXCEPT {
typedef bool(*ReferenceMATLABStringEqualString16FcnPtr)(detail::ReferenceImpl*, const char16_t*, size_t idx);
static const ReferenceMATLABStringEqualString16FcnPtr fcn = detail::resolveFunction<ReferenceMATLABStringEqualString16FcnPtr>
(detail::FunctionType::REFERENCE_MATLAB_STRING_EQUAL_STRING16);
return fcn(detail::Access::getImpl<detail::ReferenceImpl>(lhs), rhs.c_str(), rhs.size());
}
inline bool operator ==(String const& lhs, Reference<MATLABString> const& rhs) MW_NOEXCEPT {
typedef bool(*ReferenceMATLABStringEqualString16FcnPtr)(detail::ReferenceImpl*, const char16_t*, size_t idx);
static const ReferenceMATLABStringEqualString16FcnPtr fcn = detail::resolveFunction<ReferenceMATLABStringEqualString16FcnPtr>
(detail::FunctionType::REFERENCE_MATLAB_STRING_EQUAL_STRING16);
return fcn(detail::Access::getImpl<detail::ReferenceImpl>(rhs), lhs.c_str(), lhs.size());
}
inline bool operator ==(Reference<MATLABString> const& lhs, MATLABString const& rhs) MW_NOEXCEPT {
if (rhs.has_value()) {
const String& str = *rhs;
return (lhs == str);
}
return false;
}
inline bool operator ==(MATLABString const& lhs, Reference<MATLABString> const& rhs) MW_NOEXCEPT {
if (lhs.has_value()) {
const String& str = *lhs;
return (rhs == str);
}
return false;
}
inline bool operator ==(Reference<MATLABString> const& lhs, Reference<MATLABString> const& rhs) MW_NOEXCEPT {
typedef bool(*ReferenceMATLABStringEqualReferenceFcnPtr)(detail::ReferenceImpl*, detail::ReferenceImpl*);
static const ReferenceMATLABStringEqualReferenceFcnPtr fcn = detail::resolveFunction<ReferenceMATLABStringEqualReferenceFcnPtr>
(detail::FunctionType::REFERENCE_MATLAB_STRING_EQUAL_REFERENCE);
return fcn(detail::Access::getImpl<detail::ReferenceImpl>(lhs), detail::Access::getImpl<detail::ReferenceImpl>(rhs));
}
template<typename T1, typename T2>
inline bool operator !=( T1 const& lhs, T2 const& rhs) MW_NOEXCEPT {
return !(lhs == rhs);
}
template<typename T>
bool operator ==(Reference<T> const& lhs, T const& rhs) MW_NOEXCEPT {
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) == rhs;
}
template<typename T>
bool operator ==(T const& lhs, Reference<T> const& rhs) MW_NOEXCEPT {
using ref_type = typename Reference<T>::ref_type;
return lhs == static_cast<ref_type>(rhs);
}
template<typename T>
bool operator ==(Reference<T> const& lhs, Reference<T> const& rhs) MW_NOEXCEPT {
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) == static_cast<ref_type>(rhs);
}
template<typename T>
std::ostream& operator <<(std::ostream& os, Reference<T> const& rhs) MW_NOEXCEPT {
using ref_type = typename Reference<T>::ref_type;
return os << static_cast<ref_type>(rhs);
}
template<typename T>
bool operator <(Reference<T> const& lhs, Reference<T> const& rhs)
{
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) < static_cast<ref_type>(rhs);
}
template<typename T>
bool operator >(Reference<T> const& lhs, Reference<T> const& rhs)
{
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) > static_cast<ref_type>(rhs);
}
template<typename T>
bool operator <=(Reference<T> const& lhs, Reference<T> const& rhs)
{
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) <= static_cast<ref_type>(rhs);
}
template<typename T>
bool operator >=(Reference<T> const& lhs, Reference<T> const& rhs)
{
using ref_type = typename Reference<T>::ref_type;
return static_cast<ref_type>(lhs) >= static_cast<ref_type>(rhs);
}
}
}
#endif