#pragma once #include "dtcore/inc/dtcontainer.h" #include "dtcore/inc/dterror.h" #include "dtcore/inc/dtmath.h" #include "dtcore/inc/dtconstant.h" #pragma warning(push) #include #pragma warning(pop) namespace dt { template> class Queue : private std::deque { public: typedef typename std::deque MyBase; typedef typename MyBase::iterator Iterator; typedef typename MyBase::const_iterator ConstIterator; typedef typename MyBase::reverse_iterator ReverseIterator; typedef typename MyBase::const_reverse_iterator ConstReverseIterator; Queue() = default; Queue(const Queue& rhs) : MyBase::deque(rhs) {} Queue(Queue&& rhs) : MyBase::deque(rhs) {} Queue(const std::initializer_list& rhs) : MyBase::deque(rhs) {} Queue& operator=(const Queue& rhs) { MyBase::operator =(rhs); return *this; } void Merge(const Queue& rhs, SizeT startIndex = 0, SizeT stopIndex = Constant::MAX); void Swap(Queue& rhs) { MyBase::swap(rhs); } void PushFront(const VALUE& rhs) { MyBase::push_front(rhs); } void PushBack(const VALUE& rhs) { MyBase::push_back(rhs); } void Insert(ConstIterator pos, const VALUE& rhs) { MyBase::insert(pos, rhs); } Iterator Erase(ConstIterator pos) { return pos != MyBase::end() ? MyBase::erase(pos) : MyBase::end(); } void Clear() { MyBase::clear(); } VALUE& operator[](SizeT index) { DT_ASSERT_WITH_REASON(index < Size(), "OutOfBound"); return MyBase::operator [](index); } const VALUE& operator[](SizeT index) const { DT_ASSERT_WITH_REASON(index < Size(), "OutOfBound"); return MyBase::operator [](index); } Iterator Begin() { return MyBase::begin(); } ConstIterator Begin() const { return MyBase::begin(); } ReverseIterator RBegin() { return MyBase::rbegin(); } ConstReverseIterator RBegin() const { return MyBase::rbegin(); } Iterator begin() { return MyBase::begin(); } ConstIterator begin() const { return MyBase::begin(); } ReverseIterator rbegin() { return MyBase::rbegin(); } ConstReverseIterator rbegin() const { return MyBase::rbegin(); } Iterator End() { return MyBase::end(); } ConstIterator End() const { return MyBase::end(); } ReverseIterator REnd() { return MyBase::rend(); } ConstReverseIterator REnd() const { return MyBase::rend(); } Iterator end() { return MyBase::end(); } ConstIterator end() const { return MyBase::end(); } ReverseIterator rend() { return MyBase::rend(); } ConstReverseIterator rend() const { return MyBase::rend(); } SizeT Size() const { return static_cast(MyBase::size()); } bool Empty() const { return MyBase::empty(); } void Resize(SizeT newSize) { MyBase::resize(newSize); } void Resize(SizeT newSize, const VALUE& initialValue) { MyBase::resize(newSize, initialValue); } const VALUE& Back() const { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); return MyBase::back(); } VALUE& Back() { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); return MyBase::back(); } const VALUE& Front() const { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); return MyBase::front(); } VALUE& Front() { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); return MyBase::front(); } void PopBack() { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); MyBase::pop_back(); } void PopFront() { DT_ASSERT_WITH_REASON(!Empty(), "OutOfBound"); MyBase::pop_front(); } }; template inline void Queue::Merge(const Queue &rhs, SizeT startIndex, SizeT stopIndex) { stopIndex = Math::Clamp(stopIndex, (SizeT)0, rhs.Size()); if (startIndex >= stopIndex) { return; } startIndex = Math::Max(startIndex, (SizeT)0); MyBase::insert(MyBase::end(), rhs.begin() + startIndex, rhs.begin() + stopIndex); } }