/*------------------------------------------------------------------------------ * Copyright (c) 2023 by Bai Bing (seread@163.com) * See COPYING file for copying and redistribution conditions. * * Alians IT Studio. *----------------------------------------------------------------------------*/ #pragma once #include #include #include "_Define.h" namespace ais { //================================================================================ // Class Description: /// Custom const_iterator for template class AIS_EXPORT ConstIterator { private: using self_type = ConstIterator; public: using iterator_category = std::random_access_iterator_tag; using value_type = dtype; using pointer = PointerType; using reference = const value_type &; using difference_type = DifferenceType; //============================================================================ // Method Description: /// Default Constructor /// ConstIterator() = default; //============================================================================ // Method Description: /// Constructor /// /// @param ptr: the iterator pointer /// explicit ConstIterator(pointer ptr) : ptr_(ptr) { if (ptr == nullptr) { throw std::runtime_error(" has not been initialized."); } } //============================================================================ // Method Description: /// Iterator dereference /// /// @return reference /// reference operator*() const noexcept { return *ptr_; } //============================================================================ // Method Description: /// Iterator pointer operator /// /// @return pointer /// pointer operator->() const noexcept { return ptr_; } //============================================================================ // Method Description: /// Iterator prefix increment operator /// /// @return ConstIterator& /// self_type &operator++() noexcept { ++ptr_; return *this; } //============================================================================ // Method Description: /// Iterator postfix increment operator /// /// @return ConstIterator /// self_type operator++(int) noexcept { self_type tmp = *this; ++*this; return tmp; } //============================================================================ // Method Description: /// Iterator prefix decrement operator /// /// @return ConstIterator& /// self_type &operator--() noexcept { --ptr_; return *this; } //============================================================================ // Method Description: /// Iterator postfix decrement operator /// /// @return ConstIterator /// self_type operator--(int) noexcept { self_type tmp = *this; --*this; return tmp; } //============================================================================ // Method Description: /// Iterator addition assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator+=(const difference_type offset) noexcept { ptr_ += offset; return *this; } //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @return ConstIterator /// self_type operator+(const difference_type offset) const noexcept { self_type tmp = *this; return tmp += offset; } //============================================================================ // Method Description: /// Iterator subtraction assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator-=(const difference_type offset) noexcept { return *this += -offset; } //============================================================================ // Method Description: /// Iterator subtraction operator /// /// @param offset /// @return ConstIterator /// self_type operator-(const difference_type offset) const noexcept { self_type tmp = *this; return tmp -= offset; } //============================================================================ // Method Description: /// Iterator difference operator /// /// @param rhs /// @return difference_type /// difference_type operator-(const self_type &rhs) const noexcept { return ptr_ - rhs.ptr_; } //============================================================================ // Method Description: /// Iterator access operator /// /// @param offset /// @return reference /// reference operator[](const difference_type offset) const noexcept { return *(*this + offset); } //============================================================================ // Method Description: /// Iterator equality operator /// /// @param rhs /// @return bool /// bool operator==(const self_type &rhs) const noexcept { return ptr_ == rhs.ptr_; } //============================================================================ // Method Description: /// Iterator not-equality operator /// /// @param rhs /// @return bool /// bool operator!=(const self_type &rhs) const noexcept { return !(*this == rhs); } //============================================================================ // Method Description: /// Iterator less than operator /// /// @param rhs /// @return bool /// bool operator<(const self_type &rhs) const noexcept { return ptr_ < rhs.ptr_; } //============================================================================ // Method Description: /// Iterator greater than operator /// /// @param rhs /// @return bool /// bool operator>(const self_type &rhs) const noexcept { return rhs < *this; } //============================================================================ // Method Description: /// Iterator less than equal operator /// /// @param rhs /// @return bool /// bool operator<=(const self_type &rhs) const noexcept { return !(rhs < *this); } //============================================================================ // Method Description: /// Iterator greater than equal operator /// /// @param rhs /// @return bool /// bool operator>=(const self_type &rhs) const noexcept { return !(*this < rhs); } private: pointer ptr_{nullptr}; }; //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @param next /// @return bool /// template AIS_EXPORT ConstIterator operator+(typename ConstIterator::difference_type offset, ConstIterator next) noexcept { return next += offset; } //================================================================================ // Class Description: /// Custom iterator for template class AIS_EXPORT Iterator : public ConstIterator { private: using MyBase = ConstIterator; using self_type = Iterator; public: using iterator_category = std::random_access_iterator_tag; using value_type = dtype; using pointer = PointerType; using reference = value_type &; using difference_type = DifferenceType; using MyBase::MyBase; //============================================================================ // Method Description: /// Iterator dereference /// /// @return reference /// reference operator*() const noexcept { return const_cast(MyBase::operator*()); } //============================================================================ // Method Description: /// Iterator pointer operator /// /// @return pointer /// pointer operator->() const noexcept { return const_cast(MyBase::operator->()); } //============================================================================ // Method Description: /// Iterator prefix increment operator /// /// @return ConstIterator& /// self_type &operator++() noexcept { MyBase::operator++(); return *this; } //============================================================================ // Method Description: /// Iterator postfix increment operator /// /// @return ConstIterator /// self_type operator++(int) noexcept { self_type tmp = *this; MyBase::operator++(); return tmp; } //============================================================================ // Method Description: /// Iterator prefix decrement operator /// /// @return ConstIterator& /// self_type &operator--() noexcept { MyBase::operator--(); return *this; } //============================================================================ // Method Description: /// Iterator postfix decrement operator /// /// @return ConstIterator /// self_type operator--(int) noexcept { self_type tmp = *this; MyBase::operator--(); return tmp; } //============================================================================ // Method Description: /// Iterator addition assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator+=(const difference_type offset) noexcept { MyBase::operator+=(offset); return *this; } //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @return ConstIterator /// self_type operator+(const difference_type offset) const noexcept { self_type tmp = *this; return tmp += offset; } //============================================================================ // Method Description: /// Iterator subtraction assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator-=(const difference_type offset) noexcept { MyBase::operator-=(offset); return *this; } using MyBase::operator-; //============================================================================ // Method Description: /// Iterator difference operator /// /// @param offset /// @return ConstIterator /// self_type operator-(const difference_type offset) const noexcept { self_type tmp = *this; return tmp -= offset; } //============================================================================ // Method Description: /// Iterator access operator /// /// @param offset /// @return reference /// reference operator[](const difference_type offset) const noexcept { return const_cast(MyBase::operator[](offset)); } }; //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @param next /// @return Iterator /// template AIS_EXPORT Iterator operator+(typename Iterator::difference_type offset, Iterator next) noexcept { return next += offset; } //================================================================================ // Class Description: /// Custom column const_iterator for template class AIS_EXPORT ConstColumnIterator { private: using self_type = ConstColumnIterator; public: using iterator_category = std::random_access_iterator_tag; using value_type = dtype; using size_type = SizeType; using pointer = PointerType; using reference = const value_type &; using difference_type = DifferenceType; //============================================================================ // Method Description: /// Default Constructor /// ConstColumnIterator() = default; //============================================================================ // Method Description: /// Constructor /// /// @param ptr: the iterator pointer /// @param numRows: the number of rows in the array /// @param numCols: the number of cols in the array /// ConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept : ptr_(ptr), currPtr_(ptr), numRows_(static_cast(numRows)), numCols_(static_cast(numCols)), size_(numRows_ * numCols_) { } //============================================================================ // Method Description: /// Iterator dereference /// /// @return reference /// reference operator*() const noexcept { return *currPtr_; } //============================================================================ // Method Description: /// Iterator pointer operator /// /// @return pointer /// pointer operator->() const noexcept { return currPtr_; } //============================================================================ // Method Description: /// Iterator prefix increment operator /// /// @return ConstIterator& /// self_type &operator++() noexcept { return *this += 1; } //============================================================================ // Method Description: /// Iterator postfix increment operator /// /// @return ConstIterator /// self_type operator++(int) noexcept { self_type tmp = *this; ++*this; return tmp; } //============================================================================ // Method Description: /// Iterator prefix decrement operator /// /// @return ConstIterator& /// self_type &operator--() noexcept { return *this -= 1; } //============================================================================ // Method Description: /// Iterator postfix decrement operator /// /// @return ConstIterator /// self_type operator--(int) noexcept { self_type tmp = *this; --*this; return tmp; } //============================================================================ // Method Description: /// Iterator addition assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator+=(const difference_type offset) noexcept { currPtr_ = colIdx2Ptr(ptr2ColIdx(currPtr_) + offset); return *this; } //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @return ConstIterator /// self_type operator+(const difference_type offset) const noexcept { self_type tmp = *this; return tmp += offset; } //============================================================================ // Method Description: /// Iterator subtraction assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator-=(const difference_type offset) noexcept { return *this += -offset; } //============================================================================ // Method Description: /// Iterator subtraction operator /// /// @param offset /// @return ConstIterator /// self_type operator-(const difference_type offset) const noexcept { self_type tmp = *this; return tmp -= offset; } //============================================================================ // Method Description: /// Iterator difference operator /// /// @param rhs /// @return difference_type /// difference_type operator-(const self_type &rhs) const noexcept { return ptr2ColIdx(currPtr_) - ptr2ColIdx(rhs.currPtr_); } //============================================================================ // Method Description: /// Iterator access operator /// /// @param offset /// @return reference /// reference operator[](const difference_type offset) const noexcept { return *(*this + offset); } //============================================================================ // Method Description: /// Iterator equality operator /// /// @param rhs /// @return bool /// bool operator==(const self_type &rhs) const noexcept { return currPtr_ == rhs.currPtr_; } //============================================================================ // Method Description: /// Iterator not-equality operator /// /// @param rhs /// @return bool /// bool operator!=(const self_type &rhs) const noexcept { return !(*this == rhs); } //============================================================================ // Method Description: /// Iterator less than operator /// /// @param rhs /// @return bool /// bool operator<(const self_type &rhs) const noexcept { return *this - rhs < 0; } //============================================================================ // Method Description: /// Iterator greater than operator /// /// @param rhs /// @return bool /// bool operator>(const self_type &rhs) const noexcept { return *this - rhs > 0; } //============================================================================ // Method Description: /// Iterator less than equal operator /// /// @param rhs /// @return bool /// bool operator<=(const self_type &rhs) const noexcept { return !(rhs < *this); } //============================================================================ // Method Description: /// Iterator greater than equal operator /// /// @param rhs /// @return bool /// bool operator>=(const self_type &rhs) const noexcept { return !(*this < rhs); } private: pointer ptr_{}; pointer currPtr_{}; difference_type numRows_{0}; difference_type numCols_{0}; difference_type size_{0}; //============================================================================ // Method Description: /// Converts a pointer to column order index /// /// @param ptr /// @return difference_type /// difference_type ptr2ColIdx(pointer ptr) const noexcept { if (ptr == nullptr) { return size_; } const auto rowIdx = ptr - ptr_; if (rowIdx >= size_) { return size_; } const auto row = rowIdx / numCols_; const auto col = rowIdx % numCols_; return row + col * numRows_; } //============================================================================ // Method Description: /// Converts column order index to a pointer /// /// @param colIdx /// @return pointer /// pointer colIdx2Ptr(difference_type colIdx) const noexcept { if (colIdx >= size_) { return nullptr; } const auto row = colIdx % numRows_; const auto col = colIdx / numRows_; const auto rowIdx = col + row * numCols_; return ptr_ + rowIdx; } }; //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @param next /// @return bool /// template AIS_EXPORT ConstColumnIterator operator+( typename ConstColumnIterator::difference_type offset, ConstColumnIterator next) noexcept { return next += offset; } //================================================================================ // Class Description: /// Custom column iterator for template class AIS_EXPORT ColumnIterator : public ConstColumnIterator { private: using MyBase = ConstColumnIterator; using self_type = ColumnIterator; public: using iterator_category = std::random_access_iterator_tag; using value_type = dtype; using size_type = SizeType; using pointer = PointerType; using reference = value_type &; using difference_type = DifferenceType; using MyBase::MyBase; //============================================================================ // Method Description: /// Iterator dereference /// /// @return reference /// reference operator*() const noexcept { return const_cast(MyBase::operator*()); } //============================================================================ // Method Description: /// Iterator pointer operator /// /// @return pointer /// pointer operator->() const noexcept { return const_cast(MyBase::operator->()); } //============================================================================ // Method Description: /// Iterator prefix increment operator /// /// @return ConstIterator& /// self_type &operator++() noexcept { MyBase::operator++(); return *this; } //============================================================================ // Method Description: /// Iterator postfix increment operator /// /// @return ConstIterator /// self_type operator++(int) noexcept { self_type tmp = *this; MyBase::operator++(); return tmp; } //============================================================================ // Method Description: /// Iterator prefix decrement operator /// /// @return ConstIterator& /// self_type &operator--() noexcept { MyBase::operator--(); return *this; } //============================================================================ // Method Description: /// Iterator postfix decrement operator /// /// @return ConstIterator /// self_type operator--(int) noexcept { self_type tmp = *this; MyBase::operator--(); return tmp; } //============================================================================ // Method Description: /// Iterator addition assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator+=(const difference_type offset) noexcept { MyBase::operator+=(offset); return *this; } //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @return ConstIterator /// self_type operator+(const difference_type offset) const noexcept { self_type tmp = *this; return tmp += offset; } //============================================================================ // Method Description: /// Iterator subtraction assignment operator /// /// @param offset /// @return ConstIterator& /// self_type &operator-=(const difference_type offset) noexcept { MyBase::operator-=(offset); return *this; } using MyBase::operator-; //============================================================================ // Method Description: /// Iterator difference operator /// /// @param offset /// @return ConstIterator /// self_type operator-(const difference_type offset) const noexcept { self_type tmp = *this; return tmp -= offset; } //============================================================================ // Method Description: /// Iterator access operator /// /// @param offset /// @return reference /// reference operator[](const difference_type offset) const noexcept { return const_cast(MyBase::operator[](offset)); } }; //============================================================================ // Method Description: /// Iterator addition operator /// /// @param offset /// @param next /// @return bool /// template AIS_EXPORT ColumnIterator operator+(typename ColumnIterator::difference_type offset, ColumnIterator next) noexcept { return next += offset; } } // namespace ais