25#ifndef JAU_COW_ITERATOR_HPP_
26#define JAU_COW_ITERATOR_HPP_
46 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
47 class cow_ro_iterator;
49 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
50 class cow_rw_iterator;
85 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
88 template<
typename,
typename,
typename,
bool,
bool>
friend class cow_darray;
100 typedef std::iterator_traits<iterator_type> sub_traits_t;
103 std::unique_lock<std::recursive_mutex> lock_;
108 : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()), store_ref_(std::move(store)),
112 : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()),
113 store_ref_(cow_parent.copy_store()), iterator_(store_ref_->
begin()) { }
125 typedef typename sub_traits_t::pointer
pointer;
128#if __cplusplus > 201703L && __cpp_lib_concepts && 0
129 using iterator_concept = std::__detail::__iter_concept<iterator_type>;
157 if(
nullptr != store_ref_ ) {
158 cow_parent_.set_store(std::move(store_ref_));
160 lock_ = std::unique_lock<std::recursive_mutex>();
161 store_ref_ =
nullptr;
170 : cow_parent_(o.cow_parent_), lock_(cow_parent_.get_write_mutex()),
171 store_ref_(o.store_ref_), iterator_(o.iterator_) { }
184 cow_parent_ = o.cow_parent_;
185 lock_ = std::unique_lock<std::recursive_mutex>( cow_parent_.get_write_mutex() );
186 store_ref_ = o.store_ref_;
187 iterator_ = o.iterator_;
197 : cow_parent_( o.cow_parent_ ), lock_( std::move( o.lock_ ) ),
198 store_ref_( std::move( o.store_ref_ ) ),
199 iterator_( std::move(o.iterator_ ) ) {
214 cow_parent_ = o.cow_parent_;
215 lock_ = std::move(o.lock_);
216 store_ref_ = std::move(o.store_ref_);
217 iterator_ = std::move(o.iterator_);
257 {
return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->begin()); }
269 {
return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->end() ); }
274 constexpr bool empty() const noexcept {
return store_ref_->empty(); }
280 constexpr bool capacity_reached() const noexcept {
return store_ref_->capacity_reached(); }
308 constexpr bool is_end() const noexcept {
return iterator_ == store_ref_->end(); }
314 { iterator_ = store_ref_->
end();
return *
this; }
324 constexpr bool is_begin() const noexcept {
return iterator_ == store_ref_->begin(); }
330 { iterator_ = store_ref_->
begin();
return *
this; }
350 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
351 : ( iterator_ < rhs.iterator_ ? -1 : 1);
389 return &(*iterator_);
403 return &(*iterator_);
432 {
return iterator_[i]; }
443 { iterator_ += i;
return *
this; }
451 { iterator_ -= i;
return *
this; }
461 {
return iterator_ - rhs.iterator_; }
467 inline operator std::string() const noexcept {
481 store_ref_->pop_back();
482 iterator_ = store_ref_->end();
492 iterator_ = store_ref_->erase(iterator_);
502 iterator_ = store_ref_->erase(iterator_, iterator_+count);
516 iterator_ = store_ref_->insert(iterator_, x);
530 iterator_ = store_ref_->insert(iterator_, std::move(x));
547 template<
typename... Args>
549 iterator_ = store_ref_->emplace(iterator_, std::forward<Args>(args)... );
561 template<
class InputIt >
562 constexpr void insert( InputIt first, InputIt last ) {
563 iterator_ = store_ref_->insert(iterator_, first, last);
574 store_ref_->push_back(x);
575 iterator_ = store_ref_->end();
586 store_ref_->push_back(std::move(x));
587 iterator_ = store_ref_->end();
603 template<
typename... Args>
605 reference res = store_ref_->emplace_back(std::forward<Args>(args)...);
606 iterator_ = store_ref_->end();
619 template<
class InputIt >
620 constexpr void push_back( InputIt first, InputIt last ) {
621 store_ref_->push_back(first, last);
622 iterator_ = store_ref_->end();
653 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
656 template<
typename,
typename,
typename,
bool,
bool>
friend class cow_darray;
668 typedef std::iterator_traits<iterator_type> sub_traits_t;
674 : store_ref_(std::move(store)), iterator_(std::move(it)) { }
686 typedef typename sub_traits_t::pointer
pointer;
689#if __cplusplus > 201703L && __cpp_lib_concepts && 0
690 using iterator_concept = std::__detail::__iter_concept<iterator_type>;
695 : store_ref_(
nullptr), iterator_() { }
699 : store_ref_(o.store_ref_), iterator_(o.iterator_) {}
704 store_ref_ = o.store_ref_;
705 iterator_ = o.iterator_;
712 : store_ref_(std::move(o.store_ref_)), iterator_(std::move(o.iterator_)) {
719 store_ref_ = std::move(o.store_ref_);
720 iterator_ = std::move(o.iterator_);
759 constexpr bool empty() const noexcept {
return store_ref_->empty(); }
765 constexpr bool capacity_reached() const noexcept {
return store_ref_->capacity_reached(); }
793 constexpr bool is_end() const noexcept {
return iterator_ == store_ref_->cend(); }
799 { iterator_ = store_ref_->
cend();
return *
this; }
809 constexpr bool is_begin() const noexcept {
return iterator_ == store_ref_->cbegin(); }
815 { iterator_ = store_ref_->
cbegin();
return *
this; }
838 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
839 : ( iterator_ < rhs.iterator_ ? -1 : 1);
843 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
844 : ( iterator_ < rhs.iterator_ ? -1 : 1);
874 return &(*iterator_);
903 {
return iterator_[i]; }
907 { iterator_ += i;
return *
this; }
915 { iterator_ -= i;
return *
this; }
925 {
return iterator_ - rhs.iterator_; }
928 {
return iterator_ - rhs.iterator_; }
934 inline operator std::string() const noexcept {
948 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
954 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
963 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
966 {
return lhs.compare(rhs) == 0; }
968 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
971 {
return lhs.compare(rhs) != 0; }
973 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
976 {
return rhs.compare(lhs) == 0; }
978 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
981 {
return rhs.compare(lhs) != 0; }
983 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
986 {
return lhs.compare(rhs) <= 0; }
988 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
991 {
return rhs.compare(lhs) > 0; }
993 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
996 {
return lhs.compare(rhs) < 0; }
998 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1001 {
return rhs.compare(lhs) >= 0; }
1003 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1006 {
return lhs.compare(rhs) >= 0; }
1008 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1011 {
return rhs.compare(lhs) < 0; }
1013 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1016 {
return lhs.compare(rhs) > 0; }
1018 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1021 {
return rhs.compare(lhs) <= 0; }
1023 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1024 constexpr typename Storage_type::difference_type
operator-
1027 {
return lhs.distance(rhs); }
1029 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1030 constexpr typename Storage_type::difference_type
operator-
1033 {
return rhs.distance(lhs) * -1; }
1043 template<
class,
class =
void >
1052 struct is_cow_type<T,
std::void_t<typename T::cow_container_t>> : std::true_type { };
Implementation of a Copy-On-Write (CoW) using jau::darray as the underlying storage,...
Implementation of a Copy-On-Write (CoW) read-onlu iterator over immutable value_type storage.
constexpr bool operator>=(const cow_ro_iterator &rhs) const noexcept
constexpr bool operator!=(const cow_ro_iterator &rhs) const noexcept
constexpr difference_type dist_end() const noexcept
Returns the distance to_end() using zero as first index.
constexpr cow_ro_iterator(const cow_ro_iterator &o) noexcept
constexpr cow_ro_iterator & to_end() noexcept
This iterator is set to the last element, cend().
constexpr const reference operator[](difference_type i) const noexcept
Subscript of 'element_index', returning immutable Value_type reference.
constexpr bool operator==(const cow_ro_iterator &rhs) const noexcept
constexpr difference_type dist_begin() const noexcept
Returns the distance to_begin() using zero as first index.
constexpr cow_ro_iterator cbegin() const noexcept
Returns a new const_iterator pointing to the first element, aka begin.
constexpr int compare(const cow_rw_iterator< storage_t, storage_ref_t, cow_container_t > &rhs) const noexcept
Storage_ref_type storage_ref_t
constexpr difference_type distance(const cow_rw_iterator< storage_t, storage_ref_t, cow_container_t > &rhs) const noexcept
constexpr iterator_type base() const noexcept
Returns a copy of the underlying storage const_iterator.
constexpr cow_ro_iterator operator++(int) noexcept
Post-increment; Try to avoid: Low performance due to returning copy-ctor.
constexpr cow_ro_iterator & operator-=(difference_type i) noexcept
Subtraction-assignment of 'element_count'; Well performing, return *this.
storage_t::difference_type difference_type
constexpr cow_ro_iterator(cow_ro_iterator &&o) noexcept
constexpr size_type size() const noexcept
Return the size of the underlying value_type store.
sub_traits_t::reference reference
constexpr const reference operator*() const noexcept
constexpr difference_type operator-(const cow_ro_iterator &rhs) const noexcept
Binary 'iterator - iterator -> element_count'; Well performing, return element_count of type differen...
std::string toString() const noexcept
constexpr bool is_begin() const noexcept
Returns true, if this iterator points to cbegin().
storage_t::size_type size_type
sub_traits_t::value_type value_type
storage_t::const_iterator iterator_type
Actual const iterator type of the contained native iterator, probably a simple pointer.
constexpr cow_ro_iterator & operator++() noexcept
Pre-increment; Well performing, return *this.
constexpr bool operator>(const cow_ro_iterator &rhs) const noexcept
sub_traits_t::iterator_category iterator_category
constexpr bool is_end() const noexcept
Returns true, if this iterator points to cend().
constexpr const pointer operator->() const noexcept
constexpr cow_ro_iterator & operator=(cow_ro_iterator &&o) noexcept
constexpr bool capacity_reached() const noexcept
Returns true if storage capacity has been reached and the next push_back() will grow the storage and ...
sub_traits_t::pointer pointer
CoW_container cow_container_t
constexpr cow_ro_iterator() noexcept
std::string get_info() const noexcept
constexpr cow_ro_iterator & operator=(const cow_ro_iterator &o) noexcept
constexpr cow_ro_iterator operator+(difference_type rhs) const noexcept
Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor.
constexpr cow_ro_iterator & to_begin() noexcept
This iterator is set to the first element, cbegin().
void swap(cow_ro_iterator &o) noexcept
constexpr bool operator<=(const cow_ro_iterator &rhs) const noexcept
constexpr cow_ro_iterator operator-(difference_type rhs) const noexcept
Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor.
constexpr storage_t & storage() const noexcept
Returns this instances' underlying shared storage by reference.
constexpr cow_ro_iterator & operator--() noexcept
Pre-decrement; Well performing, return *this.
constexpr int compare(const cow_ro_iterator &rhs) const noexcept
Returns signum or three-way comparison value.
constexpr bool empty() const noexcept
Returns true if storage is empty().
constexpr cow_ro_iterator cend() const noexcept
Returns a new const_iterator pointing to the element following the last element, aka end.
constexpr bool operator<(const cow_ro_iterator &rhs) const noexcept
constexpr cow_ro_iterator operator--(int) noexcept
Post-decrement; Try to avoid: Low performance due to returning copy-ctor.
constexpr cow_ro_iterator & operator+=(difference_type i) noexcept
Addition-assignment of 'element_count'; Well performing, return *this.
Implementation of a Copy-On-Write (CoW) read-write iterator over mutable value_type storage.
constexpr void erase(size_type count)
Like std::vector::erase(), removes the elements in the range [current, current+count).
sub_traits_t::value_type value_type
constexpr cow_rw_iterator begin() const noexcept
Returns a new iterator pointing to the first element, aka begin.
storage_t::difference_type difference_type
constexpr void pop_back() noexcept
Removes the last element and sets this iterator to end()
constexpr void emplace(Args &&... args)
Like std::vector::emplace(), construct a new element in place.
constexpr void insert(InputIt first, InputIt last)
Like std::vector::insert(), inserting the value_type range [first, last).
constexpr bool operator==(const cow_rw_iterator &rhs) const noexcept
constexpr reference operator[](difference_type i) noexcept
Subscript of 'element_index', returning mutable Value_type reference.
constexpr cow_rw_iterator operator+(difference_type rhs) const noexcept
Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor.
constexpr iterator_type base() const noexcept
Returns a copy of the underlying storage iterator.
storage_t::iterator iterator_type
Actual iterator type of the contained native iterator, probably a simple pointer.
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
constexpr void insert(value_type &&x)
Inserts the element before the current position (std::move operation) and moves all elements from the...
constexpr void push_back(value_type &&x)
Like std::vector::push_back(), move.
sub_traits_t::iterator_category iterator_category
constexpr cow_rw_iterator & to_begin() noexcept
This iterator is set to the first element, begin().
constexpr reference emplace_back(Args &&... args)
Like std::vector::emplace_back(), construct a new element in place at the end().
constexpr bool operator<(const cow_rw_iterator &rhs) const noexcept
constexpr bool is_begin() const noexcept
Returns true, if this iterator points to begin().
constexpr pointer operator->() noexcept
Pointer to member access.
constexpr difference_type dist_begin() const noexcept
Returns the distance to_begin() using zero as first index.
std::string toString() const noexcept
constexpr cow_rw_iterator & operator++() noexcept
Pre-increment; Well performing, return *this.
Storage_ref_type storage_ref_t
constexpr cow_rw_iterator & operator-=(difference_type i) noexcept
Subtraction-assignment of 'element_count'; Well performing, return *this.
constexpr cow_ro_iterator< Storage_type, Storage_ref_type, CoW_container > immutable() const noexcept
Returns a new const_iterator pointing to the current position.
constexpr cow_rw_iterator & operator=(const cow_rw_iterator &o) noexcept
Assigns content of other mutable iterator to this one, if they are not identical.
constexpr cow_rw_iterator & operator+=(difference_type i) noexcept
Addition-assignment of 'element_count'; Well performing, return *this.
constexpr cow_rw_iterator & operator--() noexcept
Pre-decrement; Well performing, return *this.
sub_traits_t::pointer pointer
constexpr difference_type operator-(const cow_rw_iterator &rhs) const noexcept
Binary 'iterator - iterator -> element_count'; Well performing, return element_count of type differen...
constexpr storage_t & storage() const noexcept
Returns this instances' underlying shared storage by reference.
constexpr reference operator*() noexcept
Dereferencing iterator to value_type reference.
constexpr void push_back(InputIt first, InputIt last)
Like std::vector::push_back(), but appends the value_type range [first, last).
constexpr cow_rw_iterator operator-(difference_type rhs) const noexcept
Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor.
std::string get_info() const noexcept
storage_t::size_type size_type
constexpr cow_rw_iterator(const cow_rw_iterator &o) noexcept
C++ named requirements: LegacyIterator: CopyConstructible.
constexpr size_type size() const noexcept
Return the size of the underlying value_type store.
constexpr bool is_end() const noexcept
Returns true, if this iterator points to end().
constexpr cow_rw_iterator(cow_rw_iterator &&o) noexcept
C++ named requirements: LegacyIterator: MoveConstructable.
CoW_container cow_container_t
constexpr void insert(const value_type &x)
Inserts the element before the current position and moves all elements from there to the right before...
void swap(cow_rw_iterator &o) noexcept
C++ named requirements: LegacyIterator: Swappable.
constexpr cow_rw_iterator end() const noexcept
Returns a new iterator pointing to the element following the last element, aka end.
void write_back() noexcept
Replace the parent's current store with this iterators' instance, unlock the CoW parents' write lock ...
constexpr cow_rw_iterator & to_end() noexcept
This iterator is set to the last element, end().
constexpr const pointer operator->() const noexcept
Pointer to member access.
constexpr difference_type dist_end() const noexcept
Returns the distance to_end() using zero as first index.
constexpr cow_rw_iterator operator--(int) noexcept
Post-decrement; Try to avoid: Low performance due to returning copy-ctor.
constexpr void erase()
Erases the element at the current position.
constexpr const reference operator*() const noexcept
Dereferencing iterator to value_type reference.
constexpr const reference operator[](difference_type i) const noexcept
Subscript of 'element_index', returning immutable Value_type reference.
constexpr cow_rw_iterator & operator=(cow_rw_iterator &&o) noexcept
Assigns identity of given mutable iterator, if they are not identical.
sub_traits_t::reference reference
constexpr bool operator<=(const cow_rw_iterator &rhs) const noexcept
constexpr int compare(const cow_rw_iterator &rhs) const noexcept
Returns signum or three-way comparison value.
constexpr cow_rw_iterator operator++(int) noexcept
Post-increment; Try to avoid: Low performance due to returning copy-ctor.
constexpr bool empty() const noexcept
Returns true if storage is empty().
constexpr bool operator!=(const cow_rw_iterator &rhs) const noexcept
constexpr bool operator>(const cow_rw_iterator &rhs) const noexcept
constexpr bool operator>=(const cow_rw_iterator &rhs) const noexcept
constexpr bool capacity_reached() const noexcept
Returns true if storage capacity has been reached and the next push_back() will grow the storage and ...
Implementation of a Copy-On-Write (CoW) using std::vector as the underlying storage,...
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
std::ostream & operator<<(std::ostream &out, const cow_darray< Value_type, Size_type, Alloc_type > &c)
bool operator>=(const cow_darray< Value_type, Size_type, Alloc_type > &rhs, const cow_darray< Value_type, Size_type, Alloc_type > &lhs)
bool operator>(const cow_darray< Value_type, Size_type, Alloc_type > &rhs, const cow_darray< Value_type, Size_type, Alloc_type > &lhs)
bool operator<(const cow_darray< Value_type, Size_type, Alloc_type > &rhs, const cow_darray< Value_type, Size_type, Alloc_type > &lhs)
void swap(cow_darray< Value_type, Size_type, Alloc_type > &rhs, cow_darray< Value_type, Size_type, Alloc_type > &lhs) noexcept
bool operator<=(const cow_darray< Value_type, Size_type, Alloc_type > &rhs, const cow_darray< Value_type, Size_type, Alloc_type > &lhs)
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
template< class T > is_cow_type<T>::value compile-time Type Trait, determining whether the given temp...