/* Copyright 2016-2017 The MathWorks, Inc. */ #ifndef MATLAB_DATA_FORWARD_ITERATOR_HPP #define MATLAB_DATA_FORWARD_ITERATOR_HPP #include "detail/publish_util.hpp" #include "detail/FunctionType.hpp" #include #include #include namespace matlab { namespace data { namespace detail { class Access; class RefCounted; class ForwardIteratorImpl; } template class ForwardIterator { public: typedef std::ptrdiff_t difference_type; typedef T value_type; typedef T* pointer; typedef T reference; typedef std::forward_iterator_tag iterator_category; /** * ForwardIterator copy constructor. Guaranteed not to throw. * * @param rhs ForwardIterator object to be copied. * @throw none. */ ForwardIterator(const ForwardIterator &rhs) MW_NOEXCEPT : fIndex(rhs.fIndex) { typedef detail::ForwardIteratorImpl*(*ForwardIteratorCloneFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorCloneFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_CLONE); pImpl = std::shared_ptr (fcn(rhs.pImpl.get()), [](detail::ForwardIteratorImpl* ptr) { typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_DESTROY); fcn2(ptr); }); } /** * ForwardIterator operator=. * * @param rhs ForwardIterator object to assign to this instance. * @return the updated instance. * @throw none */ ForwardIterator& operator=(const ForwardIterator &rhs) MW_NOEXCEPT { typedef detail::ForwardIteratorImpl*(*ForwardIteratorCloneFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorCloneFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_CLONE); pImpl = std::shared_ptr (fcn(rhs.pImpl.get()), [](detail::ForwardIteratorImpl* ptr) { typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_DESTROY); fcn2(ptr); }); fRef = rhs.fRef; fIndex = rhs.fIndex; return *this; } /** * Pre-increment * * @return ForwardIterator& - reference to this. * @throw none */ ForwardIterator& operator++() MW_NOEXCEPT { ++fIndex; typedef void(*ForwardIteratorPlusPlusFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorPlusPlusFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_PLUS_PLUS); fcn(pImpl.get()); return *this; } /** * Post-increment * * @return ForwardIterator - newly created ForwardIterator * @throw none */ ForwardIterator operator++(int) MW_NOEXCEPT { ForwardIterator temp(*this); ++fIndex; typedef void(*ForwardIteratorPlusPlusFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorPlusPlusFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_PLUS_PLUS); fcn(pImpl.get()); return temp; } /** * operator== determine if 2 iterators are pointing to the same element * @param rhs - the iterator to be compared with * @return bool - true if the iterators are pointing to the same element * @throw none */ bool operator==(const ForwardIterator &rhs) const MW_NOEXCEPT { typedef bool(*ForwardIteratorEqualFcnPtr)(detail::ForwardIteratorImpl*, detail::ForwardIteratorImpl*); static const ForwardIteratorEqualFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_EQUAL); return fcn(pImpl.get(), rhs.pImpl.get()); } /** * operator!= determine if 2 iterators are pointing to the same element * @param rhs - the iterator to be compared with * @return bool - true if this iterator points to a different element * @throw none */ bool operator!=(const ForwardIterator &rhs) const MW_NOEXCEPT { typedef bool(*ForwardIteratorEqualFcnPtr)(detail::ForwardIteratorImpl*, detail::ForwardIteratorImpl*); static const ForwardIteratorEqualFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_EQUAL); return !fcn(pImpl.get(), rhs.pImpl.get()); } /** * operator* return a shared copy of the element that the iterator is pointing to * * @return T - shared copy of the element that the iterator is pointing to * @throw none */ reference operator*() const MW_NOEXCEPT { detail::RefCounted* value = nullptr; typedef void(*ForwardIteratorGetRefFcnPtr)(detail::ForwardIteratorImpl*, detail::RefCounted**); static const ForwardIteratorGetRefFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_GET_REF); fcn(pImpl.get(), &value); return detail::Access::createObj(value, fIndex); } /** * Get a pointer the element pointed to by this iterator * * @return pointer - the element * @throw none */ pointer operator->() const MW_NOEXCEPT { detail::RefCounted* value = nullptr; typedef void(*ForwardIteratorGetRefFcnPtr)(detail::ForwardIteratorImpl*, detail::RefCounted**); static const ForwardIteratorGetRefFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_GET_REF); fcn(pImpl.get(), &value); fRef = detail::Access::createObj(value); return &fRef; } /** * Get a reference using a linear index * * @return reference - the element * @throw none */ reference operator[](const size_t& rhs) const MW_NOEXCEPT { ForwardIterator temp(*this); temp.fIndex += rhs; typedef void(*ForwardIteratorIncrementFcnPtr)(detail::ForwardIteratorImpl*, size_t); static const ForwardIteratorIncrementFcnPtr fcn = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_INCREMENT); fcn(temp.pImpl.get(), rhs); return *temp; } private: friend class detail::Access; std::shared_ptr pImpl; mutable std::remove_const fRef; size_t fIndex; /** * ForwardIterator constructor. * @param *impl pointer to the implementation * @throw None */ ForwardIterator(detail::ForwardIteratorImpl *impl) : pImpl(std::shared_ptr (impl, [](detail::ForwardIteratorImpl* ptr) { typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*); static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction (detail::FunctionType::FORWARD_ITERATOR_DESTROY); fcn2(ptr); })), fIndex(0) {} }; } } #endif