11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
15#include <initializer_list>
20PROMEKI_NAMESPACE_BEGIN
45template <
typename T>
class Deque {
46 PROMEKI_SHARED_FINAL(Deque)
49 using Ptr = SharedPtr<Deque>;
52 using Data = std::deque<T>;
58 using Iterator =
typename Data::iterator;
61 using ConstIterator =
typename Data::const_iterator;
64 using RevIterator =
typename Data::reverse_iterator;
67 using ConstRevIterator =
typename Data::const_reverse_iterator;
73 Deque(
const Deque &other) : d(other.d) {}
76 Deque(Deque &&other) noexcept : d(std::move(other.d)) {}
82 Deque(std::initializer_list<T> initList) : d(initList) {}
88 Deque &operator=(
const Deque &other) {
94 Deque &operator=(Deque &&other)
noexcept {
95 d = std::move(other.d);
102 Iterator begin() noexcept {
return d.begin(); }
105 ConstIterator begin() const noexcept {
return d.cbegin(); }
108 ConstIterator cbegin() const noexcept {
return d.cbegin(); }
111 ConstIterator constBegin() const noexcept {
return d.cbegin(); }
114 Iterator end() noexcept {
return d.end(); }
117 ConstIterator end() const noexcept {
return d.cend(); }
120 ConstIterator cend() const noexcept {
return d.cend(); }
123 ConstIterator constEnd() const noexcept {
return d.cend(); }
126 RevIterator rbegin() noexcept {
return d.rbegin(); }
129 RevIterator revBegin() noexcept {
return d.rbegin(); }
132 ConstRevIterator crbegin() const noexcept {
return d.crbegin(); }
135 ConstRevIterator constRevBegin() const noexcept {
return d.crbegin(); }
138 RevIterator rend() noexcept {
return d.rend(); }
141 RevIterator revEnd() noexcept {
return d.rend(); }
144 ConstRevIterator crend() const noexcept {
return d.crend(); }
147 ConstRevIterator constRevEnd() const noexcept {
return d.crend(); }
156 T &at(
size_t index) {
return d.at(index); }
159 const T &at(
size_t index)
const {
return d.at(index); }
166 T &operator[](
size_t index) {
return d[index]; }
169 const T &operator[](
size_t index)
const {
return d[index]; }
172 T &front() {
return d.front(); }
175 const T &front()
const {
return d.front(); }
178 T &back() {
return d.back(); }
181 const T &back()
const {
return d.back(); }
186 bool isEmpty() const noexcept {
return d.empty(); }
189 size_t size() const noexcept {
return d.size(); }
197 void pushToFront(
const T &value) {
206 void pushToFront(T &&value) {
207 d.push_front(std::move(value));
215 void pushToBack(
const T &value) {
224 void pushToBack(T &&value) {
225 d.push_back(std::move(value));
235 if (d.empty())
throw std::logic_error(
"Deque::popFromFront on empty deque");
236 T val = std::move(d.front());
247 if (d.empty())
throw std::logic_error(
"Deque::popFromBack on empty deque");
248 T val = std::move(d.back());
254 void clear() noexcept {
263 void swap(Deque &other)
noexcept {
273 template <
typename Func>
void forEach(Func &&func)
const {
274 for (
const auto &v : d) func(v);
281 friend bool operator==(
const Deque &lhs,
const Deque &rhs) {
return lhs.d == rhs.d; }
284 friend bool operator!=(
const Deque &lhs,
const Deque &rhs) {
return lhs.d != rhs.d; }