You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

965 lines
30 KiB
C++

/*------------------------------------------------------------------------------
* Copyright (c) 2023 by Bai Bing (seread@163.com)
* See COPYING file for copying and redistribution conditions.
*
* Alians IT Studio.
*----------------------------------------------------------------------------*/
#pragma once
#include <stdexcept>
#include <iterator>
#include "_Define.h"
namespace ais
{
//================================================================================
// Class Description:
/// Custom const_iterator for
template <typename dtype, typename PointerType, typename DifferenceType>
class AIS_EXPORT ConstIterator
{
private:
using self_type = ConstIterator<dtype, PointerType, DifferenceType>;
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 <class dtype, typename PointerType, typename DifferenceType>
AIS_EXPORT ConstIterator<dtype, PointerType, DifferenceType>
operator+(typename ConstIterator<dtype, PointerType, DifferenceType>::difference_type offset,
ConstIterator<dtype, PointerType, DifferenceType> next) noexcept
{
return next += offset;
}
//================================================================================
// Class Description:
/// Custom iterator for
template <typename dtype, typename PointerType, typename DifferenceType>
class AIS_EXPORT Iterator : public ConstIterator<dtype, PointerType, DifferenceType>
{
private:
using MyBase = ConstIterator<dtype, PointerType, DifferenceType>;
using self_type = Iterator<dtype, PointerType, DifferenceType>;
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<reference>(MyBase::operator*());
}
//============================================================================
// Method Description:
/// Iterator pointer operator
///
/// @return pointer
///
pointer operator->() const noexcept
{
return const_cast<pointer>(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<reference>(MyBase::operator[](offset));
}
};
//============================================================================
// Method Description:
/// Iterator addition operator
///
/// @param offset
/// @param next
/// @return Iterator
///
template <class dtype, typename PointerType, typename DifferenceType>
AIS_EXPORT Iterator<dtype, PointerType, DifferenceType>
operator+(typename Iterator<dtype, PointerType, DifferenceType>::difference_type offset,
Iterator<dtype, PointerType, DifferenceType> next) noexcept
{
return next += offset;
}
//================================================================================
// Class Description:
/// Custom column const_iterator for
template <typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
class AIS_EXPORT ConstColumnIterator
{
private:
using self_type = ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>;
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<difference_type>(numRows)),
numCols_(static_cast<difference_type>(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 <class dtype, typename SizeType, typename PointerType, typename DifferenceType>
AIS_EXPORT ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType> operator+(
typename ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>::difference_type offset,
ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType> next) noexcept
{
return next += offset;
}
//================================================================================
// Class Description:
/// Custom column iterator for
template <typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
class AIS_EXPORT ColumnIterator : public ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>
{
private:
using MyBase = ConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>;
using self_type = ColumnIterator<dtype, SizeType, PointerType, DifferenceType>;
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<reference>(MyBase::operator*());
}
//============================================================================
// Method Description:
/// Iterator pointer operator
///
/// @return pointer
///
pointer operator->() const noexcept
{
return const_cast<pointer>(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<reference>(MyBase::operator[](offset));
}
};
//============================================================================
// Method Description:
/// Iterator addition operator
///
/// @param offset
/// @param next
/// @return bool
///
template <class dtype, typename SizeType, typename PointerType, typename DifferenceType>
AIS_EXPORT ColumnIterator<dtype, SizeType, PointerType, DifferenceType>
operator+(typename ColumnIterator<dtype, SizeType, PointerType, DifferenceType>::difference_type offset,
ColumnIterator<dtype, SizeType, PointerType, DifferenceType> next) noexcept
{
return next += offset;
}
} // namespace ais