Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarList.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarList.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarList.hpp')
-rw-r--r--source/core/StarList.hpp1138
1 files changed, 1138 insertions, 0 deletions
diff --git a/source/core/StarList.hpp b/source/core/StarList.hpp
new file mode 100644
index 0000000..bfedf54
--- /dev/null
+++ b/source/core/StarList.hpp
@@ -0,0 +1,1138 @@
+#ifndef STAR_LIST_HPP
+#define STAR_LIST_HPP
+
+#include <vector>
+#include <deque>
+#include <list>
+
+#include "StarException.hpp"
+#include "StarStaticVector.hpp"
+#include "StarSmallVector.hpp"
+#include "StarPythonic.hpp"
+#include "StarMaybe.hpp"
+#include "StarFormat.hpp"
+
+namespace Star {
+
+template <typename BaseList>
+class ListMixin : public BaseList {
+public:
+ typedef BaseList Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ ListMixin();
+ ListMixin(Base const& list);
+ ListMixin(Base&& list);
+ ListMixin(value_type const* p, size_t count);
+ template <typename InputIterator>
+ ListMixin(InputIterator beg, InputIterator end);
+ explicit ListMixin(size_t len, const_reference s1 = value_type());
+ ListMixin(initializer_list<value_type> list);
+
+ void append(value_type e);
+
+ template <typename Container>
+ void appendAll(Container&& list);
+
+ template <class... Args>
+ reference emplaceAppend(Args&&... args);
+
+ reference first();
+ const_reference first() const;
+
+ reference last();
+ const_reference last() const;
+
+ Maybe<value_type> maybeFirst();
+ Maybe<value_type> maybeLast();
+
+ void removeLast();
+ value_type takeLast();
+
+ Maybe<value_type> maybeTakeLast();
+
+ // Limit the size of the list by removing elements from the back until the
+ // size is the maximumSize or less.
+ void limitSizeBack(size_t maximumSize);
+
+ size_t count() const;
+
+ bool contains(const_reference e) const;
+ // Remove all equal to element, returns number removed.
+ size_t remove(const_reference e);
+
+ template <typename Filter>
+ void filter(Filter&& filter);
+
+ template <typename Comparator>
+ void insertSorted(value_type e, Comparator&& comparator);
+ void insertSorted(value_type e);
+
+ // Returns true if this *sorted* list contains the given element.
+ template <typename Comparator>
+ bool containsSorted(value_type const& e, Comparator&& comparator);
+ bool containsSorted(value_type e);
+
+ template <typename Function>
+ void exec(Function&& function);
+
+ template <typename Function>
+ void exec(Function&& function) const;
+
+ template <typename Function>
+ void transform(Function&& function);
+
+ template <typename Function>
+ bool any(Function&& function) const;
+ bool any() const;
+
+ template <typename Function>
+ bool all(Function&& function) const;
+ bool all() const;
+};
+
+template <typename List>
+class ListHasher {
+public:
+ size_t operator()(List const& l) const;
+
+private:
+ hash<typename List::value_type> elemHasher;
+};
+
+template <typename BaseList>
+class RandomAccessListMixin : public BaseList {
+public:
+ typedef BaseList Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ using Base::Base;
+
+ template <typename Comparator>
+ void sort(Comparator&& comparator);
+ void sort();
+
+ void reverse();
+
+ // Returns first index of given element, NPos if not found.
+ size_t indexOf(const_reference e, size_t from = 0) const;
+ // Returns last index of given element, NPos if not found.
+ size_t lastIndexOf(const_reference e, size_t til = NPos) const;
+
+ const_reference at(size_t n) const;
+ reference at(size_t n);
+
+ const_reference operator[](size_t n) const;
+ reference operator[](size_t n);
+
+ // Does not throw if n is beyond end of list, instead returns def
+ value_type get(size_t n, value_type def = value_type()) const;
+
+ value_type takeAt(size_t i);
+
+ // Same as at, but wraps around back to the beginning
+ // (throws if list is empty)
+ const_reference wrap(size_t n) const;
+ reference wrap(size_t n);
+
+ // Does not throw if list is empty
+ value_type wrap(size_t n, value_type def) const;
+
+ void eraseAt(size_t index);
+ // Erases region from begin to end, not including end.
+ void eraseAt(size_t begin, size_t end);
+
+ void insertAt(size_t pos, value_type e);
+
+ template <typename Container>
+ void insertAllAt(size_t pos, Container const& l);
+
+ // Ensures that list is large enough to hold pos elements.
+ void set(size_t pos, value_type e);
+
+ void swap(size_t i, size_t j);
+ // same as insert(to, takeAt(from))
+ void move(size_t from, size_t to);
+};
+
+template <typename BaseList>
+class FrontModifyingListMixin : public BaseList {
+public:
+ typedef BaseList Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ using Base::Base;
+
+ void prepend(value_type e);
+
+ template <typename Container>
+ void prependAll(Container&& list);
+
+ template <class... Args>
+ reference emplacePrepend(Args&&... args);
+
+ void removeFirst();
+ value_type takeFirst();
+
+ // Limit the size of the list by removing elements from the front until the
+ // size is the maximumSize or less.
+ void limitSizeFront(size_t maximumSize);
+};
+
+template <typename Element, typename Allocator = std::allocator<Element>>
+class List : public RandomAccessListMixin<ListMixin<std::vector<Element, Allocator>>> {
+public:
+ typedef RandomAccessListMixin<ListMixin<std::vector<Element, Allocator>>> Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ template <typename Container>
+ static List from(Container const& c);
+
+ using Base::Base;
+
+ // Pointer to contiguous storage, returns nullptr if empty
+ value_type* ptr();
+ value_type const* ptr() const;
+
+ List slice(SliceIndex a = SliceIndex(), SliceIndex b = SliceIndex(), int i = 1) const;
+
+ template <typename Filter>
+ List filtered(Filter&& filter) const;
+
+ template <typename Comparator>
+ List sorted(Comparator&& comparator) const;
+ List sorted() const;
+
+ template <typename Function>
+ auto transformed(Function&& function);
+
+ template <typename Function>
+ auto transformed(Function&& function) const;
+};
+
+template <typename Element, typename Allocator>
+struct hash<List<Element, Allocator>> : public ListHasher<List<Element, Allocator>> {};
+
+template <typename Element, size_t MaxSize>
+class StaticList : public RandomAccessListMixin<ListMixin<StaticVector<Element, MaxSize>>> {
+public:
+ typedef RandomAccessListMixin<ListMixin<StaticVector<Element, MaxSize>>> Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ template <typename Container>
+ static StaticList from(Container const& c);
+
+ using Base::Base;
+
+ StaticList slice(SliceIndex a = SliceIndex(), SliceIndex b = SliceIndex(), int i = 1) const;
+
+ template <typename Filter>
+ StaticList filtered(Filter&& filter) const;
+
+ template <typename Comparator>
+ StaticList sorted(Comparator&& comparator) const;
+ StaticList sorted() const;
+
+ template <typename Function>
+ auto transformed(Function&& function);
+
+ template <typename Function>
+ auto transformed(Function&& function) const;
+};
+
+template <typename Element, size_t MaxStackSize>
+struct hash<StaticList<Element, MaxStackSize>> : public ListHasher<StaticList<Element, MaxStackSize>> {};
+
+template <typename Element, size_t MaxStackSize>
+class SmallList : public RandomAccessListMixin<ListMixin<SmallVector<Element, MaxStackSize>>> {
+public:
+ typedef RandomAccessListMixin<ListMixin<SmallVector<Element, MaxStackSize>>> Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ template <typename Container>
+ static SmallList from(Container const& c);
+
+ using Base::Base;
+
+ SmallList slice(SliceIndex a = SliceIndex(), SliceIndex b = SliceIndex(), int i = 1) const;
+
+ template <typename Filter>
+ SmallList filtered(Filter&& filter) const;
+
+ template <typename Comparator>
+ SmallList sorted(Comparator&& comparator) const;
+ SmallList sorted() const;
+
+ template <typename Function>
+ auto transformed(Function&& function);
+
+ template <typename Function>
+ auto transformed(Function&& function) const;
+};
+
+template <typename Element, size_t MaxStackSize>
+struct hash<SmallList<Element, MaxStackSize>> : public ListHasher<SmallList<Element, MaxStackSize>> {};
+
+template <typename Element, typename Allocator = std::allocator<Element>>
+class Deque : public FrontModifyingListMixin<RandomAccessListMixin<ListMixin<std::deque<Element, Allocator>>>> {
+public:
+ typedef FrontModifyingListMixin<RandomAccessListMixin<ListMixin<std::deque<Element, Allocator>>>> Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ template <typename Container>
+ static Deque from(Container const& c);
+
+ using Base::Base;
+
+ Deque slice(SliceIndex a = SliceIndex(), SliceIndex b = SliceIndex(), int i = 1) const;
+
+ template <typename Filter>
+ Deque filtered(Filter&& filter) const;
+
+ template <typename Comparator>
+ Deque sorted(Comparator&& comparator) const;
+ Deque sorted() const;
+
+ template <typename Function>
+ auto transformed(Function&& function);
+
+ template <typename Function>
+ auto transformed(Function&& function) const;
+};
+
+template <typename Element, typename Allocator>
+struct hash<Deque<Element, Allocator>> : public ListHasher<Deque<Element, Allocator>> {};
+
+template <typename Element, typename Allocator = std::allocator<Element>>
+class LinkedList : public FrontModifyingListMixin<ListMixin<std::list<Element, Allocator>>> {
+public:
+ typedef FrontModifyingListMixin<ListMixin<std::list<Element, Allocator>>> Base;
+
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::value_type value_type;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+
+ template <typename Container>
+ static LinkedList from(Container const& c);
+
+ using Base::Base;
+
+ void appendAll(LinkedList list);
+ void prependAll(LinkedList list);
+
+ template <typename Container>
+ void appendAll(Container&& list);
+ template <typename Container>
+ void prependAll(Container&& list);
+
+ template <typename Filter>
+ LinkedList filtered(Filter&& filter) const;
+
+ template <typename Comparator>
+ LinkedList sorted(Comparator&& comparator) const;
+ LinkedList sorted() const;
+
+ template <typename Function>
+ auto transformed(Function&& function);
+
+ template <typename Function>
+ auto transformed(Function&& function) const;
+};
+
+template <typename Element, typename Allocator>
+struct hash<LinkedList<Element, Allocator>> : public ListHasher<LinkedList<Element, Allocator>> {};
+
+template <typename BaseList>
+std::ostream& operator<<(std::ostream& os, ListMixin<BaseList> const& list);
+
+template <typename... Containers>
+struct ListZipTypes {
+ typedef tuple<typename std::decay<Containers>::type::value_type...> Tuple;
+ typedef List<Tuple> Result;
+};
+
+template <typename... Containers>
+typename ListZipTypes<Containers...>::Result zip(Containers&&... args);
+
+template <typename Container>
+struct ListEnumerateTypes {
+ typedef pair<typename std::decay<Container>::type::value_type, size_t> Pair;
+ typedef List<Pair> Result;
+};
+
+template <typename Container>
+typename ListEnumerateTypes<Container>::Result enumerate(Container&& container);
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin()
+ : Base() {}
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin(Base const& list)
+ : Base(list) {}
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin(Base&& list)
+ : Base(std::move(list)) {}
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin(size_t len, const_reference s1)
+ : Base(len, s1) {}
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin(value_type const* p, size_t count)
+ : Base(p, p + count) {}
+
+template <typename BaseList>
+template <typename InputIterator>
+ListMixin<BaseList>::ListMixin(InputIterator beg, InputIterator end)
+ : Base(beg, end) {}
+
+template <typename BaseList>
+ListMixin<BaseList>::ListMixin(initializer_list<value_type> list) {
+ // In case underlying class type doesn't support initializer_list
+ for (auto& e : list)
+ append(std::move(e));
+}
+
+template <typename BaseList>
+void ListMixin<BaseList>::append(value_type e) {
+ Base::push_back(std::move(e));
+}
+
+template <typename BaseList>
+template <typename Container>
+void ListMixin<BaseList>::appendAll(Container&& list) {
+ for (auto& e : list) {
+ if (std::is_rvalue_reference<Container&&>::value)
+ Base::push_back(std::move(e));
+ else
+ Base::push_back(e);
+ }
+}
+
+template <typename BaseList>
+template <class... Args>
+auto ListMixin<BaseList>::emplaceAppend(Args&&... args) -> reference {
+ Base::emplace_back(forward<Args>(args)...);
+ return *prev(Base::end());
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::first() -> reference {
+ if (Base::empty())
+ throw OutOfRangeException("first() called on empty list");
+ return *Base::begin();
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::first() const -> const_reference {
+ if (Base::empty())
+ throw OutOfRangeException("first() called on empty list");
+ return *Base::begin();
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::last() -> reference {
+ if (Base::empty())
+ throw OutOfRangeException("last() called on empty list");
+ return *prev(Base::end());
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::last() const -> const_reference {
+ if (Base::empty())
+ throw OutOfRangeException("last() called on empty list");
+ return *prev(Base::end());
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::maybeFirst() -> Maybe<value_type> {
+ if (Base::empty())
+ return {};
+ return *Base::begin();
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::maybeLast() -> Maybe<value_type> {
+ if (Base::empty())
+ return {};
+ return *prev(Base::end());
+}
+
+template <typename BaseList>
+void ListMixin<BaseList>::removeLast() {
+ if (Base::empty())
+ throw OutOfRangeException("removeLast() called on empty list");
+ Base::pop_back();
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::takeLast() -> value_type {
+ value_type e = std::move(last());
+ Base::pop_back();
+ return e;
+}
+
+template <typename BaseList>
+auto ListMixin<BaseList>::maybeTakeLast() -> Maybe<value_type> {
+ if (Base::empty())
+ return {};
+ value_type e = std::move(last());
+ Base::pop_back();
+ return e;
+}
+
+template <typename BaseList>
+void ListMixin<BaseList>::limitSizeBack(size_t maximumSize) {
+ while (Base::size() > maximumSize)
+ Base::pop_back();
+}
+
+template <typename BaseList>
+size_t ListMixin<BaseList>::count() const {
+ return Base::size();
+}
+
+template <typename BaseList>
+bool ListMixin<BaseList>::contains(const_reference e) const {
+ for (auto const& r : *this) {
+ if (r == e)
+ return true;
+ }
+ return false;
+}
+
+template <typename BaseList>
+size_t ListMixin<BaseList>::remove(const_reference e) {
+ size_t removed = 0;
+ auto i = Base::begin();
+ while (i != Base::end()) {
+ if (*i == e) {
+ ++removed;
+ i = Base::erase(i);
+ } else {
+ ++i;
+ }
+ }
+ return removed;
+}
+
+template <typename BaseList>
+template <typename Filter>
+void ListMixin<BaseList>::filter(Filter&& filter) {
+ Star::filter(*this, forward<Filter>(filter));
+}
+
+template <typename BaseList>
+template <typename Comparator>
+void ListMixin<BaseList>::insertSorted(value_type e, Comparator&& comparator) {
+ auto i = std::upper_bound(Base::begin(), Base::end(), e, forward<Comparator>(comparator));
+ Base::insert(i, std::move(e));
+}
+
+template <typename BaseList>
+void ListMixin<BaseList>::insertSorted(value_type e) {
+ auto i = std::upper_bound(Base::begin(), Base::end(), e);
+ Base::insert(i, std::move(e));
+}
+
+template <typename BaseList>
+template <typename Comparator>
+bool ListMixin<BaseList>::containsSorted(value_type const& e, Comparator&& comparator) {
+ auto range = std::equal_range(Base::begin(), Base::end(), e, forward<Comparator>(comparator));
+ return range.first != range.second;
+}
+
+template <typename BaseList>
+bool ListMixin<BaseList>::containsSorted(value_type e) {
+ auto range = std::equal_range(Base::begin(), Base::end(), e);
+ return range.first != range.second;
+}
+
+template <typename BaseList>
+template <typename Function>
+void ListMixin<BaseList>::exec(Function&& function) {
+ for (auto& e : *this)
+ function(e);
+}
+
+template <typename BaseList>
+template <typename Function>
+void ListMixin<BaseList>::exec(Function&& function) const {
+ for (auto const& e : *this)
+ function(e);
+}
+
+template <typename BaseList>
+template <typename Function>
+void ListMixin<BaseList>::transform(Function&& function) {
+ for (auto& e : *this)
+ e = function(e);
+}
+
+template <typename BaseList>
+template <typename Function>
+bool ListMixin<BaseList>::any(Function&& function) const {
+ return Star::any(*this, forward<Function>(function));
+}
+
+template <typename BaseList>
+bool ListMixin<BaseList>::any() const {
+ return Star::any(*this);
+}
+
+template <typename BaseList>
+template <typename Function>
+bool ListMixin<BaseList>::all(Function&& function) const {
+ return Star::all(*this, forward<Function>(function));
+}
+
+template <typename BaseList>
+bool ListMixin<BaseList>::all() const {
+ return Star::all(*this);
+}
+
+template <typename BaseList>
+template <typename Comparator>
+void RandomAccessListMixin<BaseList>::sort(Comparator&& comparator) {
+ Star::sort(*this, forward<Comparator>(comparator));
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::sort() {
+ Star::sort(*this);
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::reverse() {
+ Star::reverse(*this);
+}
+
+template <typename BaseList>
+size_t RandomAccessListMixin<BaseList>::indexOf(const_reference e, size_t from) const {
+ for (size_t i = from; i < Base::size(); ++i)
+ if (operator[](i) == e)
+ return i;
+ return NPos;
+}
+
+template <typename BaseList>
+size_t RandomAccessListMixin<BaseList>::lastIndexOf(const_reference e, size_t til) const {
+ size_t index = NPos;
+ size_t end = std::min(Base::size(), til);
+ for (size_t i = 0; i < end; ++i) {
+ if (operator[](i) == e)
+ index = i;
+ }
+ return index;
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::at(size_t n) const -> const_reference {
+ if (n >= Base::size())
+ throw OutOfRangeException(strf("out of range list::at(%s)", n));
+ return operator[](n);
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::at(size_t n) -> reference {
+ if (n >= Base::size())
+ throw OutOfRangeException(strf("out of range list::at(%s)", n));
+ return operator[](n);
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::operator[](size_t n) const -> const_reference {
+ starAssert(n < Base::size());
+ return Base::operator[](n);
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::operator[](size_t n) -> reference {
+ starAssert(n < Base::size());
+ return Base::operator[](n);
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::get(size_t n, value_type def) const -> value_type {
+ if (n >= BaseList::size())
+ return def;
+ return operator[](n);
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::takeAt(size_t i) -> value_type {
+ value_type e = at(i);
+ Base::erase(Base::begin() + i);
+ return e;
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::wrap(size_t n) const -> const_reference {
+ if (BaseList::empty())
+ throw OutOfRangeException();
+ else
+ return operator[](n % BaseList::size());
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::wrap(size_t n) -> reference {
+ if (BaseList::empty())
+ throw OutOfRangeException();
+ else
+ return operator[](n % BaseList::size());
+}
+
+template <typename BaseList>
+auto RandomAccessListMixin<BaseList>::wrap(size_t n, value_type def) const -> value_type {
+ if (BaseList::empty())
+ return def;
+ else
+ return operator[](n % BaseList::size());
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::eraseAt(size_t i) {
+ starAssert(i < Base::size());
+ Base::erase(Base::begin() + i);
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::eraseAt(size_t b, size_t e) {
+ starAssert(b < Base::size() && e <= Base::size());
+ Base::erase(Base::begin() + b, Base::begin() + e);
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::insertAt(size_t pos, value_type e) {
+ starAssert(pos <= Base::size());
+ Base::insert(Base::begin() + pos, std::move(e));
+}
+
+template <typename BaseList>
+template <typename Container>
+void RandomAccessListMixin<BaseList>::insertAllAt(size_t pos, Container const& l) {
+ starAssert(pos <= Base::size());
+ Base::insert(Base::begin() + pos, l.begin(), l.end());
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::set(size_t pos, value_type e) {
+ if (pos >= Base::size())
+ Base::resize(pos + 1);
+ operator[](pos) = std::move(e);
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::swap(size_t i, size_t j) {
+ std::swap(operator[](i), operator[](j));
+}
+
+template <typename BaseList>
+void RandomAccessListMixin<BaseList>::move(size_t from, size_t to) {
+ Base::insert(to, takeAt(from));
+}
+
+template <typename BaseList>
+void FrontModifyingListMixin<BaseList>::prepend(value_type e) {
+ Base::push_front(std::move(e));
+}
+
+template <typename BaseList>
+template <typename Container>
+void FrontModifyingListMixin<BaseList>::prependAll(Container&& list) {
+ for (auto i = std::rbegin(list); i != std::rend(list); ++i) {
+ if (std::is_rvalue_reference<Container&&>::value)
+ Base::push_front(std::move(*i));
+ else
+ Base::push_front(*i);
+ }
+}
+
+template <typename BaseList>
+template <class... Args>
+auto FrontModifyingListMixin<BaseList>::emplacePrepend(Args&&... args) -> reference {
+ Base::emplace_front(forward<Args>(args)...);
+ return *Base::begin();
+}
+
+template <typename BaseList>
+void FrontModifyingListMixin<BaseList>::removeFirst() {
+ if (Base::empty())
+ throw OutOfRangeException("removeFirst() called on empty list");
+ Base::pop_front();
+}
+
+template <typename BaseList>
+auto FrontModifyingListMixin<BaseList>::takeFirst() -> value_type {
+ value_type e = std::move(Base::first());
+ Base::pop_front();
+ return e;
+}
+
+template <typename BaseList>
+void FrontModifyingListMixin<BaseList>::limitSizeFront(size_t maximumSize) {
+ while (Base::size() > maximumSize)
+ Base::pop_front();
+}
+
+template <typename Element, typename Allocator>
+template <typename Container>
+List<Element, Allocator> List<Element, Allocator>::from(Container const& c) {
+ return List(c.begin(), c.end());
+}
+
+template <typename Element, typename Allocator>
+auto List<Element, Allocator>::ptr() -> value_type * {
+ return Base::data();
+}
+
+template <typename Element, typename Allocator>
+auto List<Element, Allocator>::ptr() const -> value_type const * {
+ return Base::data();
+}
+
+template <typename Element, typename Allocator>
+auto List<Element, Allocator>::slice(SliceIndex a, SliceIndex b, int i) const -> List {
+ return Star::slice(*this, a, b, i);
+}
+
+template <typename Element, typename Allocator>
+template <typename Filter>
+auto List<Element, Allocator>::filtered(Filter&& filter) const -> List {
+ List list(*this);
+ list.filter(forward<Filter>(filter));
+ return list;
+}
+
+template <typename Element, typename Allocator>
+template <typename Comparator>
+auto List<Element, Allocator>::sorted(Comparator&& comparator) const -> List {
+ List list(*this);
+ list.sort(forward<Comparator>(comparator));
+ return list;
+}
+
+template <typename Element, typename Allocator>
+List<Element, Allocator> List<Element, Allocator>::sorted() const {
+ List list(*this);
+ list.sort();
+ return list;
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto List<Element, Allocator>::transformed(Function&& function) {
+ List<typename std::decay<decltype(std::declval<Function>()(std::declval<reference>()))>::type> res;
+ res.reserve(Base::size());
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto List<Element, Allocator>::transformed(Function&& function) const {
+ List<typename std::decay<decltype(std::declval<Function>()(std::declval<const_reference>()))>::type> res;
+ res.reserve(Base::size());
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, size_t MaxSize>
+template <typename Container>
+StaticList<Element, MaxSize> StaticList<Element, MaxSize>::from(Container const& c) {
+ return StaticList(c.begin(), c.end());
+}
+
+template <typename Element, size_t MaxSize>
+auto StaticList<Element, MaxSize>::slice(SliceIndex a, SliceIndex b, int i) const -> StaticList {
+ return Star::slice(*this, a, b, i);
+}
+
+template <typename Element, size_t MaxSize>
+template <typename Filter>
+auto StaticList<Element, MaxSize>::filtered(Filter&& filter) const -> StaticList {
+ StaticList list(*this);
+ list.filter(forward<Filter>(filter));
+ return list;
+}
+
+template <typename Element, size_t MaxSize>
+template <typename Comparator>
+auto StaticList<Element, MaxSize>::sorted(Comparator&& comparator) const -> StaticList {
+ StaticList list(*this);
+ list.sort(forward<Comparator>(comparator));
+ return list;
+}
+
+template <typename Element, size_t MaxSize>
+StaticList<Element, MaxSize> StaticList<Element, MaxSize>::sorted() const {
+ StaticList list(*this);
+ list.sort();
+ return list;
+}
+
+template <typename Element, size_t MaxSize>
+template <typename Function>
+auto StaticList<Element, MaxSize>::transformed(Function&& function) {
+ StaticList<typename std::decay<decltype(std::declval<Function>()(std::declval<reference>()))>::type, MaxSize> res;
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, size_t MaxSize>
+template <typename Function>
+auto StaticList<Element, MaxSize>::transformed(Function&& function) const {
+ StaticList<typename std::decay<decltype(std::declval<Function>()(std::declval<const_reference>()))>::type, MaxSize> res;
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, size_t MaxStackSize>
+template <typename Container>
+SmallList<Element, MaxStackSize> SmallList<Element, MaxStackSize>::from(Container const& c) {
+ return SmallList(c.begin(), c.end());
+}
+
+template <typename Element, size_t MaxStackSize>
+auto SmallList<Element, MaxStackSize>::slice(SliceIndex a, SliceIndex b, int i) const -> SmallList {
+ return Star::slice(*this, a, b, i);
+}
+
+template <typename Element, size_t MaxStackSize>
+template <typename Filter>
+auto SmallList<Element, MaxStackSize>::filtered(Filter&& filter) const -> SmallList {
+ SmallList list(*this);
+ list.filter(forward<Filter>(filter));
+ return list;
+}
+
+template <typename Element, size_t MaxStackSize>
+template <typename Comparator>
+auto SmallList<Element, MaxStackSize>::sorted(Comparator&& comparator) const -> SmallList {
+ SmallList list(*this);
+ list.sort(forward<Comparator>(comparator));
+ return list;
+}
+
+template <typename Element, size_t MaxStackSize>
+SmallList<Element, MaxStackSize> SmallList<Element, MaxStackSize>::sorted() const {
+ SmallList list(*this);
+ list.sort();
+ return list;
+}
+
+template <typename Element, size_t MaxStackSize>
+template <typename Function>
+auto SmallList<Element, MaxStackSize>::transformed(Function&& function) {
+ SmallList<typename std::decay<decltype(std::declval<Function>()(std::declval<reference>()))>::type, MaxStackSize> res;
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, size_t MaxStackSize>
+template <typename Function>
+auto SmallList<Element, MaxStackSize>::transformed(Function&& function) const {
+ SmallList<typename std::decay<decltype(std::declval<Function>()(std::declval<const_reference>()))>::type, MaxStackSize> res;
+ transformInto(res, *this, forward<Function>(function));
+ return res;
+}
+
+template <typename Element, typename Allocator>
+template <typename Container>
+Deque<Element, Allocator> Deque<Element, Allocator>::from(Container const& c) {
+ return Deque(c.begin(), c.end());
+}
+
+template <typename Element, typename Allocator>
+Deque<Element, Allocator> Deque<Element, Allocator>::slice(SliceIndex a, SliceIndex b, int i) const {
+ return Star::slice(*this, a, b, i);
+}
+
+template <typename Element, typename Allocator>
+template <typename Filter>
+Deque<Element, Allocator> Deque<Element, Allocator>::filtered(Filter&& filter) const {
+ Deque l(*this);
+ l.filter(forward<Filter>(filter));
+ return l;
+}
+
+template <typename Element, typename Allocator>
+template <typename Comparator>
+Deque<Element, Allocator> Deque<Element, Allocator>::sorted(Comparator&& comparator) const {
+ Deque l(*this);
+ l.sort(forward<Comparator>(comparator));
+ return l;
+}
+
+template <typename Element, typename Allocator>
+Deque<Element, Allocator> Deque<Element, Allocator>::sorted() const {
+ Deque l(*this);
+ l.sort();
+ return l;
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto Deque<Element, Allocator>::transformed(Function&& function) {
+ return Star::transform<Deque<decltype(std::declval<Function>()(std::declval<reference>()))>>(*this, forward<Function>(function));
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto Deque<Element, Allocator>::transformed(Function&& function) const {
+ return Star::transform<Deque<decltype(std::declval<Function>()(std::declval<const_reference>()))>>(*this, forward<Function>(function));
+}
+
+template <typename Element, typename Allocator>
+template <typename Container>
+LinkedList<Element, Allocator> LinkedList<Element, Allocator>::from(Container const& c) {
+ return LinkedList(c.begin(), c.end());
+}
+
+template <typename Element, typename Allocator>
+void LinkedList<Element, Allocator>::appendAll(LinkedList list) {
+ Base::splice(Base::end(), list);
+}
+
+template <typename Element, typename Allocator>
+void LinkedList<Element, Allocator>::prependAll(LinkedList list) {
+ Base::splice(Base::begin(), list);
+}
+
+template <typename Element, typename Allocator>
+template <typename Container>
+void LinkedList<Element, Allocator>::appendAll(Container&& list) {
+ for (auto& e : list) {
+ if (std::is_rvalue_reference<Container&&>::value)
+ Base::push_back(std::move(e));
+ else
+ Base::push_back(e);
+ }
+}
+
+template <typename Element, typename Allocator>
+template <typename Container>
+void LinkedList<Element, Allocator>::prependAll(Container&& list) {
+ for (auto i = std::rbegin(list); i != std::rend(list); ++i) {
+ if (std::is_rvalue_reference<Container&&>::value)
+ Base::push_front(std::move(*i));
+ else
+ Base::push_front(*i);
+ }
+}
+
+template <typename Element, typename Allocator>
+template <typename Filter>
+LinkedList<Element, Allocator> LinkedList<Element, Allocator>::filtered(Filter&& filter) const {
+ LinkedList list(*this);
+ list.filter(forward<Filter>(filter));
+ return list;
+}
+
+template <typename Element, typename Allocator>
+template <typename Comparator>
+LinkedList<Element, Allocator> LinkedList<Element, Allocator>::sorted(Comparator&& comparator) const {
+ LinkedList l(*this);
+ l.sort(forward<Comparator>(comparator));
+ return l;
+}
+
+template <typename Element, typename Allocator>
+LinkedList<Element, Allocator> LinkedList<Element, Allocator>::sorted() const {
+ LinkedList l(*this);
+ l.sort();
+ return l;
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto LinkedList<Element, Allocator>::transformed(Function&& function) {
+ return Star::transform<LinkedList<decltype(std::declval<Function>()(std::declval<reference>()))>>(*this, forward<Function>(function));
+}
+
+template <typename Element, typename Allocator>
+template <typename Function>
+auto LinkedList<Element, Allocator>::transformed(Function&& function) const {
+ return Star::transform<LinkedList<decltype(std::declval<Function>()(std::declval<const_reference>()))>>(*this, forward<Function>(function));
+}
+
+template <typename BaseList>
+std::ostream& operator<<(std::ostream& os, ListMixin<BaseList> const& list) {
+ os << "(";
+ for (auto i = list.begin(); i != list.end(); ++i) {
+ if (i != list.begin())
+ os << ", ";
+ os << *i;
+ }
+ os << ")";
+ return os;
+}
+
+template <typename List>
+size_t ListHasher<List>::operator()(List const& l) const {
+ size_t h = 0;
+ for (auto const& e : l)
+ hashCombine(h, elemHasher(e));
+ return h;
+}
+
+template <typename... Containers>
+typename ListZipTypes<Containers...>::Result zip(Containers&&... args) {
+ typename ListZipTypes<Containers...>::Result res;
+ for (auto el : zipIterator(args...))
+ res.push_back(std::move(el));
+
+ return res;
+}
+
+template <typename Container>
+typename ListEnumerateTypes<Container>::Result enumerate(Container&& container) {
+ typename ListEnumerateTypes<Container>::Result res;
+ for (auto el : enumerateIterator(container))
+ res.push_back(std::move(el));
+
+ return res;
+}
+
+}
+
+#endif