11#include <l4/cxx/type_traits> 
   12#include <l4/cxx/std_alloc> 
   13#include <l4/cxx/std_ops> 
   37    Iter(List_item *c, List_item *f) noexcept : _c(c), _f(f) {}
 
   38    Iter(List_item *f = 0) noexcept : _c(f), _f(f) {}
 
   40    List_item *operator * () 
const noexcept { 
return _c; }
 
   41    List_item *operator -> () 
const noexcept { 
return _c; }
 
   42    Iter &operator ++ () 
noexcept 
   47        _c = _c->get_next_item();
 
   55    Iter operator ++ (
int) 
noexcept 
   56    { Iter o = *
this; operator ++ (); 
return o; }
 
   58    Iter &operator -- () 
noexcept 
   63        _c = _c->get_prev_item();
 
   71    Iter operator -- (
int) 
noexcept 
   72    { Iter o = *
this; operator -- (); 
return o; }
 
 
  107  template< 
typename T, 
bool Poly = false>
 
  108  class T_iter : 
public Iter
 
  111    static bool const P = !Conversion<const T*, const List_item *>::exists
 
  114    static List_item *cast_to_li(T *i, Int_to_type<true>) 
noexcept 
  115    { 
return dynamic_cast<List_item*
>(i); }
 
  117    static List_item *cast_to_li(T *i, Int_to_type<false>) 
noexcept 
  120    static T *cast_to_type(List_item *i, Int_to_type<true>) 
noexcept 
  121    { 
return dynamic_cast<T*
>(i); }
 
  123    static T *cast_to_type(List_item *i, Int_to_type<false>) 
noexcept 
  124    { 
return static_cast<T*
>(i); }
 
  128    template< 
typename O >
 
  129    explicit T_iter(T_iter<O> 
const &o) noexcept
 
  130    : Iter(o) { 
dynamic_cast<T*
>(*o); }
 
  133    T_iter(T *f = 0) noexcept : Iter(cast_to_li(f, Int_to_type<P>())) {}
 
  134    T_iter(T *c, T *f) noexcept
 
  135    : Iter(cast_to_li(c, Int_to_type<P>()),
 
  136  cast_to_li(f, Int_to_type<P>()))
 
  139    inline T *operator * () 
const noexcept 
  140    { 
return cast_to_type(Iter::operator * (),Int_to_type<P>()); }
 
  141    inline T *operator -> () 
const noexcept 
  142    { 
return operator * (); }
 
  144    T_iter<T, Poly> operator ++ (
int) 
noexcept 
  145    { T_iter<T, Poly> o = *
this; Iter::operator ++ (); 
return o; }
 
  146    T_iter<T, Poly> operator -- (
int) 
noexcept 
  147    { T_iter<T, Poly> o = *
this; Iter::operator -- (); 
return o; }
 
  148    T_iter<T, Poly> &operator ++ () 
noexcept 
  149    { Iter::operator ++ (); 
return *
this; }
 
  150    T_iter<T, Poly> &operator -- () 
noexcept 
  151    { Iter::operator -- (); 
return *
this; }
 
 
  155  List_item() noexcept : _n(this), _p(this) {}
 
  171    List_item *pr = p->_p;
 
 
  205  template< 
typename C, 
typename N >
 
  206  static inline C *
push_back(C *head, N *p) 
noexcept;
 
  216  template< 
typename C, 
typename N >
 
  217  static inline C *
push_front(C *head, N *p) 
noexcept;
 
  227  template< 
typename C, 
typename N >
 
  228  static inline C *
remove(C *head, N *p) 
noexcept;
 
 
  236template< 
typename C, 
typename N >
 
  243  h->insert_prev_item(p);
 
 
  247template< 
typename C, 
typename N >
 
  253    h->insert_prev_item(p);
 
 
  257template< 
typename C, 
typename N >
 
  269        h = 
static_cast<C*
>(p->_n);
 
 
  276template< 
typename T, 
bool Poly >
 
  279{ 
return cast_to_type(Iter::remove_me(), Int_to_type<P>()); }
 
  282template< 
typename T >
 
  283class T_list_item : 
public List_item
 
  291template< 
typename LI >
 
  301  void push_front(LI *e) { _h = LI::push_front(_h, e); }
 
  302  void push_back(LI *e) { _h = LI::push_back(_h, e); }
 
  303  void insert_before(LI *e, LI *p)
 
  305    p->insert_prev_item(e);
 
  309  void insert_after(LI *e, LI *p) { p->insert_next_item(e); }
 
  312  { _h = LI::remove(_h, e); }
 
  314  LI *head()
 const { 
return _h; }
 
  322template< 
typename D, 
template<
typename A> 
class Alloc = 
New_allocator >
 
  329    E(D 
const &d) noexcept : data(d) {}
 
  334  class Node : 
private E
 
  337  typedef Alloc<Node> Node_alloc;
 
  349    Iter(E *e) noexcept : _i(e) {}
 
  351    D &operator * () 
const noexcept { 
return (*_i)->data; }
 
  352    D &operator -> () 
const noexcept { 
return (*_i)->data; }
 
  354    Iter operator ++ (
int) 
noexcept 
  355    { Iter o = *
this; operator ++ (); 
return o; }
 
  356    Iter operator -- (
int) 
noexcept 
  357    { Iter o = *
this; operator -- (); 
return o; }
 
  358    Iter &operator ++ () 
noexcept { ++_i; 
return *
this; }
 
  359    Iter &operator -- () 
noexcept { --_i; 
return *
this; }
 
  362    operator E* () 
const noexcept { 
return *_i; }
 
 
  365  List(Alloc<Node> 
const &a = Alloc<Node>()) noexcept : _h(0), _l(0), _a(a) {}
 
  370    void *n = _a.alloc();
 
 
  379    void *n = _a.alloc();
 
 
  387  { E *e = i; _h = 
E::remove(_h, e); --_l; _a.free(e); }
 
 
  390  unsigned long size() const noexcept { 
return _l; }
 
  394  { 
Iter i = _h; 
for (; idx && *i; ++i, --idx) { } 
return *i; }
 
 
  398  { 
Iter i = _h; 
for (; idx && *i; ++i, --idx) { } 
return *i; }
 
 
 
List_item * remove_me() noexcept
Remove item pointed to by iterator, and return pointer to element.
 
Iterator for derived classes from ListItem.
 
void remove_me() noexcept
Remove this item from the list.
 
static C * remove(C *head, N *p) noexcept
Remove item from a list.
 
static C * push_front(C *head, N *p) noexcept
Prepend item to a list.
 
void insert_next_item(List_item *p) noexcept
Insert item p after this item.
 
void insert_prev_item(List_item *p) noexcept
Insert item p before this item.
 
List_item * get_prev_item() const noexcept
Get previous item.
 
List_item * get_next_item() const noexcept
Get next item.
 
static C * push_back(C *head, N *p) noexcept
Append item to a list.
 
Doubly linked list, with internal allocation.
 
void remove(Iter const &i) noexcept
Remove element pointed to by the iterator.
 
unsigned long size() const noexcept
Get the length of the list.
 
void push_front(D const &d) noexcept
Add element at the beginning of the list.
 
D const & operator[](unsigned long idx) const noexcept
Random access.
 
Iter items() noexcept
Get iterator for the list elements.
 
void push_back(D const &d) noexcept
Add element at the end of the list.
 
Standard allocator based on operator new () .