Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
cow_iterator.hpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifndef JAU_COW_ITERATOR_HPP_
26 #define JAU_COW_ITERATOR_HPP_
27 
28 #include <cstddef>
29 #include <limits>
30 #include <mutex>
31 #include <utility>
32 
33 #include <type_traits>
34 #include <iostream>
35 
36 #include <jau/cpp_lang_util.hpp>
37 #include <jau/debug.hpp>
38 #include <jau/basic_types.hpp>
39 
40 namespace jau {
41 
42  // forward declaration for friendship with cow_rw_iterator
43  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
45 
46  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
48 
49  /****************************************************************************************
50  ****************************************************************************************/
51 
52  /**
53  * Implementation of a Copy-On-Write (CoW) read-write iterator over mutable value_type storage.<br>
54  * Instance holds a copy of the parents' CoW storage and locks its write mutex until
55  * write_back() or destruction.
56  * <p>
57  * Implementation complies with Type Traits iterator_category 'random_access_iterator_tag'
58  * </p>
59  * <p>
60  * This iterator wraps the native iterator of type 'iterator_type'
61  * and manages the CoW related resource lifecycle.
62  * </p>
63  * <p>
64  * After completing all mutable operations but before this iterator's destruction,
65  * the user might want to write back this iterators' storage to its parents' CoW
66  * using write_back()
67  * </p>
68  * <p>
69  * Due to the costly nature of mutable CoW resource management,
70  * consider using jau::cow_ro_iterator if elements won't get mutated
71  * or any changes can be discarded.
72  * </p>
73  * <p>
74  * To allow data-race free operations on this iterator's data copy from a potentially mutated CoW,
75  * only one begin iterator should be retrieved from CoW and all further operations shall use
76  * jau::cow_rw_iterator::size(), jau::cow_rw_iterator::begin() and jau::cow_rw_iterator::end().
77  * </p>
78  * @see jau::cow_rw_iterator::write_back()
79  * @see jau::for_each_fidelity
80  * @see jau::cow_darray
81  */
82  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
83  class cow_rw_iterator {
85  template<typename, typename, typename, bool, bool, bool> friend class cow_darray;
86  template<typename, typename> friend class cow_vector;
87 
88  public:
89  typedef Storage_type storage_t;
90  typedef Storage_ref_type storage_ref_t;
91  typedef CoW_container cow_container_t;
92 
93  /** Actual iterator type of the contained native iterator, probably a simple pointer. */
94  typedef typename storage_t::iterator iterator_type;
95 
96  private:
97  typedef std::iterator_traits<iterator_type> sub_traits_t;
98 
99  cow_container_t& cow_parent_;
100  std::unique_lock<std::recursive_mutex> lock_; // can move and swap
101  storage_ref_t store_ref_;
102  iterator_type iterator_;
103 
104  constexpr explicit cow_rw_iterator(cow_container_t& cow_parent, const storage_ref_t& store, iterator_type iter) noexcept
105  : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()), store_ref_(store),
106  iterator_(iter) { }
107 
108  constexpr explicit cow_rw_iterator(cow_container_t& cow_parent)
109  : cow_parent_(cow_parent), lock_(cow_parent_.get_write_mutex()),
110  store_ref_(cow_parent.copy_store()), iterator_(store_ref_->begin()) { }
111 
112  public:
113  typedef typename sub_traits_t::iterator_category iterator_category; // random_access_iterator_tag
114 
115  typedef typename storage_t::size_type size_type; // using our template overload Size_type
116  typedef typename storage_t::difference_type difference_type; // derived from our Size_type
117  // typedef typename storage_t::value_type value_type; // OK
118  // typedef typename storage_t::reference reference; //
119  // typedef typename storage_t::pointer pointer; //
120  typedef typename sub_traits_t::value_type value_type; // OK
121  typedef typename sub_traits_t::reference reference; // 'value_type &'
122  typedef typename sub_traits_t::pointer pointer; // 'value_type *'
123 
124 #if __cplusplus > 201703L && __cpp_lib_concepts
125  using iterator_concept = std::__detail::__iter_concept<_Iterator>;
126 #endif
127 
128  public:
129 
130  /**
131  * Replace the parent's current store with this iterators' instance,
132  * unlock the CoW parents' write lock and discard all storage references.
133  * <p>
134  * After calling write_back(), this iterator is invalidated and no more operational.
135  * </p>
136  * <p>
137  * It is the user's responsibility to issue call this method
138  * to update the CoW parents' storage.
139  * </p>
140  * <p>
141  * It is not feasible nor effective to automatically earmark a dirty state
142  * on mutable operations.<br>
143  * This is due to the ambiguous semantics of like <code>operator*()</code>.<br>
144  * Also usage of multiple iterators to one CoW instance during a mutable operation
145  * complicates such an automated task, especially as we wish to only realize one
146  * storage replacement at the end.<br>
147  * Lastly, the user probably wants to issue the CoW storage sync
148  * in a programmatic deterministic fashion at the end.
149  * </p>
150  * @see jau::cow_darray::set_store()
151  */
152  void write_back() noexcept {
153  if( nullptr != store_ref_ ) {
154  cow_parent_.set_store(std::move(store_ref_));
155 
156  lock_ = std::unique_lock<std::recursive_mutex>(); // force-dtor-unlock-null
157  store_ref_ = nullptr;
158  iterator_ = iterator_type();
159  }
160  }
161 
162  /**
163  * C++ named requirements: LegacyIterator: CopyConstructible
164  */
165  constexpr cow_rw_iterator(const cow_rw_iterator& o) noexcept
166  : cow_parent_(o.cow_parent_), lock_(cow_parent_.get_write_mutex()),
167  store_ref_(o.store_ref_), iterator_(o.iterator_) { }
168 
169  /**
170  * Assigns content of other mutable iterator to this one,
171  * if they are not identical.
172  * <p>
173  * C++ named requirements: LegacyIterator: CopyAssignable
174  * </p>
175  * @param o the new identity value to be copied into this iterator
176  * @return reference to this
177  */
178  constexpr cow_rw_iterator& operator=(const cow_rw_iterator& o) noexcept {
179  if( this != &o ) {
180  cow_parent_ = o.cow_parent_;
181  lock_ = std::unique_lock<std::recursive_mutex>( cow_parent_.get_write_mutex() );
182  store_ref_ = o.store_ref_;
183  iterator_ = o.iterator_;
184  }
185  return *this;
186  }
187 
188 
189  /**
190  * C++ named requirements: LegacyIterator: MoveConstructable
191  */
192  constexpr cow_rw_iterator(cow_rw_iterator && o) noexcept
193  : cow_parent_( o.cow_parent_ ), lock_( std::move( o.lock_ ) ),
194  store_ref_( std::move( o.store_ref_ ) ),
195  iterator_( std::move(o.iterator_ ) ) {
196  // Moved source has been disowned semantically and source's dtor will release resources!
197  }
198 
199  /**
200  * Assigns identity of given mutable iterator,
201  * if they are not identical.
202  * <p>
203  * C++ named requirements: LegacyIterator: MoveAssignable
204  * </p>
205  * @param o the new identity to be taken
206  * @return reference to this
207  */
208  constexpr cow_rw_iterator& operator=(cow_rw_iterator&& o) noexcept {
209  if( this != &o ) {
210  cow_parent_ = o.cow_parent_;
211  lock_ = std::move(o.lock_);
212  store_ref_ = std::move(o.store_ref_);
213  iterator_ = std::move(o.iterator_);
214  // Moved source has been disowned semantically and source's dtor will release resources!
215  }
216  return *this;
217  }
218 
219  /**
220  * C++ named requirements: LegacyIterator: Swappable
221  */
222  void swap(cow_rw_iterator& o) noexcept {
223  std::swap( cow_parent_, o.cow_parent_);
224  std::swap( lock_, o.lock_);
225  std::swap( store_ref_, o.store_ref_);
226  std::swap( iterator_, o.iterator_);
227  }
228 
229  /**
230  * Returns a new const_iterator pointing to the current position.<br>
231  * This is the only explicit conversion operation of mutable -> immutable iterator, see below.
232  * <p>
233  * Be aware that the resulting cow_ro_iterator points to transient storage
234  * of this immutable iterator. In case write_back() won't be called
235  * and this iterator destructs, the returned immutable iterator is invalidated.
236  * </p>
237  * @see size()
238  * @see end()
239  */
242 
243  /**
244  * Returns a new iterator pointing to the first element, aka begin.
245  * <p>
246  * This is an addition API entry, allowing data-race free operations on
247  * this iterator's data snapshot from a potentially mutated CoW.
248  * </p>
249  * @see size()
250  * @see end()
251  */
252  constexpr cow_rw_iterator begin() const noexcept
253  { return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->begin()); }
254 
255  /**
256  * Returns a new iterator pointing to the <i>element following the last element</i>, aka end.<br>
257  * <p>
258  * This is an addition API entry, allowing data-race free operations on
259  * this iterator's data snapshot from a potentially mutated CoW.
260  * </p>
261  * @see size()
262  * @see begin()
263  */
264  constexpr cow_rw_iterator end() const noexcept
265  { return cow_rw_iterator( cow_parent_, store_ref_, store_ref_->end() ); }
266 
267  /**
268  * Returns true if storage is empty().
269  */
270  constexpr bool empty() const noexcept { return store_ref_->empty(); }
271 
272  /**
273  * Returns true if storage capacity has been reached and the next push_back()
274  * will grow the storage and invalidates all iterators and references.
275  */
276  constexpr bool capacity_reached() const noexcept { return store_ref_->capacity_reached(); }
277 
278  /**
279  * Return the size of the underlying value_type store.
280  * <p>
281  * This is an addition API entry, allowing data-race free arithmetic on
282  * this iterator's data snapshot from a potentially mutated CoW.
283  * </p>
284  * @see begin()
285  * @see end()
286  */
287  constexpr size_type size() const noexcept { return store_ref_->size(); }
288 
289  /**
290  * Returns this instances' underlying shared storage by reference.
291  */
292  constexpr storage_t& storage() const noexcept {
293  return *store_ref_;
294  }
295 
296  /**
297  * Returns the distance to_end() using zero as first index. A.k.a the remaining elements iterable.
298  */
299  constexpr difference_type dist_end() const noexcept { return store_ref_->end() - iterator_; }
300 
301  /**
302  * Returns true, if this iterator points to end().
303  */
304  constexpr bool is_end() const noexcept { return iterator_ == store_ref_->end(); }
305 
306  /**
307  * This iterator is set to the last element, end(). Returns *this;
308  */
309  constexpr cow_rw_iterator& to_end() noexcept
310  { iterator_ = store_ref_->end(); return *this; }
311 
312  /**
313  * Returns the distance to_begin() using zero as first index. A.k.a the index from start.
314  */
315  constexpr difference_type dist_begin() const noexcept { return iterator_ - store_ref_->begin(); }
316 
317  /**
318  * Returns true, if this iterator points to begin().
319  */
320  constexpr bool is_begin() const noexcept { return iterator_ == store_ref_->begin(); }
321 
322  /**
323  * This iterator is set to the first element, begin(). Returns *this;
324  */
325  constexpr cow_rw_iterator& to_begin() noexcept
326  { iterator_ = store_ref_->begin(); return *this; }
327 
328  /**
329  * Returns a copy of the underlying storage iterator.
330  */
331  constexpr iterator_type base() const noexcept { return iterator_; }
332 
333  // Multipass guarantee equality
334 
335  /**
336  * Returns signum or three-way comparison value
337  * <pre>
338  * 0 if equal (both, store and iteratore),
339  * -1 if this->iterator_ < rhs_iter and
340  * 1 if this->iterator_ > rhs_iter (otherwise)
341  * </pre>
342  * @param rhs_store right-hand side store
343  * @param rhs_iter right-hand side iterator
344  */
345  constexpr int compare(const cow_rw_iterator& rhs) const noexcept {
346  return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
347  : ( iterator_ < rhs.iterator_ ? -1 : 1);
348  }
349 
350  constexpr bool operator==(const cow_rw_iterator& rhs) const noexcept
351  { return compare(rhs) == 0; }
352 
353  constexpr bool operator!=(const cow_rw_iterator& rhs) const noexcept
354  { return compare(rhs) != 0; }
355 
356  // Relation
357 
358  constexpr bool operator<=(const cow_rw_iterator& rhs) const noexcept
359  { return compare(rhs) <= 0; }
360 
361  constexpr bool operator<(const cow_rw_iterator& rhs) const noexcept
362  { return compare(rhs) < 0; }
363 
364  constexpr bool operator>=(const cow_rw_iterator& rhs) const noexcept
365  { return compare(rhs) >= 0; }
366 
367  constexpr bool operator>(const cow_rw_iterator& rhs) const noexcept
368  { return compare(rhs) > 0; }
369 
370  // Forward iterator requirements
371 
372  /**
373  * Dereferencing iterator to value_type reference
374  * @return immutable reference to value_type
375  */
376  constexpr const reference operator*() const noexcept {
377  return *iterator_;
378  }
379 
380  /**
381  * Pointer to member access.
382  * @return immutable pointer to value_type
383  */
384  constexpr const pointer operator->() const noexcept {
385  return &(*iterator_); // just in case iterator_type is a class, trick via dereference
386  }
387 
388  /**
389  * Dereferencing iterator to value_type reference.
390  * @return mutable reference to value_type
391  */
392  constexpr reference operator*() noexcept { return *iterator_; }
393 
394  /**
395  * Pointer to member access.
396  * @return mutable pointer to value_type
397  */
398  constexpr pointer operator->() noexcept {
399  return &(*iterator_); // just in case iterator_type is a class, trick via dereference
400  }
401 
402  /** Pre-increment; Well performing, return *this. */
403  constexpr cow_rw_iterator& operator++() noexcept {
404  ++iterator_;
405  return *this;
406  }
407 
408  /** Post-increment; Try to avoid: Low performance due to returning copy-ctor. */
409  constexpr cow_rw_iterator operator++(int) noexcept
410  { return cow_rw_iterator(cow_parent_, store_ref_, iterator_++); }
411 
412  // Bidirectional iterator requirements
413 
414  /** Pre-decrement; Well performing, return *this. */
415  constexpr cow_rw_iterator& operator--() noexcept {
416  --iterator_;
417  return *this;
418  }
419 
420  /** Post-decrement; Try to avoid: Low performance due to returning copy-ctor. */
421  constexpr cow_rw_iterator operator--(int) noexcept
422  { return cow_rw_iterator(cow_parent_, store_ref_, iterator_--); }
423 
424  // Random access iterator requirements
425 
426  /** Subscript of 'element_index', returning immutable Value_type reference. */
427  constexpr const reference operator[](difference_type i) const noexcept
428  { return iterator_[i]; }
429 
430  /**
431  * Subscript of 'element_index', returning mutable Value_type reference.
432  */
433  constexpr reference operator[](difference_type i) noexcept {
434  return iterator_[i];
435  }
436 
437  /** Addition-assignment of 'element_count'; Well performing, return *this. */
438  constexpr cow_rw_iterator& operator+=(difference_type i) noexcept
439  { iterator_ += i; return *this; }
440 
441  /** Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor. */
442  constexpr cow_rw_iterator operator+(difference_type rhs) const noexcept
443  { return cow_rw_iterator(cow_parent_, store_ref_, iterator_ + rhs); }
444 
445  /** Subtraction-assignment of 'element_count'; Well performing, return *this. */
446  constexpr cow_rw_iterator& operator-=(difference_type i) noexcept
447  { iterator_ -= i; return *this; }
448 
449  /** Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor. */
450  constexpr cow_rw_iterator operator-(difference_type rhs) const noexcept
451  { return cow_rw_iterator(cow_parent_, store_ref_, iterator_ - rhs); }
452 
453  // Distance or element count, binary subtraction of two iterator.
454 
455  /** Binary 'iterator - iterator -> element_count'; Well performing, return element_count of type difference_type. */
456  constexpr difference_type operator-(const cow_rw_iterator& rhs) const noexcept
457  { return iterator_ - rhs.iterator_; }
458 
459  constexpr_cxx20 std::string toString() const noexcept {
460  return jau::to_string(iterator_);
461  }
462 #if 0
463  constexpr_cxx20 operator std::string() const noexcept {
464  return toString();
465  }
466 #endif
467  constexpr_cxx20 std::string get_info() const noexcept {
468  return "cow_rw_iterator[this "+jau::to_hexstring(this)+", CoW "+jau::to_hexstring(&cow_parent_)+
469  ", store "+jau::to_hexstring(&store_ref_)+
470  ", "+jau::to_string(iterator_)+"]";
471  }
472 
473  /**
474  * Removes the last element and sets this iterator to end()
475  */
476  constexpr void pop_back() noexcept {
477  store_ref_->pop_back();
478  iterator_ = store_ref_->end();
479  }
480 
481  /**
482  * Erases the element at the current position.
483  * <p>
484  * This iterator is set to the element following the last removed element.
485  * </p>
486  */
487  constexpr void erase () {
488  iterator_ = store_ref_->erase(iterator_);
489  }
490 
491  /**
492  * Like std::vector::erase(), removes the elements in the range [current, current+count).
493  * <p>
494  * This iterator is set to the element following the last removed element.
495  * </p>
496  */
497  constexpr void erase (size_type count) {
498  iterator_ = store_ref_->erase(iterator_, iterator_+count);
499  }
500 
501  /**
502  * Inserts the element before the current position
503  * and moves all elements from there to the right beforehand.
504  * <p>
505  * size will be increased by one.
506  * </p>
507  * <p>
508  * This iterator is set to the inserted element.
509  * </p>
510  */
511  constexpr void insert(const value_type& x) {
512  iterator_ = store_ref_->insert(iterator_, x);
513  }
514 
515  /**
516  * Inserts the element before the current position (std::move operation)
517  * and moves all elements from there to the right beforehand.
518  * <p>
519  * size will be increased by one.
520  * </p>
521  * <p>
522  * This iterator is set to the inserted element.
523  * </p>
524  */
525  constexpr void insert(value_type&& x) {
526  iterator_ = store_ref_->insert(iterator_, std::move(x));
527  }
528 
529  /**
530  * Like std::vector::emplace(), construct a new element in place.
531  * <p>
532  * Constructs the element before the current position using placement new
533  * and moves all elements from there to the right beforehand.
534  * </p>
535  * <p>
536  * size will be increased by one.
537  * </p>
538  * <p>
539  * This iterator is set to the inserted element.
540  * </p>
541  * @param args arguments to forward to the constructor of the element
542  */
543  template<typename... Args>
544  constexpr void emplace(Args&&... args) {
545  iterator_ = store_ref_->emplace(iterator_, std::forward<Args>(args)... );
546  }
547 
548  /**
549  * Like std::vector::insert(), inserting the value_type range [first, last).
550  * <p>
551  * This iterator is set to the first element inserted, or pos if first==last.
552  * </p>
553  * @tparam InputIt foreign input-iterator to range of value_type [first, last)
554  * @param first first foreign input-iterator to range of value_type [first, last)
555  * @param last last foreign input-iterator to range of value_type [first, last)
556  */
557  template< class InputIt >
558  constexpr void insert( InputIt first, InputIt last ) {
559  iterator_ = store_ref_->insert(iterator_, first, last);
560  }
561 
562  /**
563  * Like std::vector::push_back(), copy
564  * <p>
565  * This iterator is set to the end.
566  * </p>
567  * @param x the value to be added at the tail.
568  */
569  constexpr void push_back(const value_type& x) {
570  store_ref_->push_back(x);
571  iterator_ = store_ref_->end();
572  }
573 
574  /**
575  * Like std::vector::push_back(), move
576  * <p>
577  * This iterator is set to the end.
578  * </p>
579  * @param x the value to be added at the tail.
580  */
581  constexpr void push_back(value_type&& x) {
582  store_ref_->push_back(std::move(x));
583  iterator_ = store_ref_->end();
584  }
585 
586  /**
587  * Like std::vector::emplace_back(), construct a new element in place at the end().
588  * <p>
589  * Constructs the element at the end() using placement new.
590  * </p>
591  * <p>
592  * size will be increased by one.
593  * </p>
594  * <p>
595  * This iterator is set to the end.
596  * </p>
597  * @param args arguments to forward to the constructor of the element
598  */
599  template<typename... Args>
600  constexpr reference emplace_back(Args&&... args) {
601  reference res = store_ref_->emplace_back(std::forward<Args>(args)...);
602  iterator_ = store_ref_->end();
603  return res;
604  }
605 
606  /**
607  * Like std::vector::push_back(), but appends the value_type range [first, last).
608  * <p>
609  * This iterator is set to the end.
610  * </p>
611  * @tparam InputIt foreign input-iterator to range of value_type [first, last)
612  * @param first first foreign input-iterator to range of value_type [first, last)
613  * @param last last foreign input-iterator to range of value_type [first, last)
614  */
615  template< class InputIt >
616  constexpr void push_back( InputIt first, InputIt last ) {
617  store_ref_->push_back(first, last);
618  iterator_ = store_ref_->end();
619  }
620  };
621 
622  /**
623  * Implementation of a Copy-On-Write (CoW) read-onlu iterator over immutable value_type storage.<br>
624  * Instance holds a shared storage snapshot of the parents' CoW storage until destruction.
625  * <p>
626  * Implementation complies with Type Traits iterator_category 'random_access_iterator_tag'
627  * </p>
628  * <p>
629  * Implementation simply wraps the native iterator of type 'iterator_type'
630  * and manages the CoW related resource lifecycle.
631  * </p>
632  * <p>
633  * This iterator is the preferred choice if no mutations are made to the elements state
634  * itself, or all changes can be discarded after the iterator's destruction.<br>
635  * This avoids the costly mutex lock and storage copy of jau::cow_rw_iterator.<br>
636  * Also see jau::for_each_fidelity to iterate through in this good faith fashion.
637  * </p>
638  * <p>
639  * To allow data-race free operations on this iterator's data snapshot from a potentially mutated CoW,
640  * only one begin iterator should be retrieved from CoW and all further operations shall use
641  * jau::cow_ro_iterator::size(), jau::cow_ro_iterator::begin() and jau::cow_ro_iterator::end().
642  * </p>
643  * @see jau::cow_ro_iterator::size()
644  * @see jau::cow_ro_iterator::begin()
645  * @see jau::cow_ro_iterator::end()
646  * @see jau::for_each_fidelity
647  * @see jau::cow_darray
648  */
649  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
650  class cow_ro_iterator {
651  friend cow_rw_iterator<Storage_type, Storage_ref_type, CoW_container>;
652  template<typename, typename, typename, bool, bool, bool> friend class cow_darray;
653  template<typename, typename> friend class cow_vector;
654 
655  public:
656  typedef Storage_type storage_t;
657  typedef Storage_ref_type storage_ref_t;
658  typedef CoW_container cow_container_t;
659 
660  /** Actual const iterator type of the contained native iterator, probably a simple pointer. */
661  typedef typename storage_t::const_iterator iterator_type;
662 
663  private:
664  typedef std::iterator_traits<iterator_type> sub_traits_t;
665 
666  storage_ref_t store_ref_;
667  iterator_type iterator_;
668 
669  constexpr cow_ro_iterator(storage_ref_t store, iterator_type it) noexcept
670  : store_ref_(store), iterator_(it) { }
671 
672  public:
673  typedef typename sub_traits_t::iterator_category iterator_category; // random_access_iterator_tag
674 
675  typedef typename storage_t::size_type size_type; // using our template overload Size_type
676  typedef typename storage_t::difference_type difference_type; // derived from our Size_type
677  // typedef typename storage_t::value_type value_type; // OK
678  // typedef typename storage_t::reference reference; // storage_t is not 'const'
679  // typedef typename storage_t::pointer pointer; // storage_t is not 'const'
680  typedef typename sub_traits_t::value_type value_type; // OK
681  typedef typename sub_traits_t::reference reference; // 'const value_type &'
682  typedef typename sub_traits_t::pointer pointer; // 'const value_type *'
683 
684 #if __cplusplus > 201703L && __cpp_lib_concepts
685  using iterator_concept = std::__detail::__iter_concept<_Iterator>;
686 #endif
687 
688  public:
689  constexpr cow_ro_iterator() noexcept
690  : store_ref_(nullptr), iterator_() { }
691 
692  // C++ named requirements: LegacyIterator: CopyConstructible
693  constexpr cow_ro_iterator(const cow_ro_iterator& o) noexcept
694  : store_ref_(o.store_ref_), iterator_(o.iterator_) {}
695 
696  // C++ named requirements: LegacyIterator: CopyAssignable
697  constexpr cow_ro_iterator& operator=(const cow_ro_iterator& o) noexcept {
698  if( this != &o ) {
699  store_ref_ = o.store_ref_;
700  iterator_ = o.iterator_;
701  }
702  return *this;
703  }
704 
705  // C++ named requirements: LegacyIterator: MoveConstructable
706  constexpr cow_ro_iterator(cow_ro_iterator && o) noexcept
707  : store_ref_(std::move(o.store_ref_)), iterator_(std::move(o.iterator_)) {
708  // Moved source has been disowned semantically and source's dtor will release resources!
709  }
710 
711  // C++ named requirements: LegacyIterator: MoveAssignable
712  constexpr cow_ro_iterator& operator=(cow_ro_iterator&& o) noexcept {
713  if( this != &o ) {
714  store_ref_ = std::move(o.store_ref_);
715  iterator_ = std::move(o.iterator_);
716  // Moved source has been disowned semantically and source's dtor will release resources!
717  }
718  return *this;
719  }
720 
721  // C++ named requirements: LegacyIterator: Swappable
722  void swap(cow_ro_iterator& o) noexcept {
723  std::swap( store_ref_, o.store_ref_);
724  std::swap( iterator_, o.iterator_);
725  }
726 
727  /**
728  * Returns a new const_iterator pointing to the first element, aka begin.
729  * <p>
730  * This is an addition API entry, allowing data-race free operations on
731  * this iterator's data snapshot from a potentially mutated CoW.
732  * </p>
733  * @see size()
734  * @see end()
735  */
736  constexpr cow_ro_iterator cbegin() const noexcept
737  { return cow_ro_iterator( store_ref_, store_ref_->cbegin() ); }
738 
739  /**
740  * Returns a new const_iterator pointing to the <i>element following the last element</i>, aka end.<br>
741  * <p>
742  * This is an addition API entry, allowing data-race free operations on
743  * this iterator's data snapshot from a potentially mutated CoW.
744  * </p>
745  * @see size()
746  * @see begin()
747  */
748  constexpr cow_ro_iterator cend() const noexcept
749  { return cow_ro_iterator( store_ref_, store_ref_->cend() ); }
750 
751  /**
752  * Returns true if storage is empty().
753  */
754  constexpr bool empty() const noexcept { return store_ref_->empty(); }
755 
756  /**
757  * Returns true if storage capacity has been reached and the next push_back()
758  * will grow the storage and invalidates all iterators and references.
759  */
760  constexpr bool capacity_reached() const noexcept { return store_ref_->capacity_reached(); }
761 
762  /**
763  * Return the size of the underlying value_type store.
764  * <p>
765  * This is an addition API entry, allowing data-race free arithmetic on
766  * this iterator's data snapshot from a potentially mutated CoW.
767  * </p>
768  * @see begin()
769  * @see end()
770  */
771  constexpr size_type size() const noexcept { return store_ref_->size(); }
772 
773  /**
774  * Returns this instances' underlying shared storage by reference.
775  */
776  constexpr storage_t& storage() const noexcept {
777  return *store_ref_;
778  }
779 
780  /**
781  * Returns the distance to_end() using zero as first index. A.k.a the remaining elements iterable.
782  */
783  constexpr difference_type dist_end() const noexcept { return store_ref_->cend() - iterator_; }
784 
785  /**
786  * Returns true, if this iterator points to cend().
787  */
788  constexpr bool is_end() const noexcept { return iterator_ == store_ref_->cend(); }
789 
790  /**
791  * This iterator is set to the last element, cend(). Returns *this;
792  */
793  constexpr cow_ro_iterator& to_end() noexcept
794  { iterator_ = store_ref_->cend(); return *this; }
795 
796  /**
797  * Returns the distance to_begin() using zero as first index. A.k.a the index from start.
798  */
799  constexpr difference_type dist_begin() const noexcept { return iterator_ - store_ref_->cbegin(); }
800 
801  /**
802  * Returns true, if this iterator points to cbegin().
803  */
804  constexpr bool is_begin() const noexcept { return iterator_ == store_ref_->cbegin(); }
805 
806  /**
807  * This iterator is set to the first element, cbegin(). Returns *this;
808  */
809  constexpr cow_ro_iterator& to_begin() noexcept
810  { iterator_ = store_ref_->cbegin(); return *this; }
811 
812  /**
813  * Returns a copy of the underlying storage const_iterator.
814  * <p>
815  * This is an addition API entry, inspired by the STL std::normal_iterator.
816  * </p>
817  */
818  constexpr iterator_type base() const noexcept { return iterator_; };
819 
820  // Multipass guarantee equality
821 
822  /**
823  * Returns signum or three-way comparison value
824  * <pre>
825  * 0 if equal (both, store and iteratore),
826  * -1 if this->iterator_ < rhs_iter and
827  * 1 if this->iterator_ > rhs_iter (otherwise)
828  * </pre>
829  * @param rhs_store right-hand side store
830  * @param rhs_iter right-hand side iterator
831  */
832  constexpr int compare(const cow_ro_iterator& rhs) const noexcept {
833  return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
834  : ( iterator_ < rhs.iterator_ ? -1 : 1);
835  }
836 
837  constexpr int compare(const cow_rw_iterator<storage_t, storage_ref_t, cow_container_t>& rhs) const noexcept {
838  return store_ref_ == rhs.store_ref_ && iterator_ == rhs.iterator_ ? 0
839  : ( iterator_ < rhs.iterator_ ? -1 : 1);
840  }
841 
842  constexpr bool operator==(const cow_ro_iterator& rhs) const noexcept
843  { return compare(rhs) == 0; }
844 
845  constexpr bool operator!=(const cow_ro_iterator& rhs) const noexcept
846  { return compare(rhs) != 0; }
847 
848  // Relation
849 
850  constexpr bool operator<=(const cow_ro_iterator& rhs) const noexcept
851  { return compare(rhs) <= 0; }
852 
853  constexpr bool operator<(const cow_ro_iterator& rhs) const noexcept
854  { return compare(rhs) < 0; }
855 
856  constexpr bool operator>=(const cow_ro_iterator& rhs) const noexcept
857  { return compare(rhs) >= 0; }
858 
859  constexpr bool operator>(const cow_ro_iterator& rhs) const noexcept
860  { return compare(rhs) > 0; }
861 
862  // Forward iterator requirements
863 
864  constexpr const reference operator*() const noexcept {
865  return *iterator_;
866  }
867 
868  constexpr const pointer operator->() const noexcept {
869  return &(*iterator_); // just in case iterator_type is a class, trick via dereference
870  }
871 
872  /** Pre-increment; Well performing, return *this. */
873  constexpr cow_ro_iterator& operator++() noexcept {
874  ++iterator_;
875  return *this;
876  }
877 
878  /** Post-increment; Try to avoid: Low performance due to returning copy-ctor. */
879  constexpr cow_ro_iterator operator++(int) noexcept
880  { return cow_ro_iterator(store_ref_, iterator_++); }
881 
882  // Bidirectional iterator requirements
883 
884  /** Pre-decrement; Well performing, return *this. */
885  constexpr cow_ro_iterator& operator--() noexcept {
886  --iterator_;
887  return *this;
888  }
889 
890  /** Post-decrement; Try to avoid: Low performance due to returning copy-ctor. */
891  constexpr cow_ro_iterator operator--(int) noexcept
892  { return cow_ro_iterator(store_ref_, iterator_--); }
893 
894  // Random access iterator requirements
895 
896  /** Subscript of 'element_index', returning immutable Value_type reference. */
897  constexpr const reference operator[](difference_type i) const noexcept
898  { return iterator_[i]; }
899 
900  /** Addition-assignment of 'element_count'; Well performing, return *this. */
902  { iterator_ += i; return *this; }
903 
904  /** Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor. */
905  constexpr cow_ro_iterator operator+(difference_type rhs) const noexcept
906  { return cow_ro_iterator(store_ref_, iterator_ + rhs); }
907 
908  /** Subtraction-assignment of 'element_count'; Well performing, return *this. */
910  { iterator_ -= i; return *this; }
911 
912  /** Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor. */
913  constexpr cow_ro_iterator operator-(difference_type rhs) const noexcept
914  { return cow_ro_iterator(store_ref_, iterator_ - rhs); }
915 
916  // Distance or element count, binary subtraction of two iterator.
917 
918  /** Binary 'iterator - iterator -> element_count'; Well performing, return element_count of type difference_type. */
919  constexpr difference_type operator-(const cow_ro_iterator& rhs) const noexcept
920  { return iterator_ - rhs.iterator_; }
921 
923  { return iterator_ - rhs.iterator_; }
924 
925  constexpr_cxx20 std::string toString() const noexcept {
926  return jau::to_string(iterator_);
927  }
928 #if 0
929  constexpr_cxx20 operator std::string() const noexcept {
930  return toString();
931  }
932 #endif
933  constexpr_cxx20 std::string get_info() const noexcept {
934  return "cow_ro_iterator[this "+jau::to_hexstring(this)+
935  ", store "+jau::to_hexstring(&store_ref_)+
936  ", "+jau::to_string(iterator_)+"]";
937  }
938  };
939 
940  /****************************************************************************************
941  ****************************************************************************************/
942 
943  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
945  out << c.toString();
946  return out;
947  }
948 
949  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
951  out << c.toString();
952  return out;
953  }
954 
955  /****************************************************************************************
956  ****************************************************************************************/
957 
958  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
961  { return lhs.compare(rhs) == 0; }
962 
963  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
966  { return lhs.compare(rhs) != 0; }
967 
968  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
971  { return rhs.compare(lhs) == 0; }
972 
973  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
976  { return rhs.compare(lhs) != 0; }
977 
978  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
981  { return lhs.compare(rhs) <= 0; }
982 
983  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
986  { return rhs.compare(lhs) > 0; }
987 
988  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
991  { return lhs.compare(rhs) < 0; }
992 
993  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
996  { return rhs.compare(lhs) >= 0; }
997 
998  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1001  { return lhs.compare(rhs) >= 0; }
1002 
1003  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1006  { return rhs.compare(lhs) < 0; }
1007 
1008  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1011  { return lhs.compare(rhs) > 0; }
1012 
1013  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1016  { return rhs.compare(lhs) <= 0; }
1017 
1018  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1019  constexpr typename Storage_type::difference_type operator-
1022  { return lhs.distance(rhs); }
1023 
1024  template <typename Storage_type, typename Storage_ref_type, typename CoW_container>
1025  constexpr typename Storage_type::difference_type operator-
1028  { return rhs.distance(lhs) * -1; }
1029 
1030  /****************************************************************************************
1031  ****************************************************************************************/
1032 
1033  /**
1034  * <code>template< class T > is_cow_type<T>::value</code> compile-time Type Trait,
1035  * determining whether the given template class is a CoW type, e.g. jau::cow_darray,
1036  * jau::cow_vector or any of their iterator.
1037  */
1038  template< class, class = void >
1039  struct is_cow_type : std::false_type { };
1040 
1041  /**
1042  * <code>template< class T > is_cow_type<T>::value</code> compile-time Type Trait,
1043  * determining whether the given template class is a CoW type, e.g. jau::cow_darray,
1044  * jau::cow_vector or any of their iterator.
1045  */
1046  template< class T >
1047  struct is_cow_type<T, std::void_t<typename T::cow_container_t>> : std::true_type { };
1048 
1049  /****************************************************************************************
1050  ****************************************************************************************/
1051 
1052 } /* namespace jau */
1053 
1054 
1055 #endif /* JAU_COW_ITERATOR_HPP_ */
constexpr_cxx20
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
Definition: cpp_lang_util.hpp:95
jau::cow_rw_iterator::end
constexpr cow_rw_iterator end() const noexcept
Returns a new iterator pointing to the element following the last element, aka end.
Definition: cow_iterator.hpp:265
jau::cow_rw_iterator::empty
constexpr bool empty() const noexcept
Returns true if storage is empty().
Definition: cow_iterator.hpp:271
jau::cow_ro_iterator::operator++
constexpr cow_ro_iterator operator++(int) noexcept
Post-increment; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:879
jau::cow_ro_iterator::cow_ro_iterator
constexpr cow_ro_iterator(cow_ro_iterator &&o) noexcept
Definition: cow_iterator.hpp:706
jau::cow_ro_iterator::cow_ro_iterator
constexpr cow_ro_iterator() noexcept
Definition: cow_iterator.hpp:689
jau::cow_ro_iterator::operator=
constexpr cow_ro_iterator & operator=(cow_ro_iterator &&o) noexcept
Definition: cow_iterator.hpp:712
jau::cow_ro_iterator::operator--
constexpr cow_ro_iterator & operator--() noexcept
Pre-decrement; Well performing, return *this.
Definition: cow_iterator.hpp:885
jau::cow_ro_iterator
Implementation of a Copy-On-Write (CoW) read-onlu iterator over immutable value_type storage.
Definition: cow_iterator.hpp:44
jau::cow_rw_iterator::begin
constexpr cow_rw_iterator begin() const noexcept
Returns a new iterator pointing to the first element, aka begin.
Definition: cow_iterator.hpp:253
jau::cow_ro_iterator::capacity_reached
constexpr bool capacity_reached() const noexcept
Returns true if storage capacity has been reached and the next push_back() will grow the storage and ...
Definition: cow_iterator.hpp:760
jau::cow_rw_iterator::is_begin
constexpr bool is_begin() const noexcept
Returns true, if this iterator points to begin().
Definition: cow_iterator.hpp:321
jau::operator<<
std::ostream & operator<<(std::ostream &out, const cow_darray< Value_type, Alloc_type > &c)
Definition: cow_darray.hpp:1029
jau::cow_ro_iterator::operator+=
constexpr cow_ro_iterator & operator+=(difference_type i) noexcept
Addition-assignment of 'element_count'; Well performing, return *this.
Definition: cow_iterator.hpp:901
jau::cow_rw_iterator::write_back
void write_back() noexcept
Replace the parent's current store with this iterators' instance, unlock the CoW parents' write lock ...
Definition: cow_iterator.hpp:153
jau::cow_rw_iterator::get_info
constexpr_cxx20 std::string get_info() const noexcept
Definition: cow_iterator.hpp:468
jau::cow_ro_iterator::compare
constexpr int compare(const cow_rw_iterator< storage_t, storage_ref_t, cow_container_t > &rhs) const noexcept
Definition: cow_iterator.hpp:837
jau::cow_ro_iterator::cow_ro_iterator
constexpr cow_ro_iterator(const cow_ro_iterator &o) noexcept
Definition: cow_iterator.hpp:693
jau::cow_rw_iterator::immutable
constexpr cow_ro_iterator< Storage_type, Storage_ref_type, CoW_container > immutable() const noexcept
Returns a new const_iterator pointing to the current position.
Definition: cow_iterator.hpp:241
jau::cow_ro_iterator::storage
constexpr storage_t & storage() const noexcept
Returns this instances' underlying shared storage by reference.
Definition: cow_iterator.hpp:776
jau::cow_ro_iterator::swap
void swap(cow_ro_iterator &o) noexcept
Definition: cow_iterator.hpp:722
jau::cow_ro_iterator::value_type
sub_traits_t::value_type value_type
Definition: cow_iterator.hpp:680
jau::cow_rw_iterator::dist_begin
constexpr difference_type dist_begin() const noexcept
Returns the distance to_begin() using zero as first index.
Definition: cow_iterator.hpp:316
jau::cow_rw_iterator::pointer
sub_traits_t::pointer pointer
Definition: cow_iterator.hpp:123
jau::cow_ro_iterator::operator=
constexpr cow_ro_iterator & operator=(const cow_ro_iterator &o) noexcept
Definition: cow_iterator.hpp:697
jau::cow_ro_iterator::reference
sub_traits_t::reference reference
Definition: cow_iterator.hpp:681
jau::cow_rw_iterator::operator!=
constexpr bool operator!=(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:354
jau
Definition: basic_algos.hpp:34
jau::cow_ro_iterator::iterator_type
storage_t::const_iterator iterator_type
Actual const iterator type of the contained native iterator, probably a simple pointer.
Definition: cow_iterator.hpp:661
jau::cow_ro_iterator::operator!=
constexpr bool operator!=(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:845
jau::is_cow_type
template< class T > is_cow_type<T>::value compile-time Type Trait, determining whether the given temp...
Definition: cow_iterator.hpp:1039
jau::cow_rw_iterator::insert
constexpr void insert(const value_type &x)
Inserts the element before the current position and moves all elements from there to the right before...
Definition: cow_iterator.hpp:512
jau::cow_rw_iterator::difference_type
storage_t::difference_type difference_type
Definition: cow_iterator.hpp:117
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
jau::cow_rw_iterator::emplace
constexpr void emplace(Args &&... args)
Like std::vector::emplace(), construct a new element in place.
Definition: cow_iterator.hpp:545
jau::cow_ro_iterator::operator<=
constexpr bool operator<=(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:850
jau::cow_ro_iterator::size_type
storage_t::size_type size_type
Definition: cow_iterator.hpp:675
jau::cow_ro_iterator::is_begin
constexpr bool is_begin() const noexcept
Returns true, if this iterator points to cbegin().
Definition: cow_iterator.hpp:804
jau::cow_rw_iterator::storage
constexpr storage_t & storage() const noexcept
Returns this instances' underlying shared storage by reference.
Definition: cow_iterator.hpp:293
jau::cow_ro_iterator::cend
constexpr cow_ro_iterator cend() const noexcept
Returns a new const_iterator pointing to the element following the last element, aka end.
Definition: cow_iterator.hpp:748
jau::cow_rw_iterator::operator+=
constexpr cow_rw_iterator & operator+=(difference_type i) noexcept
Addition-assignment of 'element_count'; Well performing, return *this.
Definition: cow_iterator.hpp:439
jau::cow_rw_iterator::operator++
constexpr cow_rw_iterator & operator++() noexcept
Pre-increment; Well performing, return *this.
Definition: cow_iterator.hpp:404
jau::cow_ro_iterator::dist_begin
constexpr difference_type dist_begin() const noexcept
Returns the distance to_begin() using zero as first index.
Definition: cow_iterator.hpp:799
jau::cow_rw_iterator::operator-=
constexpr cow_rw_iterator & operator-=(difference_type i) noexcept
Subtraction-assignment of 'element_count'; Well performing, return *this.
Definition: cow_iterator.hpp:447
jau::cow_rw_iterator::operator==
constexpr bool operator==(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:351
jau::cow_ro_iterator::operator-
constexpr difference_type operator-(const cow_ro_iterator &rhs) const noexcept
Binary 'iterator - iterator -> element_count'; Well performing, return element_count of type differen...
Definition: cow_iterator.hpp:919
jau::cow_rw_iterator::base
constexpr iterator_type base() const noexcept
Returns a copy of the underlying storage iterator.
Definition: cow_iterator.hpp:332
jau::cow_rw_iterator::emplace_back
constexpr reference emplace_back(Args &&... args)
Like std::vector::emplace_back(), construct a new element in place at the end().
Definition: cow_iterator.hpp:601
jau::cow_ro_iterator::storage_t
Storage_type storage_t
Definition: cow_iterator.hpp:656
jau::cow_rw_iterator::operator+
constexpr cow_rw_iterator operator+(difference_type rhs) const noexcept
Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:443
jau::cow_ro_iterator::operator>=
constexpr bool operator>=(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:856
jau::cow_ro_iterator::get_info
constexpr_cxx20 std::string get_info() const noexcept
Definition: cow_iterator.hpp:933
jau::swap
void swap(cow_darray< Value_type, Alloc_type > &rhs, cow_darray< Value_type, Alloc_type > &lhs) noexcept
Definition: cow_darray.hpp:1073
jau::cow_rw_iterator::dist_end
constexpr difference_type dist_end() const noexcept
Returns the distance to_end() using zero as first index.
Definition: cow_iterator.hpp:300
jau::cow_rw_iterator::to_end
constexpr cow_rw_iterator & to_end() noexcept
This iterator is set to the last element, end().
Definition: cow_iterator.hpp:310
jau::cow_ro_iterator::operator*
constexpr const reference operator*() const noexcept
Definition: cow_iterator.hpp:864
jau::cow_rw_iterator::operator<=
constexpr bool operator<=(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:359
jau::cow_rw_iterator::size
constexpr size_type size() const noexcept
Return the size of the underlying value_type store.
Definition: cow_iterator.hpp:288
jau::cow_ro_iterator::pointer
sub_traits_t::pointer pointer
Definition: cow_iterator.hpp:682
jau::cow_ro_iterator::distance
constexpr difference_type distance(const cow_rw_iterator< storage_t, storage_ref_t, cow_container_t > &rhs) const noexcept
Definition: cow_iterator.hpp:922
jau::cow_rw_iterator::operator--
constexpr cow_rw_iterator & operator--() noexcept
Pre-decrement; Well performing, return *this.
Definition: cow_iterator.hpp:416
jau::cow_rw_iterator::operator[]
constexpr const reference operator[](difference_type i) const noexcept
Subscript of 'element_index', returning immutable Value_type reference.
Definition: cow_iterator.hpp:428
jau::cow_ro_iterator::storage_ref_t
Storage_ref_type storage_ref_t
Definition: cow_iterator.hpp:657
jau::cow_ro_iterator::toString
constexpr_cxx20 std::string toString() const noexcept
Definition: cow_iterator.hpp:925
jau::cow_rw_iterator::storage_ref_t
Storage_ref_type storage_ref_t
Definition: cow_iterator.hpp:91
jau::cow_darray
Implementation of a Copy-On-Write (CoW) using jau::darray as the underlying storage,...
Definition: cow_darray.hpp:130
jau::cow_rw_iterator::iterator_category
sub_traits_t::iterator_category iterator_category
Definition: cow_iterator.hpp:114
jau::cow_ro_iterator::operator<
constexpr bool operator<(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:853
jau::cow_rw_iterator::swap
void swap(cow_rw_iterator &o) noexcept
C++ named requirements: LegacyIterator: Swappable.
Definition: cow_iterator.hpp:223
jau::cow_ro_iterator::iterator_category
sub_traits_t::iterator_category iterator_category
Definition: cow_iterator.hpp:673
jau::operator<=
bool operator<=(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
Definition: cow_darray.hpp:1065
debug.hpp
jau::cow_rw_iterator::operator->
constexpr const pointer operator->() const noexcept
Pointer to member access.
Definition: cow_iterator.hpp:385
jau::cow_ro_iterator::operator-=
constexpr cow_ro_iterator & operator-=(difference_type i) noexcept
Subtraction-assignment of 'element_count'; Well performing, return *this.
Definition: cow_iterator.hpp:909
jau::cow_rw_iterator::operator<
constexpr bool operator<(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:362
jau::cow_ro_iterator::empty
constexpr bool empty() const noexcept
Returns true if storage is empty().
Definition: cow_iterator.hpp:754
jau::cow_ro_iterator::operator==
constexpr bool operator==(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:842
jau::cow_ro_iterator::operator[]
constexpr const reference operator[](difference_type i) const noexcept
Subscript of 'element_index', returning immutable Value_type reference.
Definition: cow_iterator.hpp:897
jau::cow_rw_iterator::operator>
constexpr bool operator>(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:368
jau::cow_rw_iterator::is_end
constexpr bool is_end() const noexcept
Returns true, if this iterator points to end().
Definition: cow_iterator.hpp:305
jau::cow_rw_iterator::capacity_reached
constexpr bool capacity_reached() const noexcept
Returns true if storage capacity has been reached and the next push_back() will grow the storage and ...
Definition: cow_iterator.hpp:277
jau::operator>
bool operator>(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
Definition: cow_darray.hpp:1061
jau::cow_rw_iterator::to_begin
constexpr cow_rw_iterator & to_begin() noexcept
This iterator is set to the first element, begin().
Definition: cow_iterator.hpp:326
jau::cow_rw_iterator::push_back
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: cow_iterator.hpp:570
jau::cow_rw_iterator::operator=
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.
Definition: cow_iterator.hpp:179
jau::to_hexstring
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Definition: string_util.hpp:104
jau::cow_rw_iterator::reference
sub_traits_t::reference reference
Definition: cow_iterator.hpp:122
jau::cow_ro_iterator::operator->
constexpr const pointer operator->() const noexcept
Definition: cow_iterator.hpp:868
cpp_lang_util.hpp
jau::cow_rw_iterator::size_type
storage_t::size_type size_type
Definition: cow_iterator.hpp:116
jau::cow_ro_iterator::cow_container_t
CoW_container cow_container_t
Definition: cow_iterator.hpp:658
jau::cow_ro_iterator::base
constexpr iterator_type base() const noexcept
Returns a copy of the underlying storage const_iterator.
Definition: cow_iterator.hpp:818
jau::cow_ro_iterator::operator--
constexpr cow_ro_iterator operator--(int) noexcept
Post-decrement; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:891
jau::cow_ro_iterator::size
constexpr size_type size() const noexcept
Return the size of the underlying value_type store.
Definition: cow_iterator.hpp:771
jau::operator!=
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:155
basic_types.hpp
jau::cow_rw_iterator
Implementation of a Copy-On-Write (CoW) read-write iterator over mutable value_type storage.
Definition: cow_iterator.hpp:47
jau::cow_ro_iterator::is_end
constexpr bool is_end() const noexcept
Returns true, if this iterator points to cend().
Definition: cow_iterator.hpp:788
jau::cow_rw_iterator::toString
constexpr_cxx20 std::string toString() const noexcept
Definition: cow_iterator.hpp:460
jau::cow_rw_iterator::cow_container_t
CoW_container cow_container_t
Definition: cow_iterator.hpp:92
jau::cow_ro_iterator::to_begin
constexpr cow_ro_iterator & to_begin() noexcept
This iterator is set to the first element, cbegin().
Definition: cow_iterator.hpp:809
jau::cow_rw_iterator::operator>=
constexpr bool operator>=(const cow_rw_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:365
jau::cow_ro_iterator::operator>
constexpr bool operator>(const cow_ro_iterator &rhs) const noexcept
Definition: cow_iterator.hpp:859
jau::cow_ro_iterator::compare
constexpr int compare(const cow_ro_iterator &rhs) const noexcept
Returns signum or three-way comparison value.
Definition: cow_iterator.hpp:832
jau::cow_rw_iterator::value_type
sub_traits_t::value_type value_type
Definition: cow_iterator.hpp:121
jau::cow_rw_iterator::operator-
constexpr cow_rw_iterator operator-(difference_type rhs) const noexcept
Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:451
jau::operator>=
bool operator>=(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
Definition: cow_darray.hpp:1069
jau::cow_rw_iterator::erase
constexpr void erase()
Erases the element at the current position.
Definition: cow_iterator.hpp:488
jau::cow_ro_iterator::operator++
constexpr cow_ro_iterator & operator++() noexcept
Pre-increment; Well performing, return *this.
Definition: cow_iterator.hpp:873
jau::cow_vector
Implementation of a Copy-On-Write (CoW) using std::vector as the underlying storage,...
Definition: cow_vector.hpp:107
jau::cow_ro_iterator::difference_type
storage_t::difference_type difference_type
Definition: cow_iterator.hpp:676
jau::cow_ro_iterator::to_end
constexpr cow_ro_iterator & to_end() noexcept
This iterator is set to the last element, cend().
Definition: cow_iterator.hpp:793
jau::cow_ro_iterator::cbegin
constexpr cow_ro_iterator cbegin() const noexcept
Returns a new const_iterator pointing to the first element, aka begin.
Definition: cow_iterator.hpp:736
jau::cow_rw_iterator::storage_t
Storage_type storage_t
Definition: cow_iterator.hpp:90
jau::cow_ro_iterator::operator-
constexpr cow_ro_iterator operator-(difference_type rhs) const noexcept
Binary 'iterator - element_count'; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:913
jau::operator==
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:142
jau::cow_ro_iterator::operator+
constexpr cow_ro_iterator operator+(difference_type rhs) const noexcept
Binary 'iterator + element_count'; Try to avoid: Low performance due to returning copy-ctor.
Definition: cow_iterator.hpp:905
jau::cow_rw_iterator::compare
constexpr int compare(const cow_rw_iterator &rhs) const noexcept
Returns signum or three-way comparison value.
Definition: cow_iterator.hpp:346
jau::operator<
bool operator<(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
Definition: cow_darray.hpp:1052
jau::cow_rw_iterator::operator*
constexpr const reference operator*() const noexcept
Dereferencing iterator to value_type reference.
Definition: cow_iterator.hpp:377
jau::cow_rw_iterator::pop_back
constexpr void pop_back() noexcept
Removes the last element and sets this iterator to end()
Definition: cow_iterator.hpp:477
jau::cow_ro_iterator::dist_end
constexpr difference_type dist_end() const noexcept
Returns the distance to_end() using zero as first index.
Definition: cow_iterator.hpp:783
jau::cow_rw_iterator::iterator_type
storage_t::iterator iterator_type
Actual iterator type of the contained native iterator, probably a simple pointer.
Definition: cow_iterator.hpp:95