25#ifndef JAU_COW_ITERATOR_HPP_
26#define JAU_COW_ITERATOR_HPP_
44 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
47 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
83 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
84 class cow_rw_iterator {
86 template<
typename,
typename,
typename,
bool,
bool>
friend class cow_darray;
98 typedef std::iterator_traits<iterator_type> sub_traits_t;
101 std::unique_lock<std::recursive_mutex> lock_;
106 : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()), store_ref_(std::move(store)),
110 : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()),
111 store_ref_(cow_parent.copy_store()), iterator_(store_ref_->
begin()) { }
123 typedef typename sub_traits_t::pointer
pointer;
126#if __cplusplus > 201703L && __cpp_lib_concepts && 0
127 using iterator_concept = std::__detail::__iter_concept<iterator_type>;
155 if(
nullptr != store_ref_ ) {
156 cow_parent_.set_store(std::move(store_ref_));
158 lock_ = std::unique_lock<std::recursive_mutex>();
159 store_ref_ =
nullptr;
168 : cow_parent_(o.cow_parent_), lock_(cow_parent_.get_write_mutex()),
169 store_ref_(o.store_ref_), iterator_(o.iterator_) { }
180 constexpr cow_rw_iterator&
operator=(
const cow_rw_iterator& o)
noexcept {
182 cow_parent_ = o.cow_parent_;
183 lock_ = std::unique_lock<std::recursive_mutex>( cow_parent_.get_write_mutex() );
184 store_ref_ = o.store_ref_;
185 iterator_ = o.iterator_;
195 : cow_parent_( o.cow_parent_ ), lock_( std::move( o.lock_ ) ),
196 store_ref_( std::move( o.store_ref_ ) ),
197 iterator_( std::move(o.iterator_ ) ) {
210 constexpr cow_rw_iterator&
operator=(cow_rw_iterator&& o)
noexcept {
212 cow_parent_ = o.cow_parent_;
213 lock_ = std::move(o.lock_);
214 store_ref_ = std::move(o.store_ref_);
215 iterator_ = std::move(o.iterator_);
224 void swap(cow_rw_iterator& o)
noexcept {
225 std::swap( cow_parent_, o.cow_parent_);
226 std::swap( lock_, o.lock_);
227 std::swap( store_ref_, o.store_ref_);
228 std::swap( iterator_, o.iterator_);
254 constexpr cow_rw_iterator
begin() const noexcept
255 {
return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->begin()); }
266 constexpr cow_rw_iterator
end() const noexcept
267 {
return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->end() ); }
272 constexpr bool empty() const noexcept {
return store_ref_->empty(); }
278 constexpr bool capacity_reached() const noexcept {
return store_ref_->capacity_reached(); }
306 constexpr bool is_end() const noexcept {
return iterator_ == store_ref_->end(); }
311 constexpr cow_rw_iterator&
to_end() noexcept
312 { iterator_ = store_ref_->
end();
return *
this; }
322 constexpr bool is_begin() const noexcept {
return iterator_ == store_ref_->begin(); }
328 { iterator_ = store_ref_->
begin();
return *
this; }
347 constexpr int compare(
const cow_rw_iterator& rhs)
const noexcept {
348 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
349 : ( iterator_ < rhs.iterator_ ? -1 : 1);
353 constexpr bool operator==(
const cow_rw_iterator& rhs)
const noexcept
354 {
return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_; }
357 std::strong_ordering
operator<=>(
const cow_rw_iterator& rhs)
const noexcept {
358 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? std::strong_ordering::equal :
359 ( iterator_ < rhs.iterator_ ? std::strong_ordering::less : std::strong_ordering::greater );
377 return &(*iterator_);
391 return &(*iterator_);
402 {
return cow_rw_iterator(cow_parent_, store_ref_, iterator_++); }
414 {
return cow_rw_iterator(cow_parent_, store_ref_, iterator_--); }
420 {
return iterator_[i]; }
431 { iterator_ += i;
return *
this; }
435 {
return cow_rw_iterator(cow_parent_, store_ref_, iterator_ + rhs); }
439 { iterator_ -= i;
return *
this; }
443 {
return cow_rw_iterator(cow_parent_, store_ref_, iterator_ - rhs); }
449 {
return iterator_ - rhs.iterator_; }
455 inline operator std::string() const noexcept {
469 store_ref_->pop_back();
470 iterator_ = store_ref_->end();
480 iterator_ = store_ref_->erase(iterator_);
490 iterator_ = store_ref_->erase(iterator_, iterator_+count);
504 iterator_ = store_ref_->insert(iterator_, x);
518 iterator_ = store_ref_->insert(iterator_, std::move(x));
535 template<
typename... Args>
537 iterator_ = store_ref_->emplace(iterator_, std::forward<Args>(args)... );
549 template<
class InputIt >
550 constexpr void insert( InputIt first, InputIt last ) {
551 iterator_ = store_ref_->insert(iterator_, first, last);
562 store_ref_->push_back(x);
563 iterator_ = store_ref_->end();
574 store_ref_->push_back(std::move(x));
575 iterator_ = store_ref_->end();
591 template<
typename... Args>
593 reference res = store_ref_->emplace_back(std::forward<Args>(args)...);
594 iterator_ = store_ref_->end();
607 template<
class InputIt >
608 constexpr void push_back( InputIt first, InputIt last ) {
609 store_ref_->push_back(first, last);
610 iterator_ = store_ref_->end();
641 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
642 class cow_ro_iterator {
644 template<
typename,
typename,
typename,
bool,
bool>
friend class cow_darray;
656 typedef std::iterator_traits<iterator_type> sub_traits_t;
662 : store_ref_(std::move(store)), iterator_(std::move(it)) { }
674 typedef typename sub_traits_t::pointer
pointer;
677#if __cplusplus > 201703L && __cpp_lib_concepts && 0
678 using iterator_concept = std::__detail::__iter_concept<iterator_type>;
683 : store_ref_(
nullptr), iterator_() { }
687 : store_ref_(o.store_ref_), iterator_(o.iterator_) {}
690 constexpr cow_ro_iterator&
operator=(
const cow_ro_iterator& o)
noexcept {
692 store_ref_ = o.store_ref_;
693 iterator_ = o.iterator_;
700 : store_ref_(std::move(o.store_ref_)), iterator_(std::move(o.iterator_)) {
705 constexpr cow_ro_iterator&
operator=(cow_ro_iterator&& o)
noexcept {
707 store_ref_ = std::move(o.store_ref_);
708 iterator_ = std::move(o.iterator_);
715 void swap(cow_ro_iterator& o)
noexcept {
716 std::swap( store_ref_, o.store_ref_);
717 std::swap( iterator_, o.iterator_);
729 constexpr cow_ro_iterator
cbegin() const noexcept
741 constexpr cow_ro_iterator
cend() const noexcept
747 constexpr bool empty() const noexcept {
return store_ref_->empty(); }
753 constexpr bool capacity_reached() const noexcept {
return store_ref_->capacity_reached(); }
781 constexpr bool is_end() const noexcept {
return iterator_ == store_ref_->cend(); }
786 constexpr cow_ro_iterator&
to_end() noexcept
787 { iterator_ = store_ref_->
cend();
return *
this; }
797 constexpr bool is_begin() const noexcept {
return iterator_ == store_ref_->cbegin(); }
803 { iterator_ = store_ref_->
cbegin();
return *
this; }
825 constexpr int compare(
const cow_ro_iterator& rhs)
const noexcept {
826 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
827 : ( iterator_ < rhs.iterator_ ? -1 : 1);
831 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
832 : ( iterator_ < rhs.iterator_ ? -1 : 1);
836 constexpr bool operator==(
const cow_ro_iterator& rhs)
const noexcept
837 {
return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_; }
840 std::strong_ordering
operator<=>(
const cow_ro_iterator& rhs)
const noexcept {
841 return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? std::strong_ordering::equal :
842 ( iterator_ < rhs.iterator_ ? std::strong_ordering::less : std::strong_ordering::greater );
852 return &(*iterator_);
881 {
return iterator_[i]; }
885 { iterator_ += i;
return *
this; }
893 { iterator_ -= i;
return *
this; }
903 {
return iterator_ - rhs.iterator_; }
906 {
return iterator_ - rhs.iterator_; }
912 inline operator std::string() const noexcept {
926 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
932 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
941 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
944 {
return lhs.compare(rhs) == 0; }
946 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
949 {
return lhs.compare(rhs) != 0; }
951 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
954 {
return rhs.compare(lhs) == 0; }
956 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
959 {
return rhs.compare(lhs) != 0; }
961 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
964 {
return lhs.compare(rhs) <= 0; }
966 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
969 {
return rhs.compare(lhs) > 0; }
971 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
974 {
return lhs.compare(rhs) < 0; }
976 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
979 {
return rhs.compare(lhs) >= 0; }
981 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
984 {
return lhs.compare(rhs) >= 0; }
986 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
989 {
return rhs.compare(lhs) < 0; }
991 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
994 {
return lhs.compare(rhs) > 0; }
996 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
999 {
return rhs.compare(lhs) <= 0; }
1001 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1002 constexpr typename Storage_type::difference_type
operator-
1005 {
return lhs.distance(rhs); }
1007 template <
typename Storage_type,
typename Storage_ref_type,
typename CoW_container>
1008 constexpr typename Storage_type::difference_type
operator-
1011 {
return rhs.distance(lhs) * -1; }
1021 template<
class,
class =
void >
1030 struct is_cow_type<T,
std::void_t<typename T::cow_container_t>> : std::true_type { };
Implementation of a Copy-On-Write (CoW) read-onlu iterator over immutable value_type storage.
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
Two way comparison operator, != is implicit, C++20.
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_t 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
constexpr cow_ro_iterator & operator++() noexcept
Pre-increment; Well performing, return *this.
std::strong_ordering operator<=>(const cow_ro_iterator &rhs) const noexcept
Three way std::strong_ordering comparison operator, C++20.
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_t 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 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 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).
std::strong_ordering operator<=>(const cow_rw_iterator &rhs) const noexcept
Three way std::strong_ordering comparison operator, C++20.
constexpr bool operator==(const cow_rw_iterator &rhs) const noexcept
Two way comparison operator, != is implicit, C++20.
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
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 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_t 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_t 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 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 capacity_reached() const noexcept
Returns true if storage capacity has been reached and the next push_back() will grow the storage and ...
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)
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, const bool skipLeading0x=false) noexcept
Produce a lower-case hexadecimal string representation with leading 0x in MSB 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...