213 lines
4.0 KiB
C++
213 lines
4.0 KiB
C++
// vi:set ft=cpp: -*- Mode: C++ -*-
|
|
/*
|
|
* (c) 2011 Alexander Warg <warg@os.inf.tu-dresden.de>
|
|
* economic rights: Technische Universität Dresden (Germany)
|
|
*
|
|
* License: see LICENSE.spdx (in this directory or the directories above)
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "bits/list_basics.h"
|
|
|
|
namespace cxx {
|
|
|
|
class S_list_item
|
|
{
|
|
public:
|
|
S_list_item() : _n(0) {}
|
|
// BSS allocation
|
|
explicit S_list_item(bool) {}
|
|
|
|
private:
|
|
template<typename T, typename P> friend class S_list;
|
|
template<typename T, typename P> friend class S_list_tail;
|
|
template<typename T, typename X> friend struct Bits::Basic_list_policy;
|
|
|
|
S_list_item(S_list_item const &);
|
|
void operator = (S_list_item const &);
|
|
|
|
S_list_item *_n;
|
|
};
|
|
|
|
/**
|
|
* Simple single-linked list.
|
|
*
|
|
* \tparam T Type of elements saved in the list. Must inherit from
|
|
* cxx::S_list_item
|
|
*/
|
|
template< typename T, typename POLICY = Bits::Basic_list_policy< T, S_list_item > >
|
|
class S_list : public Bits::Basic_list<POLICY>
|
|
{
|
|
S_list(S_list const &) = delete;
|
|
void operator = (S_list const &) = delete;
|
|
|
|
private:
|
|
typedef typename Bits::Basic_list<POLICY> Base;
|
|
|
|
public:
|
|
typedef typename Base::Iterator Iterator;
|
|
|
|
S_list(S_list &&o) : Base(static_cast<Base&&>(o)) {}
|
|
|
|
S_list &operator = (S_list &&o)
|
|
{
|
|
Base::operator = (static_cast<Base&&>(o));
|
|
return *this;
|
|
}
|
|
|
|
// BSS allocation
|
|
explicit S_list(bool x) : Base(x) {}
|
|
|
|
S_list() : Base() {}
|
|
|
|
/// Add an element to the front of the list.
|
|
void add(T *e)
|
|
{
|
|
e->_n = this->_f;
|
|
this->_f = e;
|
|
}
|
|
|
|
template< typename CAS >
|
|
void add(T *e, CAS const &c)
|
|
{
|
|
do
|
|
{
|
|
e->_n = this->_f;
|
|
}
|
|
while (!c(&this->_f, e->_n, e));
|
|
}
|
|
|
|
/// Add an element to the front of the list.
|
|
void push_front(T *e) { add(e); }
|
|
|
|
/**
|
|
* Remove and return the head element of the list.
|
|
*
|
|
* \pre The list must not be empty or the behaviour will be undefined.
|
|
*/
|
|
T *pop_front()
|
|
{
|
|
T *r = this->front();
|
|
if (this->_f)
|
|
this->_f = this->_f->_n;
|
|
return r;
|
|
}
|
|
|
|
void insert(T *e, Iterator const &pred)
|
|
{
|
|
S_list_item *p = *pred;
|
|
e->_n = p->_n;
|
|
p->_n = e;
|
|
}
|
|
|
|
static void insert_before(T *e, Iterator const &succ)
|
|
{
|
|
S_list_item **x = Base::__get_internal(succ);
|
|
|
|
e->_n = *x;
|
|
*x = e;
|
|
}
|
|
|
|
static void replace(Iterator const &p, T*e)
|
|
{
|
|
S_list_item **x = Base::__get_internal(p);
|
|
e->_n = (*x)->_n;
|
|
*x = e;
|
|
}
|
|
|
|
static Iterator erase(Iterator const &e)
|
|
{
|
|
S_list_item **x = Base::__get_internal(e);
|
|
*x = (*x)->_n;
|
|
return e;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
template< typename T >
|
|
class S_list_bss : public S_list<T>
|
|
{
|
|
public:
|
|
S_list_bss() : S_list<T>(true) {}
|
|
};
|
|
|
|
template< typename T, typename POLICY = Bits::Basic_list_policy< T, S_list_item > >
|
|
class S_list_tail : public S_list<T, POLICY>
|
|
{
|
|
private:
|
|
typedef S_list<T, POLICY> Base;
|
|
void add(T *e) = delete;
|
|
|
|
public:
|
|
using Iterator = typename Base::Iterator;
|
|
S_list_tail() : Base(), _tail(&this->_f) {}
|
|
|
|
S_list_tail(S_list_tail &&t)
|
|
: Base(static_cast<Base&&>(t)), _tail(t.empty() ? &this->_f : t._tail)
|
|
{
|
|
t._tail = &t._f;
|
|
}
|
|
|
|
S_list_tail &operator = (S_list_tail &&t)
|
|
{
|
|
if (&t == this)
|
|
return *this;
|
|
|
|
Base::operator = (static_cast<Base &&>(t));
|
|
_tail = t.empty() ? &this->_f : t._tail;
|
|
t._tail = &t._f;
|
|
return *this;
|
|
}
|
|
|
|
void push_front(T *e)
|
|
{
|
|
if (Base::empty())
|
|
_tail = &e->_n;
|
|
|
|
Base::push_front(e);
|
|
}
|
|
|
|
void push_back(T *e)
|
|
{
|
|
e->_n = 0;
|
|
*_tail = e;
|
|
_tail = &e->_n;
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
Base::clear();
|
|
_tail = &this->_f;
|
|
}
|
|
|
|
void append(S_list_tail &o)
|
|
{
|
|
T *x = o.front();
|
|
*_tail = x;
|
|
if (x)
|
|
_tail = o._tail;
|
|
o.clear();
|
|
}
|
|
|
|
T *pop_front()
|
|
{
|
|
T *t = Base::pop_front();
|
|
if (t && Base::empty())
|
|
_tail = &this->_f;
|
|
return t;
|
|
}
|
|
|
|
private:
|
|
static void insert(T *e, Iterator const &pred);
|
|
static void insert_before(T *e, Iterator const &succ);
|
|
static void replace(Iterator const &p, T*e);
|
|
static Iterator erase(Iterator const &e);
|
|
|
|
private:
|
|
S_list_item **_tail;
|
|
};
|
|
|
|
}
|