DEV: update deque functionality

This commit is contained in:
2021-09-22 19:30:39 +03:00
parent 28bf870959
commit 0a04a480f3
7 changed files with 1621 additions and 16 deletions
+213 -1
View File
@@ -35,10 +35,11 @@
#include <iterator>
#include <type_traits>
#include <atomic>
namespace tbx {
template<typename Iter_t, size_t N>
template<typename Iter_t, size_t N, bool Atomic=false>
class ring_iterator {
//! \name STL iterator traits "forwarding"
//! @{
@@ -164,6 +165,9 @@ class ring_iterator {
return N;
}
constexpr operator Iter_t() noexcept { return iter_; }
constexpr operator const Iter_t() const noexcept { return iter_; }
protected:
Iter_t base_;
Iter_t iter_;
@@ -226,6 +230,214 @@ noexcept {
}
template<typename Iter_t, size_t N>
class ring_iterator<Iter_t, N, true> {
//! \name STL iterator traits "forwarding"
//! @{
protected:
using traits_type = std::iterator_traits<Iter_t>;
public:
using iterator_type = Iter_t;
using iterator_category = typename traits_type::iterator_category;
using value_type = typename traits_type::value_type;
using difference_type = typename traits_type::difference_type;
using reference = typename traits_type::reference;
using pointer = typename traits_type::pointer;
//! @}
//! \name Constructor / Destructor
//! @{
public:
constexpr ring_iterator(const Iter_t base =nullptr) noexcept :
base_(base), iter_(base) { }
constexpr ring_iterator(const Iter_t base, size_t elem) noexcept :
base_(base), iter_(base + elem) { }
constexpr ring_iterator(const ring_iterator& it) noexcept :
base_(it.base_) {
iter_ = it.iter_.load(std::memory_order_acquire);
}
constexpr ring_iterator& operator= (const ring_iterator& it) noexcept {
base_ = it.base_;
iter_ = it.iter_.load(std::memory_order_acquire);
return *this;
}
//! @}
//! \name Forward iterator requirements
//! @{
public:
constexpr reference operator*() const noexcept {
return *iter_.load(std::memory_order_acquire);
}
constexpr pointer operator->() const noexcept {
return iter_.load(std::memory_order_acquire);
}
constexpr ring_iterator& operator++() noexcept {
Iter_t itnew, it = iter_.load(std::memory_order_acquire);
do {
itnew = it;
if (static_cast<size_t>(++itnew - base_) >= N)
itnew = base_;
} while (!iter_.compare_exchange_weak(it, itnew, std::memory_order_acq_rel));
return *this;
}
constexpr ring_iterator operator++(int) noexcept {
ring_iterator it = *this;
this->operator ++();
return it;
}
//! @}
//! \name Bidirectional iterator requirements
//! @{
public:
constexpr ring_iterator& operator--() noexcept {
Iter_t itnew, it = iter_.load(std::memory_order_acquire);
do {
itnew = it;
if (--itnew < base_)
itnew = base_ + N -1;
} while (!iter_.compare_exchange_weak(it, itnew, std::memory_order_acq_rel));
return *this;
}
constexpr ring_iterator operator--(int) noexcept {
ring_iterator it = *this;
this->operator --();
return it;
}
//! @}
//! \name Random access iterator requirements
//! @{
constexpr reference operator[](difference_type n) const noexcept {
difference_type k = iter_.load(std::memory_order_acquire) - base_; // ptrdiff from base_
return (static_cast<size_t>(k + n) < N) ?
base_[k + n] : // on range
base_[k + n - N]; // out of range, loop
}
constexpr ring_iterator& operator+=(difference_type n) noexcept {
Iter_t itnew, it = iter_.load(std::memory_order_acquire);
do {
itnew = it;
difference_type k = it - base_; // ptrdiff from base_
itnew += (static_cast<size_t>(k + n) < N) ?
n : // on range
n - N; // out of range, loop
} while (!iter_.compare_exchange_weak(it, itnew, std::memory_order_acquire));
return *this;
}
constexpr ring_iterator operator+(difference_type n) const noexcept {
difference_type k = iter_.load(std::memory_order_acquire) - base_; // ptrdiff from base_
return (static_cast<size_t>(k + n) < N) ?
ring_iterator(base_, k + n) : // on range
ring_iterator(base_, k + n - N); // out of range, loop
}
constexpr ring_iterator& operator-=(difference_type n) noexcept {
Iter_t itnew, it = iter_.load(std::memory_order_acquire);
do {
itnew = it;
difference_type k = it - base_; // ptrdiff from base_
itnew -= ((k - n) < 0)?
n - N: // out of range, loop
n; // on range
} while (!iter_.compare_exchange_weak(it, itnew, std::memory_order_acquire));
return *this;
}
constexpr ring_iterator operator-(difference_type n) const noexcept {
difference_type k = iter_.load(std::memory_order_acquire) - base_; // ptrdiff from base_
return ((k - n) < 0) ?
ring_iterator(base_, k - n + N) : // out of range, loop
ring_iterator(base_, k - n); // on range
}
//! @}
//! \name Data members and access
//! @{
constexpr const Iter_t& base() const noexcept {
return base_;
}
constexpr const Iter_t iter() const noexcept {
return iter_.load(std::memory_order_acquire);
}
constexpr size_t size() noexcept {
return N;
}
constexpr operator Iter_t() noexcept { return iter_.load(std::memory_order_acquire); }
constexpr operator const Iter_t() const noexcept { return iter_.load(std::memory_order_acquire); }
protected:
Iter_t base_;
std::atomic<Iter_t> iter_;
//! @}
};
// Forward iterator requirements
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator==(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() == rhs.iter();
}
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator!=(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() != rhs.iter();
}
// Random access iterator requirements
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator<(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() < rhs.iter();
}
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator<=(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() <= rhs.iter();
}
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator>(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() > rhs.iter();
}
template<typename Iter_L, typename Iter_R, size_t N>
inline bool operator>=(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept {
return lhs.iter() >= rhs.iter();
}
template<typename Iter_L, typename Iter_R, size_t N>
inline auto operator-(const ring_iterator<Iter_L, N, true>& lhs, const ring_iterator<Iter_R, N, true>& rhs)
noexcept
-> decltype(lhs.iter() - rhs.iter()) {
auto diff = lhs.iter() - rhs.iter();
return diff < 0 ?
diff + N : // loop
diff; // no loop
}
template<typename Iter, size_t N>
inline ring_iterator<Iter, N, true> operator+(std::ptrdiff_t lhs, const ring_iterator<Iter, N, true>& rhs)
noexcept {
ring_iterator<Iter, N, true> it(rhs.iter());
return it += lhs;
}
} //namespace tbx;
#endif /* TBX_CORE_RING_ITERATOR_H_ */