19 #ifndef UTILS_SMART_LIST_HPP_INCLUDED
20 #define UTILS_SMART_LIST_HPP_INCLUDED
82 template <
class Value,
bool Reversed>
103 template <
class V,
bool R>
120 node_t * old_ptr =
ptr_;
174 static void unref(node_t * old_ptr);
240 template <
class InputIterator>
241 smart_list(
const InputIterator &
f,
const InputIterator &
l);
247 const_iterator
end()
const {
return const_iterator(const_cast<node_t *>(&
root_)); }
249 reverse_iterator
rend() {
return reverse_iterator(&
root_); }
251 const_reverse_iterator
rend()
const {
return const_reverse_iterator(const_cast<node_t *>(&
root_)); }
253 size_type
size()
const;
272 template <
class InputIterator>
273 static void insert(
const iterator &
pos,
const InputIterator &
f,
const InputIterator &
l);
281 void resize(size_type
n,
const value_type &
d);
287 void remove(
const value_type &
value);
288 template <
class Predicate>
292 template <
class BinaryPredicate>
293 void unique(
const BinaryPredicate
p);
296 template <
class BinaryPredicate>
300 template <
class BinaryPredicate>
301 void sort(
const BinaryPredicate &
p);
308 static bool flagged(
const node_t & node) {
return node.ref_count % 2 == 0; }
310 static void flag(
const node_t & node) { node.ref_count &= ~size_t(1); }
314 static node_t *
insert(node_t *
const pos,
const value_type &
d);
316 static void link(node_t *
const pos, node_t & begin_link, node_t & end_link);
317 static void unlink(node_t & begin_unlink, node_t & end_unlink);
318 static void splice(node_t *
const pos, node_t &
f, node_t &
l);
329 template <
class Data>
336 template <
class Data>
343 template <
class Data>
351 template <
class Data>
template <
class InputIterator>
355 for ( InputIterator it = f; f !=
l; ++
f )
361 template <
class Data>
372 template <
class Data>
380 splice(
end(), temp_list);
384 template <
class Data>
391 template <
class Data>
392 template <
class InputIterator>
394 const InputIterator &
l)
396 for ( InputIterator it = f; it !=
l; ++it )
400 template <
class Data>
409 template <
class Data>
417 template <
class Data>
423 node_t * node_ptr = start.ptr_;
424 while ( node_ptr != stop.ptr_ && iterator::derefable(node_ptr) ) {
426 node_ptr = check_erase(node_ptr);
437 template <
class Data>
446 while ( it != _end && count < n ) {
453 insert(_end, n - count, d);
454 else if ( it != _end )
460 template <
class Data>
467 template <
class Data>
472 splice(pos.ptr_, *i.ptr_, *i.ptr_);
475 template <
class Data>
484 splice(pos.ptr_, *(f.ptr_), *(l.ptr_->prev));
488 template <
class Data>
500 template <
class Data>
501 template <
class Predicate>
506 while ( it != _end() )
514 template <
class Data>
515 template <
class BinaryPredicate>
527 while ( cur != _end )
528 if (
p(*prev, *cur) )
542 template <
class Data>
543 template <
class BinaryPredicate>
554 while ( iterator::derefable(dest) && iterator::derefable(source) ) {
559 while ( iterator::derefable(end_merge) &&
p(*(end_merge->
dat_ptr), *(dest->
dat_ptr)) )
560 end_merge = end_merge->
next;
563 splice(dest, *source, *(end_merge->
prev));
573 if ( iterator::derefable(source) )
574 splice(&root_, *source, *(L.
root_.
prev));
582 template <
class Data>
583 template <
class BinaryPredicate>
591 for (
node_t * node_ptr = root_.
next; iterator::derefable(node_ptr); node_ptr = node_ptr->
next )
598 std::vector<smart_list> sorter(count);
600 sorter[
i].splice(&(sorter[
i].root_), *(root_.next), *(root_.next));
608 sorter[
i].merge(sorter[
i+step], p);
619 template <
class Data>
625 link(pos, *new_node, *new_node);
635 template <
class Data>
640 if ( !iterator::derefable(pos) )
664 template <
class Data>
672 begin_link.
prev->
next = &begin_link;
683 template <
class Data>
691 end_unlink.
next =
nullptr;
692 begin_unlink.
prev =
nullptr;
699 template <
class Data>
712 template <
class Data>
720 for ( ; it_a != end_a && it_b != end_b; ++it_a, ++it_b )
721 if ( *it_a != *it_b )
726 return it_a == end_a && it_b == end_b;
731 template <
class Data>
739 for ( ; it_a != end_a && it_b != end_b; ++it_a, ++it_b )
743 else if ( *it_b < *it_a )
748 return it_b != end_b;
754 template <
class Data>
760 assert(
next ==
this);
763 assert(
next ==
nullptr &&
prev ==
nullptr);
780 template <
class Data>
781 template <
class Value,
bool Reversed>
789 skip_flagged(reverse);
797 template <
class Data>
798 template <
class Value,
bool Reversed>
807 template <
class Data>
808 template <
class Value,
bool Reversed>
812 ptr_->ref_count += 2;
819 template <
class Data>
820 template <
class Value,
bool Reversed>
823 if ( derefable(old_ptr) ) {
832 #endif // UTILS_SMART_LIST_HPP_INCLUDED
const_iterator end() const
friend class iterator_base
iterator_base & operator--()
void skip_flagged(bool reverse=Reversed)
Make sure we are not pointing to a flagged node.
const value_type & const_reference
iterator_base(const iterator_base< V, R > &that)
Conversion constructors.
reverse_iterator(const reverse_iterator &that)
Copy constructor.
static bool derefable(node_t *ptr)
Test for being in a list, rather than past-the-end (or unassigned).
iterator_base operator++(int)
bool derefable() const
Test for being in a list, rather than past-the-end (or unassigned).
bool operator!=(const iterator_base &that) const
size_type max_size() const
const_reverse_iterator(const const_reverse_iterator &that)
Copy constructor.
const_reverse_iterator rend() const
void refer() const
Add a reference.
const_iterator(const iterator_base< Data, false > &that)
Conversion from iterator.
bool empty() const
Note: if empty() returns true, the list might still contain nodes flagged for deletion.
This is a variant on a list that never invalidates iterators (unless, of course, the list ceases to e...
const_reverse_iterator rbegin() const
const_reference front() const
static bool flagged(const node_t &node)
Returns true if node has been flagged for deletion.
~iterator_base()
Destructor (Not virtual, since the derived classes are mere shells.)
iterator_base()
Default constructor.
node_t root_
Root of the list.
const_reverse_iterator(node_t *ptr)
Initialized constructor.
iterator_base & operator=(const iterator_base &that)
smart_list< Data >::node_t node_t
const_reverse_iterator(const iterator_base< const Data, false > &that)
Conversion from const_iterator.
GLdouble GLdouble GLdouble b
iterator(const iterator_base< Data, true > &that)
Conversion from reverse_iterator.
const_reference back() const
iterator_base(const iterator_base &that)
Copy constructor (the default overrides the conversion template).
const_reverse_iterator()
Default constructor.
static void flag(const node_t &node)
Flags node for deletion.
ptrdiff_t difference_type
reverse_iterator()
Default constructor.
iterator_base & operator++()
void remove_if(const Predicate &p)
Remove all nodes whose data satisfies p.
GLsizei const GLfloat * value
iterator()
Default constructor.
std::bidirectional_iterator_tag iterator_category
GLboolean GLboolean GLboolean GLboolean a
void erase(const std::string &key)
node_t(const Data &d)
Initialized constructor. This is for creating a node in a list.
const_iterator begin() const
iterator(node_t *ptr)
Initialized constructor.
iterator(const iterator &that)
Copy constructor.
GLuint GLuint GLsizei count
const_iterator(const iterator_base< const Data, true > &that)
Conversion from const_reverse_iterator.
iterator_base(node_t *ptr)
Initialized constructor.
reverse_iterator(const iterator_base< Data, false > &that)
Conversion from iterator.
static void unlink(node_t &begin_unlink, node_t &end_unlink)
Assuming begin_unlink and end_unlink are nodes from *this, with end_unlink a successor of begin_unlin...
reverse_iterator rbegin()
iterator_base operator--(int)
The base for the list's iterator classes.
const_iterator(const const_iterator &that)
Copy constructor.
node_t()
Default constructor. This is for creating the root of a list.
const_iterator()
Default constructor.
static node_t * check_erase(node_t *const pos)
Low-level erasure.
static iterator erase(const iterator &pos)
Erase the node at pos.
void push_back(const value_type &d)
void splice(const iterator &pos, smart_list &L)
Splice all of L into *this before pos.
void advance(bool reverse)
Advances our pointer to an unflagged node, possibly in the reverse direction.
void inc(bool reverse)
Advances our pointer one step, possibly in the reverse direction.
const_reverse_iterator(const iterator_base< Data, true > &that)
Conversion from reverse_iterator.
node_t & operator=(const node_t &)
No assignments.
reverse_iterator(node_t *ptr)
Initialized constructor.
bool operator==(const smart_list< Data > &a, const smart_list< Data > &b)
Equality, if lists contain equal elements in the same order.
size_t ref_count
ref_count counts 1 for the list and 2 for each iterator pointing to this node.
pointer operator->() const
void swap(game_board &one, game_board &other)
Data *const dat_ptr
The data of the node. This is nullptr for a list's root.
void merge(smart_list &L)
bool operator==(const iterator_base &that) const
utf8::string & insert(utf8::string &str, const size_t pos, const utf8::string &insert)
Insert a UTF-8 string at the specified position.
void remove(const value_type &value)
Remove all nodes whose data equals value.
const_iterator(node_t *ptr)
Initialized constructor.
size_type size() const
The size of the list, not counting flagged nodes.
void swap(smart_list &that)
Swaps two lists.
smart_list & operator=(const smart_list &)
No implementation of operator=() since that would not preserve iterators.
static void unref(node_t *old_ptr)
Remove a reference.
GLsizei GLsizei GLchar * source
reference operator*() const
static iterator insert(const iterator &pos, const value_type &d)
Insert a node before pos.
static void link(node_t *const pos, node_t &begin_link, node_t &end_link)
Assuming the nodes from begin_link to end_link are linked, they will be inserted into *this before po...
void push_front(const value_type &d)