#include <assert.h>
#include <type_traits>
namespace ximo {
template <class T> struct _List_node { _List_node<T> *_next; _List_node<T> *_prev; T _data;
_List_node(const T &x = T()) : _next(0), _prev(0), _data(x) {} };
template <class T, class Ref, class Ptr> struct _List_iterator { typedef _List_iterator<T, T &, T *> iterator; typedef _List_iterator<T, const T &, const T *> const_iterator; typedef _List_iterator<T, Ref, Ptr> Self;
typedef Ptr pointer; typedef Ref reference; typedef _List_node<T> Node;
Node *_node;
_List_iterator() {} _List_iterator(Node *x) : _node(x) {} _List_iterator(const iterator &x) : _node(x._node) {}
bool operator==(const_iterator &x) const { return _node == x._node; } bool operator!=(const_iterator &x) const { return _node != x._node; }
reference operator*() const { return _node->_data; }
pointer operator->() const { return &(operator*()); }
Self &operator++() { _node = _node->_next; return *this; } Self operator++(int) { Self tmp = *this; _node = _node->_next; return tmp; }
Self &operator--() { _node = _node->_prev; return *this; } Self operator--(int) { Self tmp = *this; _node = _node->_prev; return tmp; } };
template <class T> class list { public: typedef T value_type; typedef value_type *pointer; typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; typedef size_t size_type; typedef _List_node<T> Node;
typedef _List_iterator<T, T &, T *> iterator; typedef _List_iterator<T, const T &, const T *> const_iterator;
private: Node *_node;
public: list() { _empty_initialize(); } list(size_type n, const T &val = T()) { _empty_initialize(); insert(begin(), n, val); } template <class InputIterator> list(InputIterator first, InputIterator last) { _empty_initialize(); insert(begin(), first, last); } list(const list<T> &x) { _empty_initialize(); insert(begin(), x.begin(), x.end()); }
private: void _empty_initialize() { _node = new Node(); _node->_next = _node; _node->_prev = _node; }
public: ~list() { clear(); delete _node; _node = nullptr; }
list<T> &operator=(const list<T> &x) { if (this != &x) { iterator first1 = begin(); iterator last1 = end(); const_iterator first2 = x.begin(); const_iterator last2 = x.end(); while (first1 != last1 && first2 != last2) { *first1++ = *first2++; } if (first2 == last2) { erase(first1, last1); } else { insert(last1, first2, last2); } } return *this; }
void assign(size_type n, const T &val) { _fill_assign(n, val); } template <class InputIterator> void assign(InputIterator first, InputIterator last) { typedef typename std::is_integral<InputIterator> Integral; _assign_dispatch(first, last, Integral()); }
private: template <class Integer> void _assign_dispatch(Integer n, Integer val, std::true_type) { _fill_assign((size_type)n, (T)val); }
template <class InputIterator> void _assign_dispatch(InputIterator first2, InputIterator last2, std::false_type) { iterator first1 = begin(); iterator last1 = end(); for (; first1 != last1 && first2 != last2; ++first1, ++first2) { *first1 = *first2; } if (first2 == last2) { erase(first1, last1); } else { insert(last1, first2, last2); } }
void _fill_assign(size_type n, const T &val) { iterator i = begin(); for (; i != end() && n > 0; ++i, --n) { *i = val; } if (n > 0) { insert(end(), n, val); } else { erase(i, end()); } }
public: reference front() { return *begin(); } const_reference front() const { return *begin(); }
reference back() { return *(--end()); } const_reference back() const { return *(--end()); }
iterator begin() { return _node->_next; } const_iterator begin() const { return _node->_next; }
iterator end() { return _node; } const_iterator end() const { return _node; }
bool empty() const { return _node->_next == _node; }
size_type size() const { const_iterator first = begin(); const_iterator last = end(); size_type n = 0; while (first != last) { ++first; ++n; } return n; }
size_type max_size() const { return size_type(-1); }
void clear() { Node *cur = _node->_next; while (cur != _node) { Node *tmp = cur; cur = cur->_next; delete tmp; } _node->_next = _node; _node->_prev = _node; }
iterator insert(iterator position, const T &val = T()) { assert(position >= begin() && position <= end());
Node *tmp = new Node(val); tmp->_next = position._node; tmp->_prev = position._node->_prev; position._node->_prev->_next = tmp; position._node->_prev = tmp; return tmp; } void insert(iterator position, size_type n, const T &val) { _fill_insert(position, n, val); } template <class InputIterator> void insert(iterator position, InputIterator first, InputIterator last) { typedef typename std::is_integral<InputIterator> Integral; _insert_dispatch(position, first, last, Integral()); }
private: template <class Integer> void _insert_dispatch(iterator position, Integer n, Integer x, std::true_type) { _fill_insert(position, (size_type)n, (T)x); }
template <class InputIterator> void _insert_dispatch(iterator position, InputIterator first, InputIterator last, std::false_type) { assert(first <= last);
for (; first != last; ++first) { insert(position, *first); } }
void _fill_insert(iterator position, size_type n, const T &x) { while (n--) { insert(position, x); } }
public: iterator erase(iterator position) { assert(position >= begin() && position < end());
Node *next_node = position._node->_next; Node *prev_node = position._node->_prev; prev_node->_next = next_node; next_node->_prev = prev_node; delete position._node; return iterator(next_node); } iterator erase(iterator first, iterator last) { assert(first <= last);
while (first != last) { erase(first++); } return last; }
void push_back(const T &val = T()) { insert(end(), val); }
void pop_back() { iterator tmp = end(); erase(--tmp); } void push_front(const T &val = T()) { insert(begin(), val); }
void pop_front() { erase(begin()); }
void resize(size_type new_size, const T &x = T()) { iterator i = begin(); size_type len = 0; while (i != end() && len < new_size) { ++i; ++len; } if (len == new_size) { erase(i, end()); } else { insert(end(), new_size - len, x); } }
void swap(list<T> &x) { std::swap(_node, x._node); }
private: void transfer(iterator position, iterator first, iterator last) { assert(position >= begin() && position <= end() && first <= last);
if (position != last) { last._node->_prev->_next = position._node; first._node->_prev->_next = last._node; position._node->_prev->_next = first._node;
Node *tmp = position._node->_prev; position._node->_prev = last._node->_prev; last._node->_prev = first._node->_prev; first._node->_prev = tmp; } }
public: void merge(list &x) { iterator first1 = begin(); iterator last1 = end(); iterator first2 = x.begin(); iterator last2 = x.end(); while (first1 != last1 && first2 != last2) if (*first2 < *first1) { iterator next = first2; transfer(first1, first2, ++next); first2 = next; } else { ++first1; } if (first2 != last2) { transfer(last1, first2, last2); } } template <class StrictWeakOrdering> void merge(list<T> &x, StrictWeakOrdering comp) { iterator first1 = begin(); iterator last1 = end(); iterator first2 = x.begin(); iterator last2 = x.end(); while (first1 != last1 && first2 != last2) if (comp(*first2, *first1)) { iterator next = first2; transfer(first1, first2, ++next); first2 = next; } else { ++first1; } if (first2 != last2) { transfer(last1, first2, last2); } }
void splice(iterator position, list &x) { if (!x.empty()) { this->transfer(position, x.begin(), x.end()); } } void splice(iterator position, list &, iterator i) { iterator j = i; ++j; if (position == i || position == j) { return; } this->transfer(position, i, j); } void splice(iterator position, list &, iterator first, iterator last) { if (first != last) { this->transfer(position, first, last); } }
void remove(const T &val) { iterator first = begin(); iterator last = end(); while (first != last) { iterator next = first; ++next; if (*first == val) { erase(first); }; first = next; } } template <class Predicate> void remove_if(Predicate pred) { iterator first = begin(); iterator last = end(); while (first != last) { iterator next = first; ++next; if (pred(*first)) { erase(first); } first = next; } }
void reverse() { Node *tmp = _node; do { std::swap(tmp->_next, tmp->_prev); tmp = tmp->_prev; } while (tmp != _node); }
void unique() { iterator first = begin(); iterator last = end(); if (first == last) { return; } iterator next = first; while (++next != last) { if (*first == *next) { erase(next); } else { first = next; } next = first; } } template <class BinaryPredicate> void unique(BinaryPredicate binary_pred) { iterator first = begin(); iterator last = end(); if (first == last) { return; } iterator next = first; while (++next != last) { if (binary_pred(*first, *next)) { erase(next); } else { first = next; } next = first; } }
void sort() { if (_node->_next != _node && _node->_next->_next != _node) { list<T> carry; list<T> counter[64]; int fill = 0; while (!empty()) { carry.splice(carry.begin(), *this, begin()); int i = 0; while (i < fill && !counter[i].empty()) { counter[i].merge(carry); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) { ++fill; } }
for (int i = 1; i < fill; ++i) { counter[i].merge(counter[i - 1]); } swap(counter[fill - 1]); } } template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp) { if (_node->_next != _node && _node->_next->_next != _node) { list<T> carry; list<T> counter[64]; int fill = 0; while (!empty()) { carry.splice(carry.begin(), *this, begin()); int i = 0; while (i < fill && !counter[i].empty()) { counter[i].merge(carry, comp); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) { ++fill; } }
for (int i = 1; i < fill; ++i) { counter[i].merge(counter[i - 1], comp); } swap(counter[fill - 1]); } } };
template <class T> inline bool operator==(const list<T> &x, const list<T> &y) { typedef typename list<T>::const_iterator const_iterator; const_iterator end1 = x.end(); const_iterator end2 = y.end();
const_iterator i1 = x.begin(); const_iterator i2 = y.begin(); while (i1 != end1 && i2 != end2 && *i1 == *i2) { ++i1; ++i2; } return i1 == end1 && i2 == end2; }
template <class T> inline bool operator!=(const list<T> &x, const list<T> &y) { return !(x == y); }
template <class T> inline bool operator<(const list<T> &x, const list<T> &y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
template <class T> inline bool operator<=(const list<T> &x, const list<T> &y) { return !(y < x); }
template <class T> inline bool operator>(const list<T> &x, const list<T> &y) { return y < x; }
template <class T> inline bool operator>=(const list<T> &x, const list<T> &y) { return !(x < y); }
template <class T> inline void swap(list<T> &x, list<T> &y) { x.swap(y); } }
|