209 lines
9.1 KiB
C++
209 lines
9.1 KiB
C++
|
/* 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 <memory>
|
||
|
#include <iterator>
|
||
|
#include <functional>
|
||
|
|
||
|
namespace matlab {
|
||
|
namespace data {
|
||
|
namespace detail {
|
||
|
class Access;
|
||
|
class RefCounted;
|
||
|
class ForwardIteratorImpl;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
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<T> &rhs) MW_NOEXCEPT :
|
||
|
fIndex(rhs.fIndex) {
|
||
|
typedef detail::ForwardIteratorImpl*(*ForwardIteratorCloneFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorCloneFcnPtr fcn = detail::resolveFunction<ForwardIteratorCloneFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_CLONE);
|
||
|
pImpl = std::shared_ptr<detail::ForwardIteratorImpl>
|
||
|
(fcn(rhs.pImpl.get()),
|
||
|
[](detail::ForwardIteratorImpl* ptr) {
|
||
|
typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction<ForwardIteratorDestroyFcnPtr>
|
||
|
(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<T>& operator=(const ForwardIterator<T> &rhs) MW_NOEXCEPT {
|
||
|
typedef detail::ForwardIteratorImpl*(*ForwardIteratorCloneFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorCloneFcnPtr fcn = detail::resolveFunction<ForwardIteratorCloneFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_CLONE);
|
||
|
pImpl = std::shared_ptr<detail::ForwardIteratorImpl>
|
||
|
(fcn(rhs.pImpl.get()),
|
||
|
[](detail::ForwardIteratorImpl* ptr) {
|
||
|
typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction<ForwardIteratorDestroyFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_DESTROY);
|
||
|
fcn2(ptr);
|
||
|
});
|
||
|
fRef = rhs.fRef;
|
||
|
fIndex = rhs.fIndex;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Pre-increment
|
||
|
*
|
||
|
* @return ForwardIterator<T>& - reference to this.
|
||
|
* @throw none
|
||
|
*/
|
||
|
ForwardIterator<T>& operator++() MW_NOEXCEPT {
|
||
|
++fIndex;
|
||
|
typedef void(*ForwardIteratorPlusPlusFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorPlusPlusFcnPtr fcn = detail::resolveFunction<ForwardIteratorPlusPlusFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_PLUS_PLUS);
|
||
|
fcn(pImpl.get());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Post-increment
|
||
|
*
|
||
|
* @return ForwardIterator<T> - newly created ForwardIterator
|
||
|
* @throw none
|
||
|
*/
|
||
|
ForwardIterator<T> operator++(int) MW_NOEXCEPT {
|
||
|
ForwardIterator<T> temp(*this);
|
||
|
++fIndex;
|
||
|
typedef void(*ForwardIteratorPlusPlusFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorPlusPlusFcnPtr fcn = detail::resolveFunction<ForwardIteratorPlusPlusFcnPtr>
|
||
|
(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<T> &rhs) const MW_NOEXCEPT {
|
||
|
typedef bool(*ForwardIteratorEqualFcnPtr)(detail::ForwardIteratorImpl*, detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorEqualFcnPtr fcn = detail::resolveFunction<ForwardIteratorEqualFcnPtr>
|
||
|
(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<T> &rhs) const MW_NOEXCEPT {
|
||
|
typedef bool(*ForwardIteratorEqualFcnPtr)(detail::ForwardIteratorImpl*, detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorEqualFcnPtr fcn = detail::resolveFunction<ForwardIteratorEqualFcnPtr>
|
||
|
(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<ForwardIteratorGetRefFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_GET_REF);
|
||
|
fcn(pImpl.get(), &value);
|
||
|
return detail::Access::createObj<reference>(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<ForwardIteratorGetRefFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_GET_REF);
|
||
|
fcn(pImpl.get(), &value);
|
||
|
fRef = detail::Access::createObj<reference>(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<T> temp(*this);
|
||
|
temp.fIndex += rhs;
|
||
|
typedef void(*ForwardIteratorIncrementFcnPtr)(detail::ForwardIteratorImpl*, size_t);
|
||
|
static const ForwardIteratorIncrementFcnPtr fcn = detail::resolveFunction<ForwardIteratorIncrementFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_INCREMENT);
|
||
|
fcn(temp.pImpl.get(), rhs);
|
||
|
return *temp;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
friend class detail::Access;
|
||
|
|
||
|
std::shared_ptr<detail::ForwardIteratorImpl> pImpl;
|
||
|
mutable std::remove_const<reference> fRef;
|
||
|
|
||
|
size_t fIndex;
|
||
|
|
||
|
/**
|
||
|
* ForwardIterator constructor.
|
||
|
* @param *impl pointer to the implementation
|
||
|
* @throw None
|
||
|
*/
|
||
|
ForwardIterator(detail::ForwardIteratorImpl *impl) :
|
||
|
pImpl(std::shared_ptr<detail::ForwardIteratorImpl>
|
||
|
(impl,
|
||
|
[](detail::ForwardIteratorImpl* ptr) {
|
||
|
typedef void(*ForwardIteratorDestroyFcnPtr)(detail::ForwardIteratorImpl*);
|
||
|
static const ForwardIteratorDestroyFcnPtr fcn2 = detail::resolveFunction<ForwardIteratorDestroyFcnPtr>
|
||
|
(detail::FunctionType::FORWARD_ITERATOR_DESTROY);
|
||
|
fcn2(ptr);
|
||
|
})),
|
||
|
fIndex(0) {}
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|