From 0757b2e6e43f638dc6a424cbf69cae51854eb0b0 Mon Sep 17 00:00:00 2001 From: Hossein Moein Date: Mon, 29 Apr 2024 12:34:36 -0400 Subject: [PATCH] Added sentinels to vector views iterators --- include/DataFrame/Vectors/HeteroVector.h | 3 +- include/DataFrame/Vectors/VectorPtrView.h | 127 +++++++++++++++------- include/DataFrame/Vectors/VectorView.h | 122 +++++++++++++++------ 3 files changed, 178 insertions(+), 74 deletions(-) diff --git a/include/DataFrame/Vectors/HeteroVector.h b/include/DataFrame/Vectors/HeteroVector.h index e1bb54d5..fc4e66d9 100644 --- a/include/DataFrame/Vectors/HeteroVector.h +++ b/include/DataFrame/Vectors/HeteroVector.h @@ -70,7 +70,8 @@ struct HeteroVector { [[nodiscard]] std::vector::type> & get_vector(); template - [[nodiscard]] const std::vector::type> & + [[nodiscard]] + const std::vector::type> & get_vector() const; // It returns a view of the underlying vector. diff --git a/include/DataFrame/Vectors/VectorPtrView.h b/include/DataFrame/Vectors/VectorPtrView.h index df4df9de..bd498f7a 100644 --- a/include/DataFrame/Vectors/VectorPtrView.h +++ b/include/DataFrame/Vectors/VectorPtrView.h @@ -41,6 +41,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace hmdf { +struct VPVSentinel { + + VPVSentinel() = default; + VPVSentinel(const VPVSentinel &) = default; + VPVSentinel(VPVSentinel &&) = default; + VPVSentinel &operator = (const VPVSentinel &) = default; + VPVSentinel &operator = (VPVSentinel &&) = default; + ~VPVSentinel() = default; +}; + +// ---------------------------------------------------------------------------- + template class VectorPtrView { @@ -213,18 +225,16 @@ class VectorPtrView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline iterator () = default; - inline iterator (const iterator &) = default; - inline iterator (iterator &&) = default; - inline iterator &operator = (const iterator &) = default; - inline iterator &operator = (iterator &&) = default; - inline iterator (iter_type node) noexcept : node_ (node) { } inline iterator (pointer *node) noexcept : node_ (node) { } + iterator () = default; + ~iterator () = default; + iterator (const iterator &) = default; + iterator (iterator &&) = default; + iterator &operator = (const iterator &) = default; + iterator &operator = (iterator &&) = default; + inline iterator &operator = (iter_type rhs) noexcept { node_ = rhs; @@ -261,12 +271,24 @@ class VectorPtrView { return (node_ <= rhs.node_); } + friend bool + operator == (const iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ == rhs.vector_.end()); + } + friend bool + operator != (const iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ != rhs.vector_.end()); + } + // Following STL style, this iterator appears as a pointer // to value_type. // inline pointer operator -> () noexcept { return (*node_); } inline reference operator * () noexcept { return (**node_); } - inline const_pointer operator -> () const noexcept { return (*node_); } + inline const_pointer + operator -> () const noexcept { return (*node_); } inline const_reference operator * () const noexcept { return (**node_); } inline operator pointer() noexcept { return (*node_); } @@ -313,7 +335,7 @@ class VectorPtrView { } template - inline iterator operator + (I step) noexcept { + inline iterator operator + (I step) const noexcept { auto ret_node = node_; @@ -321,7 +343,7 @@ class VectorPtrView { return (iterator { ret_node }); } template<> - inline iterator operator + (const iterator &rhs) noexcept { + inline iterator operator + (const iterator &rhs) const noexcept { return (iterator (node_ + rhs.node_)); } @@ -333,7 +355,7 @@ class VectorPtrView { } template - inline iterator operator - (I step) noexcept { + inline iterator operator - (I step) const noexcept { auto ret_node = node_; @@ -377,20 +399,18 @@ class VectorPtrView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline const_iterator () = default; - inline const_iterator (const const_iterator &) = default; - inline const_iterator (const_iterator &&) = default; - inline const_iterator &operator = (const const_iterator &) = default; - inline const_iterator &operator = (const_iterator &&) = default; - inline const_iterator (iter_type node) noexcept : node_ (node) { } inline const_iterator (pointer const *node) noexcept : node_ (node) { } inline const_iterator (const iterator &itr) noexcept { *this = itr; } + const_iterator () = default; + ~const_iterator () = default; + const_iterator (const const_iterator &) = default; + const_iterator (const_iterator &&) = default; + const_iterator &operator = (const const_iterator &) = default; + const_iterator &operator = (const_iterator &&) = default; + inline const_iterator &operator = (iter_type rhs) noexcept { node_ = rhs; @@ -432,6 +452,17 @@ class VectorPtrView { return (node_ <= rhs.node_); } + friend bool + operator == (const const_iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ == rhs.vector_.end()); + } + friend bool + operator != (const const_iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ != rhs.vector_.end()); + } + // Following STL style, this iterator appears as a pointer // to value_type. // @@ -491,7 +522,7 @@ class VectorPtrView { } template - inline const_iterator operator + (I step) noexcept { + inline const_iterator operator + (I step) const noexcept { auto const ret_node = node_; @@ -499,7 +530,8 @@ class VectorPtrView { return (const_iterator { ret_node }); } template<> - inline const_iterator operator + (const const_iterator &rhs) noexcept { + inline const_iterator + operator + (const const_iterator &rhs) const noexcept { return (const_iterator (node_ + rhs.node_)); } @@ -511,7 +543,7 @@ class VectorPtrView { } template - inline const_iterator operator - (I step) noexcept { + inline const_iterator operator - (I step) const noexcept { auto const ret_node = node_; @@ -533,6 +565,9 @@ class VectorPtrView { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; + friend class iterator; + friend class const_iterator; + [[nodiscard]] inline iterator begin () noexcept { return (iterator(vector_.begin())); } [[nodiscard]] inline iterator @@ -628,7 +663,8 @@ class VectorConstPtrView { swap (VectorConstPtrView &rhs) noexcept { vector_.swap (rhs.vector_); } [[nodiscard]] inline friend bool - operator == (const VectorConstPtrView &lhs, const VectorConstPtrView &rhs) { + operator == (const VectorConstPtrView &lhs, + const VectorConstPtrView &rhs) { return (lhs.vector_ == rhs.vector_); } @@ -746,19 +782,17 @@ class VectorConstPtrView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline const_iterator () = default; - inline const_iterator (const const_iterator &) = default; - inline const_iterator (const_iterator &&) = default; - inline const_iterator &operator = (const const_iterator &) = default; - inline const_iterator &operator = (const_iterator &&) = default; - inline const_iterator (iter_type node) noexcept : node_ (node) { } inline const_iterator (pointer const *node) noexcept : node_ (node) { } + const_iterator () = default; + ~const_iterator () = default; + const_iterator (const const_iterator &) = default; + const_iterator (const_iterator &&) = default; + const_iterator &operator = (const const_iterator &) = default; + const_iterator &operator = (const_iterator &&) = default; + inline const_iterator &operator = (iter_type rhs) noexcept { node_ = rhs; @@ -795,6 +829,17 @@ class VectorConstPtrView { return (node_ <= rhs.node_); } + friend bool + operator == (const const_iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ == rhs.vector_.end()); + } + friend bool + operator != (const const_iterator &rhs, VPVSentinel) noexcept { + + return (rhs.node_ != rhs.vector_.end()); + } + // Following STL style, this iterator appears as a pointer // to value_type. // @@ -853,7 +898,7 @@ class VectorConstPtrView { return (*this); } - inline const_iterator operator + (int step) noexcept { + inline const_iterator operator + (int step) const noexcept { value_type const **ret_node = node_; @@ -861,7 +906,7 @@ class VectorConstPtrView { return (const_iterator (ret_node)); } - inline const_iterator operator - (int step) noexcept { + inline const_iterator operator - (int step) const noexcept { value_type const **ret_node = node_; @@ -869,7 +914,8 @@ class VectorConstPtrView { return (const_iterator (ret_node)); } - inline const_iterator operator + (difference_type step) noexcept { + inline const_iterator + operator + (difference_type step) const noexcept { value_type const **ret_node = node_; @@ -877,7 +923,8 @@ class VectorConstPtrView { return (const_iterator (ret_node)); } - inline const_iterator operator - (difference_type step) noexcept { + inline const_iterator + operator - (difference_type step) const noexcept { value_type const **ret_node = node_; @@ -898,6 +945,8 @@ class VectorConstPtrView { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; + friend class const_iterator; + [[nodiscard]] inline const_iterator begin() const noexcept { return (const_iterator(vector_.begin())); } [[nodiscard]] inline const_iterator diff --git a/include/DataFrame/Vectors/VectorView.h b/include/DataFrame/Vectors/VectorView.h index 55a87f69..e98e1aff 100644 --- a/include/DataFrame/Vectors/VectorView.h +++ b/include/DataFrame/Vectors/VectorView.h @@ -39,12 +39,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace hmdf { +struct VVSentinel { + + VVSentinel() = default; + VVSentinel(const VVSentinel &) = default; + VVSentinel(VVSentinel &&) = default; + VVSentinel &operator = (const VVSentinel &) = default; + VVSentinel &operator = (VVSentinel &&) = default; + ~VVSentinel() = default; +}; + +// ---------------------------------------------------------------------------- + // This is a view that would make an already existing array of // continuous memory look like an STL vector. // It also gives you STL conformant iterators. // template -class VectorView { +class VectorView { public: @@ -156,17 +168,18 @@ class VectorView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline const_iterator () = default; - inline const_iterator (value_type const *const node) noexcept : node_ (node) { } - inline const_iterator (const iterator &itr) noexcept : node_ (nullptr) { *this = itr; } + const_iterator () = default; + ~const_iterator () = default; + const_iterator (const const_iterator &) = default; + const_iterator (const_iterator &&) = default; + const_iterator &operator = (const const_iterator &) = default; + const_iterator &operator = (const_iterator &&) = default; + inline const_iterator &operator = (const iterator &rhs) noexcept { node_ = rhs.node_; @@ -198,15 +211,25 @@ class VectorView { return (node_ <= rhs.node_); } + friend bool + operator == (const const_iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ == rhs.end_ptr_); + } + friend bool + operator != (const const_iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ != rhs.end_ptr_); + } + // Following STL style, this iterator appears as a pointer // to value_type. // - inline const_pointer operator -> () const noexcept { return (node_); } inline const_reference operator * () const noexcept { return (*node_); } - inline operator const_pointer () const noexcept { return (node_); } + inline const_pointer operator -> () noexcept { return (node_); } // ++Prefix // @@ -257,7 +280,7 @@ class VectorView { } template - inline const_iterator operator + (I step) noexcept { + inline const_iterator operator + (I step) const noexcept { value_type const *ret_node = node_; @@ -265,7 +288,8 @@ class VectorView { return (const_iterator (ret_node)); } template<> - inline const_iterator operator + (const const_iterator &rhs) noexcept { + inline const_iterator + operator + (const const_iterator &rhs) const noexcept { return (const_iterator (node_ + rhs.node_)); } @@ -277,7 +301,7 @@ class VectorView { } template - inline const_iterator operator - (I step) noexcept { + inline const_iterator operator - (I step) const noexcept { value_type const *ret_node = node_; @@ -315,13 +339,15 @@ class VectorView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline iterator () = default; - inline iterator (value_type *node) noexcept : node_ (node) { } + iterator () = default; + ~iterator () = default; + iterator (const iterator &) = default; + iterator (iterator &&) = default; + iterator &operator = (const iterator &) = default; + iterator &operator = (iterator &&) = default; + inline bool operator == (const iterator &rhs) const noexcept { return (node_ == rhs.node_); @@ -347,12 +373,22 @@ class VectorView { return (node_ <= rhs.node_); } + friend bool + operator == (const iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ == rhs.end_ptr_); + } + friend bool + operator != (const iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ != rhs.end_ptr_); + } + // Following STL style, this iterator appears as a pointer // to value_type. // - inline pointer operator -> () const noexcept { return (node_); } - inline reference operator * () const noexcept { return (*node_); } - inline operator pointer () const noexcept { return (node_); } + inline reference operator * () const noexcept { return (*node_); } + inline pointer operator -> () noexcept { return (node_); } // We are following STL style iterator interface. // @@ -395,7 +431,7 @@ class VectorView { } template - inline iterator operator + (I step) noexcept { + inline iterator operator + (I step) const noexcept { value_type *ret_node = node_; @@ -403,7 +439,7 @@ class VectorView { return (iterator (ret_node)); } template<> - inline iterator operator + (const iterator &rhs) noexcept { + inline iterator operator + (const iterator &rhs) const noexcept { return (iterator (node_ + rhs.node_)); } @@ -415,7 +451,7 @@ class VectorView { } template - inline iterator operator - (I step) noexcept { + inline iterator operator - (I step) const noexcept { value_type *ret_node = node_; @@ -441,6 +477,9 @@ class VectorView { friend class VectorView::const_iterator; }; + friend class iterator; + friend class const_iterator; + using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; @@ -542,7 +581,7 @@ class VectorConstView { at (size_type i) const noexcept { return (*(begin_ptr_ + i)); } [[nodiscard]] inline const_reference operator [] (size_type i) const noexcept { return (*(begin_ptr_ + i)); } - [[nodiscard]] inline const_reference + [[nodiscard]] inline const_reference ront() const noexcept { return (*begin_ptr_); } [[nodiscard]] inline const_reference back() const noexcept { return (*(end_ptr_ - 1)); } @@ -585,14 +624,16 @@ class VectorConstView { public: - // NOTE: The constructor with no argument initializes - // the iterator to be the "end" iterator - // - inline const_iterator () = default; - inline const_iterator (value_type const *const node) noexcept : node_ (node) { } + const_iterator () = default; + ~const_iterator () = default; + const_iterator (const const_iterator &) = default; + const_iterator (const_iterator &&) = default; + const_iterator &operator = (const const_iterator &) = default; + const_iterator &operator = (const_iterator &&) = default; + inline bool operator == (const const_iterator &rhs) const noexcept { return (node_ == rhs.node_); @@ -618,15 +659,25 @@ class VectorConstView { return (node_ <= rhs.node_); } + friend bool + operator == (const const_iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ == rhs.end_ptr_); + } + friend bool + operator != (const const_iterator &rhs, VVSentinel) noexcept { + + return (rhs.node_ != rhs.end_ptr_); + } + // Following STL style, this iterator appears as a pointer // to value_type. // - inline const_pointer operator -> () const noexcept { return (node_); } inline const_reference operator * () const noexcept { return (*node_); } - inline operator const_pointer () const noexcept { return (node_); } + inline const_pointer operator -> () noexcept { return (node_); } // ++Prefix // @@ -677,7 +728,7 @@ class VectorConstView { } template - inline const_iterator operator + (I step) noexcept { + inline const_iterator operator + (I step) const noexcept { value_type const *ret_node = node_; @@ -685,7 +736,8 @@ class VectorConstView { return (const_iterator (ret_node)); } template<> - inline const_iterator operator + (const const_iterator &rhs) noexcept { + inline const_iterator + operator + (const const_iterator &rhs) const noexcept { return (const_iterator (node_ + rhs.node_)); } @@ -697,7 +749,7 @@ class VectorConstView { } template - inline const_iterator operator - (I step) noexcept { + inline const_iterator operator - (I step) const noexcept { value_type const *ret_node = node_; @@ -719,6 +771,8 @@ class VectorConstView { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; + friend class const_iterator; + [[nodiscard]] inline const_iterator begin () const noexcept { return (const_iterator (begin_ptr_)); } [[nodiscard]] inline const_iterator