/* Copyright 2015-2017 The MathWorks, Inc. */ #ifndef MATLAB_EXTDATA_STRUCT_REF_HPP #define MATLAB_EXTDATA_STRUCT_REF_HPP #include "TypedArrayRef.hpp" #include "Struct.hpp" #include "MDArray.hpp" #include "Exception.hpp" #include "detail/publish_util.hpp" #include "detail/FunctionType.hpp" #include "detail/HelperFunctions.hpp" #include "detail/ReferenceHelpers.hpp" namespace matlab { namespace data { namespace detail { class ReferenceImpl; class Access; } template<> class Reference : public ReferenceHolder { public: typedef TypedIterator iterator; typedef TypedIterator const_iterator; /** * operator[] index into the Struct with a field name * * @param idx - the field name * @return Reference - reference to the field value * @throw InvalidFieldNameException if the field does not exist in the struct * */ Reference operator[](std::string idx) { typedef int(*StructReferenceGetRefFcnPtr)(detail::ReferenceImpl*, const char*, size_t, bool, detail::ReferenceImpl**); static const StructReferenceGetRefFcnPtr fcn = detail::resolveFunctionNoExcept (detail::FunctionType::STRUCT_REFERENCE_GET_REF); if (fcn == nullptr) { return detail::Access::createObj>(detail::getRef(pImpl.get(), idx.c_str(), idx.size(), true)); } detail::ReferenceImpl* impl = nullptr; detail::throwIfError(fcn(pImpl.get(), idx.c_str(), idx.size(), true, &impl)); return detail::Access::createObj>(impl); } /** * return a shared copy of the Array found at the field specified * * @param idx - field name * @return Array - shared copy of the Array found at the field specified * @throw InvalidFieldNameException if the field does not exist in the struct */ Array operator[](std::string idx) const { impl::ArrayImpl* arrayImpl = nullptr; typedef int(*StructGetFieldCopyFcnPtr)(detail::ReferenceImpl*, const char*, size_t, impl::ArrayImpl**); static const StructGetFieldCopyFcnPtr fcn = detail::resolveFunction (detail::FunctionType::STRUCT_GET_FIELD_COPY); detail::throwIfError(fcn(pImpl.get(), idx.c_str(), idx.size(), &arrayImpl)); return detail::Access::createObj(arrayImpl); } /** * Return an iterator to the beginning of the list of fields * * @return iterator * @throw none */ iterator begin() MW_NOEXCEPT { typedef detail::IteratorImpl*(*ArrayReferenceBeginFcnPtr)(detail::ReferenceImpl*, bool); static const ArrayReferenceBeginFcnPtr str_fcn = detail::resolveFunctionNoExcept (detail::FunctionType::STRUCT_REFERENCE_BEGIN); if (str_fcn == nullptr) { static const ArrayReferenceBeginFcnPtr fcn = detail::resolveFunction (detail::FunctionType::ARRAY_REFERENCE_BEGIN); return detail::Access::createObj(fcn(pImpl.get(), true)); } else { return detail::Access::createObj(str_fcn(pImpl.get(), true)); } } /** * Return an iterator to the end of the list of fields * * @return iterator * @throw none */ iterator end() MW_NOEXCEPT { typedef detail::IteratorImpl*(*ArrayReferenceEndFcnPtr)(detail::ReferenceImpl*, bool); static const ArrayReferenceEndFcnPtr str_fcn = detail::resolveFunctionNoExcept (detail::FunctionType::STRUCT_REFERENCE_END); if (str_fcn == nullptr) { static const ArrayReferenceEndFcnPtr fcn = detail::resolveFunction (detail::FunctionType::ARRAY_REFERENCE_END); return detail::Access::createObj(fcn(pImpl.get(), true)); } else { return detail::Access::createObj(str_fcn(pImpl.get(), true)); } } /** * Return a const_iterator to the beginning of the list of fields * * @return const_iterator * @throw none */ const_iterator begin() const MW_NOEXCEPT { return cbegin(); } /** * Return a const_iterator to the beginning of the list of fields * * @return const_iterator * @throw none */ const_iterator cbegin() const MW_NOEXCEPT { typedef detail::IteratorImpl*(*ArrayReferenceBeginFcnPtr)(detail::ReferenceImpl*, bool); static const ArrayReferenceBeginFcnPtr str_fcn = detail::resolveFunctionNoExcept (detail::FunctionType::STRUCT_REFERENCE_BEGIN); if (str_fcn == nullptr) { static const ArrayReferenceBeginFcnPtr fcn = detail::resolveFunction (detail::FunctionType::ARRAY_REFERENCE_BEGIN); return detail::Access::createObj(fcn(pImpl.get(), false)); } else { return detail::Access::createObj(str_fcn(pImpl.get(), false)); } } /** * Return a const_iterator to the end of the list of fields * * @return const_iterator * @throw none */ const_iterator end() const MW_NOEXCEPT { return cend(); } /** * Return a const_iterator to the end of the list of fields * * @return const_iterator * @throw none */ const_iterator cend() const MW_NOEXCEPT { typedef detail::IteratorImpl*(*ArrayReferenceEndFcnPtr)(detail::ReferenceImpl*, bool); static const ArrayReferenceEndFcnPtr str_fcn = detail::resolveFunctionNoExcept (detail::FunctionType::STRUCT_REFERENCE_END); if (str_fcn == nullptr) { static const ArrayReferenceEndFcnPtr fcn = detail::resolveFunction (detail::FunctionType::ARRAY_REFERENCE_END); return detail::Access::createObj(fcn(pImpl.get(), false)); } else { return detail::Access::createObj(str_fcn(pImpl.get(), false)); } } /** * cast to a Struct * * @return Struct * @throw none */ operator Struct() const MW_NOEXCEPT { return detail::Access::createObj(pImpl); } private: friend class detail::Access; Reference(detail::ReferenceImpl* impl) MW_NOEXCEPT : ReferenceHolder(impl) {} Reference() = delete; Reference(std::shared_ptr impl) MW_NOEXCEPT : ReferenceHolder(std::move(impl)) {} }; } } #endif