Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_LIST_H
Toshihiro Shimizu 890ddd
#define TCG_LIST_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "alignment.h"
Toshihiro Shimizu 890ddd
#include "macros.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <cstddef> // size_t</cstddef>
Toshihiro Shimizu 890ddd
#include <new>	 // placement new</new>
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "assert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Discriminate rvalues support - either use Boost's config.hpp for automatic lookup,
Toshihiro Shimizu 890ddd
// or deal with it manually
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_RVALUES_SUPPORT
Toshihiro Shimizu 890ddd
#include <boost config.hpp=""></boost>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef BOOST_NO_RVALUE_REFERENCES
Toshihiro Shimizu 890ddd
#define TCG_RVALUES_SUPPORT 0
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define TCG_RVALUES_SUPPORT 1
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if (TCG_RVALUES_SUPPORT > 0)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Perfect forwarding macros
Toshihiro Shimizu 890ddd
#define TCG_FORWARD_TYPE(TheType) TheType##__ &&
Toshihiro Shimizu 890ddd
#define TCG_FORWARD_TEMPLATE(TheType) template <typename thetype##__=""></typename>
Toshihiro Shimizu 890ddd
#define TCG_FORWARD(TheType, Val) std::forward<thetype##__>(Val)</thetype##__>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Common const reference forwarding macros
Toshihiro Shimizu 890ddd
#define TCG_FORWARD_TYPE(TheType) const TheType &
Toshihiro Shimizu 890ddd
#define TCG_FORWARD_TEMPLATE(TheType)
Toshihiro Shimizu 890ddd
#define TCG_FORWARD(TheType, Val) Val
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \file     tcg_list.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    \brief    This file contains the implementation of an indexed list,
Toshihiro Shimizu 890ddd
              a list class based on a random access sequential container.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Preliminaries
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static const size_t _neg = -1,
Toshihiro Shimizu 890ddd
					_invalid = -2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace tcg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Indexed list node  definition
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Internal node class used in the implementation of a tcg::list_base.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
struct _list_node {
Toshihiro Shimizu 890ddd
	TCG_STATIC_ASSERT(sizeof(T) == sizeof(aligned_buffer<t>));</t>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aligned_buffer<t> m_val;</t>
Toshihiro Shimizu 890ddd
	size_t m_prev, m_next;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TCG_DEBUG(T &m_t;) // Provided for debuggers' convenience
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	_list_node() : m_prev(_neg), m_next(_invalid) TCG_DEBUG2(, m_t(value()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	_list_node(const T &val) : m_prev(_neg), m_next(_neg) TCG_DEBUG2(, m_t(value()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		constructValue(val);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	~_list_node()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (isValid())
Toshihiro Shimizu 890ddd
			destroyValue();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	_list_node(const _list_node &other)
Toshihiro Shimizu 890ddd
		: m_prev(other.m_prev), m_next(other.m_next) TCG_DEBUG2(, m_t(value()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (other.isValid())
Toshihiro Shimizu 890ddd
			constructValue(other.value());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	_list_node &operator=(const _list_node &other)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (isValid())
Toshihiro Shimizu 890ddd
			if (other.isValid())
Toshihiro Shimizu 890ddd
				value() = other.value();
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				destroyValue();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			constructValue(other.value());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_prev = other.m_prev, m_next = other.m_next;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const T &value() const { return reinterpret_cast<const &="" t="">(m_val.m_buf); }</const>
Toshihiro Shimizu 890ddd
	T &value() { return reinterpret_cast<t &="">(m_val.m_buf); }</t>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isValid() const { return (m_next != _invalid); }
Toshihiro Shimizu 890ddd
	void invalidate()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(isValid());
Toshihiro Shimizu 890ddd
		destroyValue();
Toshihiro Shimizu 890ddd
		m_next = _invalid;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if (TCG_RVALUES_SUPPORT > 0)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	_list_node(T &&val) : m_prev(_neg), m_next(_neg) TCG_DEBUG2(, m_t(value()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		constructValue(std::move(val));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	_list_node(_list_node &&other)
Toshihiro Shimizu 890ddd
		: m_prev(other.m_prev), m_next(other.m_next) TCG_DEBUG2(, m_t(value()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (other.isValid())
Toshihiro Shimizu 890ddd
			constructValue(std::move(other.value())), other.invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	_list_node &operator=(_list_node &&other)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (isValid())
Toshihiro Shimizu 890ddd
			if (other.isValid())
Toshihiro Shimizu 890ddd
				value() = other.value();
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				destroyValue();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			constructValue(std::move(other.value()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		value() = std::move(other.value());
Toshihiro Shimizu 890ddd
		m_prev = other.m_prev, m_next = other.m_next;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	void constructValue(const T &val) { new (m_val.m_buf) T(val); }
Toshihiro Shimizu 890ddd
	void destroyValue() { value().~T(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if (TCG_RVALUES_SUPPORT > 0)
Toshihiro Shimizu 890ddd
	void constructValue(T &&val)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		new (m_val.m_buf) T(std::move(val));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Base indexed list  definition
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Base class for list-like containers based on <tt>tcg::list</tt>'s
Toshihiro Shimizu 890ddd
            indexed list implementation.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  This class implements a barebone container class which manages
Toshihiro Shimizu 890ddd
            a collection of nodes stored in an iternal random access container.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            Nodes management is limited to the \a acquisition and \a release
Toshihiro Shimizu 890ddd
            of individual nodes (see the buyNode() and sellNode() functions).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            Links between list nodes must be managed externally.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \sa       Template class \p tcg::list for an explanation of the indexed list
Toshihiro Shimizu 890ddd
            container concept.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
class list_base
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef T value_type;
Toshihiro Shimizu 890ddd
	typedef ::size_t size_t;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static const size_t _neg = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	typedef _list_node<t> list_node;</t>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<list_node> m_vector;</list_node>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	size_t m_size;
Toshihiro Shimizu 890ddd
	size_t m_clearedHead;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	struct const_iterator : public std::iterator<std::bidirectional_iterator_tag, const="" t=""> {</std::bidirectional_iterator_tag,>
Toshihiro Shimizu 890ddd
		const list_base *m_list;
Toshihiro Shimizu 890ddd
		size_t m_idx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TCG_DEBUG(const list_node *m_node;) // Provided for debuggers' convenience
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		typedef const T value_type;
Toshihiro Shimizu 890ddd
		typedef const T *pointer;
Toshihiro Shimizu 890ddd
		typedef const T &reference;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		const_iterator() {}
Toshihiro Shimizu 890ddd
		const_iterator(const list_base *list, size_t idx)
Toshihiro Shimizu 890ddd
			: m_list(list), m_idx(idx) { TCG_DEBUG(m_node = (m_idx == _neg) ? 0 : &m_list->m_vector[m_idx]); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size_t index() const { return m_idx; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		reference operator*() const { return (*m_list)[m_idx]; }
Toshihiro Shimizu 890ddd
		pointer operator->() const { return &(*m_list)[m_idx]; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const_iterator operator++(int)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			const_iterator temp(*this);
Toshihiro Shimizu 890ddd
			operator++();
Toshihiro Shimizu 890ddd
			return temp;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		const_iterator &operator++()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			m_idx = m_list->m_vector[m_idx].m_next;
Toshihiro Shimizu 890ddd
			TCG_DEBUG(m_node = (m_idx == _neg) ? 0 : &m_list->m_vector[m_idx]);
Toshihiro Shimizu 890ddd
			return *this;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const_iterator operator--(int)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			const_iterator temp(*this);
Toshihiro Shimizu 890ddd
			operator--();
Toshihiro Shimizu 890ddd
			return temp;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		const_iterator &operator--()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			m_idx = m_list->m_vector[m_idx].m_prev;
Toshihiro Shimizu 890ddd
			TCG_DEBUG(m_node = (m_idx == _neg) ? 0 : &m_list->m_vector[m_idx]);
Toshihiro Shimizu 890ddd
			return *this;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bool operator==(const const_iterator &it) const { return (m_idx == it.m_idx); }
Toshihiro Shimizu 890ddd
		bool operator!=(const const_iterator &it) const { return (m_idx != it.m_idx); }
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	struct iterator : public const_iterator {
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		typedef T value_type;
Toshihiro Shimizu 890ddd
		typedef T *pointer;
Toshihiro Shimizu 890ddd
		typedef T &reference;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		iterator() {}
Toshihiro Shimizu 890ddd
		iterator(list_base *list, size_t idx) : const_iterator(list, idx) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		reference operator*() const { return const_cast<reference>(const_iterator::operator*()); }</reference>
Toshihiro Shimizu 890ddd
		pointer operator->() const { return const_cast<pointer>(const_iterator::operator->()); }</pointer>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		iterator operator++(int)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			iterator temp(*this);
Toshihiro Shimizu 890ddd
			operator++();
Toshihiro Shimizu 890ddd
			return temp;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		iterator &operator++()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			const_iterator::operator++();
Toshihiro Shimizu 890ddd
			return *this;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		iterator operator--(int)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			iterator temp(*this);
Toshihiro Shimizu 890ddd
			operator--();
Toshihiro Shimizu 890ddd
			return temp;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		iterator &operator--()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			const_iterator::operator--();
Toshihiro Shimizu 890ddd
			return *this;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	friend struct iterator;
Toshihiro Shimizu 890ddd
	friend struct const_iterator;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	list_base() : m_size(0), m_clearedHead(_neg) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	list_base(size_t count, const T &val)
Toshihiro Shimizu 890ddd
		: m_vector(count, list_node(val)), m_size(count), m_clearedHead(_neg)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_size >= 0);
Toshihiro Shimizu 890ddd
		for (size_t i = 0; i < m_size; ++i)
Toshihiro Shimizu 890ddd
			m_vector[i].m_prev = i - 1, m_vector[i].m_next = i + 1;
Toshihiro Shimizu 890ddd
		if (m_size > 0)
Toshihiro Shimizu 890ddd
			m_vector[m_size - 1].m_next = _neg;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename init=""></typename>
Toshihiro Shimizu 890ddd
	list_base(InIt begin, InIt end)
Toshihiro Shimizu 890ddd
		: m_vector(begin, end), m_size(m_vector.size()), m_clearedHead(_neg)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(m_size >= 0);
Toshihiro Shimizu 890ddd
		for (size_t i = 0; i < m_size; ++i)
Toshihiro Shimizu 890ddd
			m_vector[i].m_prev = i - 1, m_vector[i].m_next = i + 1;
Toshihiro Shimizu 890ddd
		if (m_size > 0)
Toshihiro Shimizu 890ddd
			m_vector[m_size - 1].m_next = _neg;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	list_base(const list_base &other)
Toshihiro Shimizu 890ddd
		: m_vector(other.m_vector), m_size(other.m_size), m_clearedHead(other.m_clearedHead) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	list_base &operator=(const list_base &other)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// Note: not using the copy-and-swap idiom. We want to attempt preservation
Toshihiro Shimizu 890ddd
		// of m_vector's buffer in case its current capacity is sufficient.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_size = other.m_size;
Toshihiro Shimizu 890ddd
		m_clearedHead = other.m_clearedHead;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// A clear must be performed before the actual =. It's necessary to prevent copying to
Toshihiro Shimizu 890ddd
		// objects that were already destroyed - but are still in the vector as zombies.
Toshihiro Shimizu 890ddd
		// In this case, the value-to-value vector::operator= would assume that the
Toshihiro Shimizu 890ddd
		// assigned-to object is NOT a zombie - and would attempt its release, which is UB!
Toshihiro Shimizu 890ddd
		m_vector.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_vector = other.m_vector;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if (TCG_RVALUES_SUPPORT > 0)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	list_base(list_base &&other)
Toshihiro Shimizu 890ddd
		: m_vector(std::move(other.m_vector)), m_size(other.m_size), m_clearedHead(other.m_clearedHead)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	list_base &operator=(list_base &&other)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		swap(*this, std::forward<list_base>(other));</list_base>
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T &operator[](size_t idx)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(idx < m_vector.size() && isValid(idx));
Toshihiro Shimizu 890ddd
		return m_vector[idx].value();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	const T &operator[](size_t idx) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(idx < m_vector.size() && isValid(idx));
Toshihiro Shimizu 890ddd
		return m_vector[idx].value();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isValid(size_t idx) const { return m_vector[idx].isValid(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	size_t size() const { return m_size; }
Toshihiro Shimizu 890ddd
	size_t nodesCount() const { return m_vector.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void reserve(size_t size) { m_vector.reserve(size); }
Toshihiro Shimizu 890ddd
	size_t capacity() const { return m_vector.capacity(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_size = 0;
Toshihiro Shimizu 890ddd
		m_clearedHead = _neg;
Toshihiro Shimizu 890ddd
		m_vector.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool empty() const { return m_size == 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void _swap(list_base &a, list_base &b)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		std::swap(a.m_size, b.m_size);
Toshihiro Shimizu 890ddd
		std::swap(a.m_clearedHead, b.m_clearedHead);
Toshihiro Shimizu 890ddd
		a.m_vector.swap(b.m_vector);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if (TCG_RVALUES_SUPPORT > 0)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void _swap(list_base &a, list_base &&b)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		a.m_size = b.m_size;
Toshihiro Shimizu 890ddd
		a.m_clearedHead = b.m_clearedHead;
Toshihiro Shimizu 890ddd
		a.m_vector.swap(b.m_vector);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void _swap(list_base &&a, list_base &b)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		swap(b, std::move(a));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Constructs from a range of (index, value) pairs
Toshihiro Shimizu 890ddd
	template <typename forit=""></typename>
Toshihiro Shimizu 890ddd
	list_base(ForIt begin, ForIt end, size_t nodesCount)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// Initialize the vector with invalid nodes up to the required nodes count
Toshihiro Shimizu 890ddd
		m_vector.resize(nodesCount, list_node());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Iterate the range and add corresponding value pairs
Toshihiro Shimizu 890ddd
		size_t lastIdx = _neg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (; begin != end; ++begin) {
Toshihiro Shimizu 890ddd
			size_t idx = (*begin).first;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			assert(idx >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Further resize the vector with holes if necessary
Toshihiro Shimizu 890ddd
			if (idx >= m_vector.size()) {
Toshihiro Shimizu 890ddd
				// The nodesCount hint was not sufficient. Thus, we have to readjust the correct minimal
Toshihiro Shimizu 890ddd
				// allocation size. Let's do it now with a further single pass toward the end.
Toshihiro Shimizu 890ddd
				size_t newSize = m_vector.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (ForIt it = begin; it != end; ++it)
Toshihiro Shimizu 890ddd
					newSize = std::max(newSize, size_t((*it).first) + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				m_vector.resize(newSize, list_node());
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Place current node in the vector
Toshihiro Shimizu 890ddd
			list_node &node = m_vector[idx];
Toshihiro Shimizu 890ddd
			new (&node) list_node((*begin).second);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Link the node
Toshihiro Shimizu 890ddd
			node.m_prev = lastIdx;
Toshihiro Shimizu 890ddd
			if (lastIdx != _neg)
Toshihiro Shimizu 890ddd
				m_vector[lastIdx].m_next = idx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			lastIdx = idx;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Finally, make up a consistent links chain for holes
Toshihiro Shimizu 890ddd
		lastIdx = _neg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size_t n, nCount = m_vector.size();
Toshihiro Shimizu 890ddd
		for (n = 0; n != nCount; ++n) {
Toshihiro Shimizu 890ddd
			list_node &node = m_vector[n];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!node.isValid())
Toshihiro Shimizu 890ddd
				node.m_prev = lastIdx, lastIdx = n;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_clearedHead = lastIdx;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	TCG_FORWARD_TEMPLATE(T)
Toshihiro Shimizu 890ddd
	size_t buyNode(TCG_FORWARD_TYPE(T) val)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		size_t nodeIdx;
Toshihiro Shimizu 890ddd
		list_node *node;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		++m_size;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_clearedHead != _neg) {
Toshihiro Shimizu 890ddd
			assert(m_clearedHead < m_vector.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// Take the last cleared element
Toshihiro Shimizu 890ddd
			nodeIdx = m_clearedHead;
Toshihiro Shimizu 890ddd
			node = &m_vector[nodeIdx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_clearedHead = node->m_prev;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_vector.push_back(list_node());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			nodeIdx = m_vector.size() - 1;
Toshihiro Shimizu 890ddd
			node = &m_vector[nodeIdx];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Construct the node's value
Toshihiro Shimizu 890ddd
		node->constructValue(TCG_FORWARD(T, val));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return nodeIdx;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void sellNode(size_t idx)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(isValid(idx));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		list_node &node = m_vector[idx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Relink neighbours
Toshihiro Shimizu 890ddd
		if (node.m_prev != _neg)
Toshihiro Shimizu 890ddd
			m_vector[node.m_prev].m_next = node.m_next;
Toshihiro Shimizu 890ddd
		if (node.m_next != _neg)
Toshihiro Shimizu 890ddd
			m_vector[node.m_next].m_prev = node.m_prev;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Explicitly invoke the node's destructor
Toshihiro Shimizu 890ddd
		node.invalidate();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Now, the node is a zombie - still, use its indices data to remember the list
Toshihiro Shimizu 890ddd
		// of unused nodes
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Remember the last cleared element in element.m_prev
Toshihiro Shimizu 890ddd
		node.m_prev = m_clearedHead;
Toshihiro Shimizu 890ddd
		m_clearedHead = idx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		--m_size;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void sellNodes(size_t begin, size_t end)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for (size_t i = begin; i != end; i = m_vector[i].m_next)
Toshihiro Shimizu 890ddd
			sellNode(i);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void move(size_t afterDst, size_t &dstBegin, size_t &dstRBegin,
Toshihiro Shimizu 890ddd
			  size_t srcBegin, size_t srcEnd, size_t srcRBegin)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (srcBegin == _neg || srcBegin == afterDst)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// afterDst-1 -> srcBegin
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			size_t beforeDst = (afterDst == _neg) ? dstRBegin : m_vector[afterDst].m_prev;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_vector[srcBegin].m_prev = beforeDst;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (beforeDst != _neg)
Toshihiro Shimizu 890ddd
				m_vector[beforeDst].m_next = srcBegin;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				dstBegin = srcBegin;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// srcEnd-1 -> afterDst
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			size_t srcLast = (srcEnd == _neg) ? srcRBegin : m_vector[srcEnd].m_prev;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_vector[srcLast].m_next = afterDst; // NOTE: srcLast cannot be _neg
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (afterDst != _neg)
Toshihiro Shimizu 890ddd
				m_vector[afterDst].m_prev = srcLast;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				dstRBegin = srcLast;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Indexed list  definition
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Double linked list container class with indexed access to elements.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  This class is the result of implementing a double linked list using a
Toshihiro Shimizu 890ddd
            dynamic random access sequential container as the underlying pool for
Toshihiro Shimizu 890ddd
            the list's nodes.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            This is somewhat different than supplying a custom allocator to an existing
Toshihiro Shimizu 890ddd
            list implementation, like \p std::list, since:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              
    Toshihiro Shimizu 890ddd
                  
  • No memory model of the underlying container is actually
  • Toshihiro Shimizu 890ddd
                        required.
    Toshihiro Shimizu 890ddd
                  
  • The underlying container provides explicit access to nodes
  • Toshihiro Shimizu 890ddd
                        using their associated insertion indexes, so \p std::list
    Toshihiro Shimizu 890ddd
                        could not be used as-is.
    Toshihiro Shimizu 890ddd
                  
    Toshihiro Shimizu 890ddd
    \n
    Toshihiro Shimizu 890ddd
                The nodes pool (see \p list_base) is an internal \a lazy container that
    Toshihiro Shimizu 890ddd
                saves released nodes \a without actually deallocating them (of course,
    Toshihiro Shimizu 890ddd
                their content is properly destroyed). They are rather stored into an
    Toshihiro Shimizu 890ddd
                internal \a stack of released nodes, ready to be reacquired.
    Toshihiro Shimizu 890ddd
                  \par Features
    Toshihiro Shimizu 890ddd
                  \li  Insertion indexes are automatically generated keys with the same
    Toshihiro Shimizu 890ddd
                       access time of the undelying container (typically super-fast
    Toshihiro Shimizu 890ddd
                       \p O(1)).
    Toshihiro Shimizu 890ddd
                  \li  Stable indexes and iterators with respect to every operation.
    Toshihiro Shimizu 890ddd
                  \li  Copying an indexed list \a preserves the original indexes.
    Toshihiro Shimizu 890ddd
                  \li  Indexes are process independent - they can be saved
    Toshihiro Shimizu 890ddd
                       on file and restored later (although you probably want to
    Toshihiro Shimizu 890ddd
                       \a squeeze the list before saving).
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
                  \par Use cases
    Toshihiro Shimizu 890ddd
                This class is surprisingly useful for cross-referencing.
    Toshihiro Shimizu 890ddd
                A graph data structure, for example, can be implemented using a pair of
    Toshihiro Shimizu 890ddd
                indexed lists for vertexes and edges.
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
                  \par Known issues
    Toshihiro Shimizu 890ddd
                The lazy nature of this container class may require \a squeezing the list's
    Toshihiro Shimizu 890ddd
                content at strategic places in your code, as noted before.
    Toshihiro Shimizu 890ddd
                Beware that composite cross-referencing may be hard to track \a precisely
    Toshihiro Shimizu 890ddd
                during this particular operation.
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
      \remark   Current implementation explicitly uses an \p std::vector class as the
    Toshihiro Shimizu 890ddd
                underlying random access container. Future improvements will make the
    Toshihiro Shimizu 890ddd
                container class a template parameter.
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
      \sa       Template class \p tcg::Mesh for a notable use case.
    Toshihiro Shimizu 890ddd
    */
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    template <typename t=""></typename>
    Toshihiro Shimizu 890ddd
    class list : public list_base<t></t>
    Toshihiro Shimizu 890ddd
    {
    Toshihiro Shimizu 890ddd
    	size_t m_begin, m_rbegin;
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    protected:
    Toshihiro Shimizu 890ddd
    	typedef typename list_base<t>::list_node list_node;</t>
    Toshihiro Shimizu 890ddd
    	using list_base<t>::m_vector;</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    public:
    Toshihiro Shimizu 890ddd
    	struct iterator : public list_base<t>::iterator {</t>
    Toshihiro Shimizu 890ddd
    		iterator() {}
    Toshihiro Shimizu 890ddd
    		iterator(list *l, size_t idx) : list_base<t>::iterator(l, idx) {}</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		iterator &operator++()
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			list_base<t>::iterator::operator++();</t>
    Toshihiro Shimizu 890ddd
    			return *this;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    		iterator &operator--()
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			if (this->m_idx == _neg)
    Toshihiro Shimizu 890ddd
    				operator=(static_cast<list *="">(this->m_list)->last());</list>
    Toshihiro Shimizu 890ddd
    			else
    Toshihiro Shimizu 890ddd
    				list_base<t>::iterator::operator--();</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    			return *this;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		iterator operator++(int)
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			iterator temp(*this);
    Toshihiro Shimizu 890ddd
    			operator++();
    Toshihiro Shimizu 890ddd
    			return temp;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    		iterator operator--(int)
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			iterator temp(*this);
    Toshihiro Shimizu 890ddd
    			operator--();
    Toshihiro Shimizu 890ddd
    			return temp;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    	};
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	struct const_iterator : public list_base<t>::const_iterator {</t>
    Toshihiro Shimizu 890ddd
    		const_iterator() {}
    Toshihiro Shimizu 890ddd
    		const_iterator(const list *l, size_t idx) : list_base<t>::const_iterator(l, idx) {}</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		const_iterator &operator++()
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			list_base<t>::const_iterator::operator++();</t>
    Toshihiro Shimizu 890ddd
    			return *this;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    		const_iterator &operator--()
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			if (this->m_idx == _neg)
    Toshihiro Shimizu 890ddd
    				operator=(static_cast<const *="" list="">(this->m_list)->last());</const>
    Toshihiro Shimizu 890ddd
    			else
    Toshihiro Shimizu 890ddd
    				list_base<t>::const_iterator::operator--();</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    			return *this;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		const_iterator operator++(int)
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			const_iterator temp(*this);
    Toshihiro Shimizu 890ddd
    			operator++();
    Toshihiro Shimizu 890ddd
    			return temp;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    		const_iterator operator--(int)
    Toshihiro Shimizu 890ddd
    		{
    Toshihiro Shimizu 890ddd
    			const_iterator temp(*this);
    Toshihiro Shimizu 890ddd
    			operator--();
    Toshihiro Shimizu 890ddd
    			return temp;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    	};
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    public:
    Toshihiro Shimizu 890ddd
    	list() : m_begin(_neg), m_rbegin(_neg) {}
    Toshihiro Shimizu 890ddd
    	list(size_t count, const T &val) : list_base<t>(count, val), m_begin(0), m_rbegin(count - 1) {}</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	template <typename init=""></typename>
    Toshihiro Shimizu 890ddd
    	list(InIt begin, InIt end) : list_base<t>(begin, end), m_begin(list_base<t>::m_size ? 0 : _neg), m_rbegin(list_base<t>::m_size - 1) {}</t></t></t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	//! Constructs from a range of (index, value) pairs
    Toshihiro Shimizu 890ddd
    	template <typename bidit=""></typename>
    Toshihiro Shimizu 890ddd
    	list(BidIt begin, BidIt end, size_t nodesCount) : list_base<t>(begin, end, nodesCount)</t>
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		if (begin != end)
    Toshihiro Shimizu 890ddd
    			m_begin = (*begin).first, m_rbegin = (*--end).first;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	//-----------------------------------------------------------------------------------------
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	list(const list &other) : list_base<t>(other), m_begin(other.m_begin), m_rbegin(other.m_rbegin) {}</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	/*!
    Toshihiro Shimizu 890ddd
        \warning  \p tcg::list has a different copy behavior from other container classes, since
    Toshihiro Shimizu 890ddd
                  it is intended to preserve the source's node indices in the process.
    Toshihiro Shimizu 890ddd
        
    Toshihiro Shimizu 890ddd
                  This means that no value-to-value assignment can take place, and thus <tt>operator=</tt>'s
    Toshihiro Shimizu 890ddd
                  behavior is equivalent to first clearing it, and then copy-constructing each value.
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
                  This typically leads to performance penalties with respect to other container classes that
    Toshihiro Shimizu 890ddd
                  implement value-to-value assignments, like \p std::vector in case its capacity is not exceeded.
    Toshihiro Shimizu 890ddd
      */
    Toshihiro Shimizu 890ddd
    	list &operator=(const list &other)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		m_begin = other.m_begin, m_rbegin = other.m_rbegin;
    Toshihiro Shimizu 890ddd
    		list_base<t>::operator=(other);</t>
    Toshihiro Shimizu 890ddd
    		return *this;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #if (TCG_RVALUES_SUPPORT > 0)
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	list(list &&other) : list_base<t>(std::forward<list_base<t>>(other)), m_begin(other.m_begin), m_rbegin(other.m_rbegin)</list_base<t></t>
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	list &operator=(list &&other)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		swap(*this, std::forward<list>(other));</list>
    Toshihiro Shimizu 890ddd
    		return *this;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #endif
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	//-----------------------------------------------------------------------------------------
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	TCG_FORWARD_TEMPLATE(T)
    Toshihiro Shimizu 890ddd
    	size_t insert(size_t idx, TCG_FORWARD_TYPE(T) val)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		assert(idx == _neg || list_base<t>::isValid(idx));</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		size_t nodeIdx = list_base<t>::buyNode(TCG_FORWARD(T, val));</t>
    Toshihiro Shimizu 890ddd
    		list_node &node = m_vector[nodeIdx];
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		//Update links
    Toshihiro Shimizu 890ddd
    		if (idx != _neg) {
    Toshihiro Shimizu 890ddd
    			//node has a valid next
    Toshihiro Shimizu 890ddd
    			list_node &next = m_vector[idx];
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    			node.m_prev = next.m_prev;
    Toshihiro Shimizu 890ddd
    			next.m_prev = nodeIdx;
    Toshihiro Shimizu 890ddd
    			node.m_next = idx;
    Toshihiro Shimizu 890ddd
    			if (node.m_prev != _neg)
    Toshihiro Shimizu 890ddd
    				m_vector[node.m_prev].m_next = nodeIdx;
    Toshihiro Shimizu 890ddd
    		} else {
    Toshihiro Shimizu 890ddd
    			node.m_next = _neg;
    Toshihiro Shimizu 890ddd
    			node.m_prev = m_rbegin;
    Toshihiro Shimizu 890ddd
    			if (m_rbegin != _neg)
    Toshihiro Shimizu 890ddd
    				m_vector[m_rbegin].m_next = nodeIdx;
    Toshihiro Shimizu 890ddd
    			m_rbegin = nodeIdx;
    Toshihiro Shimizu 890ddd
    		}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		if (idx == m_begin)
    Toshihiro Shimizu 890ddd
    			m_begin = nodeIdx;
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		return nodeIdx;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	template <typename iter=""></typename>
    Toshihiro Shimizu 890ddd
    	size_t insert(size_t idx, Iter begin, Iter end)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		if (begin == end)
    Toshihiro Shimizu 890ddd
    			return idx;
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		assert(idx == _neg || list_base<t>::isValid(idx));</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		size_t res = insert(idx, *begin);
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		for (++begin; begin != end; ++begin)
    Toshihiro Shimizu 890ddd
    			insert(idx, *begin);
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		return res;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	size_t erase(size_t idx)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		assert(list_base<t>::isValid(idx));</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		if (idx == m_begin)
    Toshihiro Shimizu 890ddd
    			m_begin = m_vector[idx].m_next;
    Toshihiro Shimizu 890ddd
    		if (idx == m_rbegin)
    Toshihiro Shimizu 890ddd
    			m_rbegin = m_vector[idx].m_prev;
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		size_t result = m_vector[idx].m_next;
    Toshihiro Shimizu 890ddd
    		list_base<t>::sellNode(idx);</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		return result;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	size_t erase(size_t begin, size_t end)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		assert(list_base<t>::isValid(begin));</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		if (begin == m_begin)
    Toshihiro Shimizu 890ddd
    			m_begin = end;
    Toshihiro Shimizu 890ddd
    		if (end == m_rbegin)
    Toshihiro Shimizu 890ddd
    			m_rbegin = m_vector[begin].m_prev;
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		list_base<t>::sellNodes(begin, end);</t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		return end;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void clear()
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		list_base<t>::clear();</t>
    Toshihiro Shimizu 890ddd
    		m_begin = m_rbegin = _neg;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void swap(list &other)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		_swap(*this, other);
    Toshihiro Shimizu 890ddd
    		std::swap(m_begin, other.m_begin);
    Toshihiro Shimizu 890ddd
    		std::swap(m_rbegin, other.m_rbegin);
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void swap(list &a, list &b)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		a.swap(b);
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #if (TCG_RVALUES_SUPPORT > 0)
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void swap(list &&other)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		this->_swap(*this, std::move(other));
    Toshihiro Shimizu 890ddd
    		m_begin = other.m_begin;
    Toshihiro Shimizu 890ddd
    		m_rbegin = other.m_rbegin;
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void swap(list &a, list &&b)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		a.swap(std::move(b));
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void swap(list &&a, list &b)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		b.swap(std::move(a));
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #endif
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	//-----------------------------------------------------------------------------------------
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	/*!
    Toshihiro Shimizu 890ddd
        \details  This function is \p tcg::list's counterpart to \p std::list::splice().
    Toshihiro Shimizu 890ddd
                  It moves the specified range to a different part of the list, \a without
    Toshihiro Shimizu 890ddd
                  touching any element elements - just by altering node links.
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
        \note     Unlike \p std::list::splice(), the list must be the same.
    Toshihiro Shimizu 890ddd
      */
    Toshihiro Shimizu 890ddd
    	void move(size_t afterDst, size_t srcBegin, size_t srcEnd) //! Moves range <tt>[srcBegin, srcEnd)</tt> right before afterDst.      \param afterDst  Index right after the destination position. \param srcBegin  Start index of the moved range. \param srcEnd  End index of the moved range.
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		return move(afterDst, m_begin, m_rbegin,
    Toshihiro Shimizu 890ddd
    					srcBegin, srcEnd, m_rbegin);
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	/*!
    Toshihiro Shimizu 890ddd
        \sa       The equivalent function move(size_t, size_t, size_t).
    Toshihiro Shimizu 890ddd
      */
    Toshihiro Shimizu 890ddd
    	void move(iterator afterDst,
    Toshihiro Shimizu 890ddd
    			  iterator srcBegin, iterator srcEnd) //! Moves range <tt>[srcBegin, srcEnd)</tt> right before afterDst.      \param afterDst  Iterator right after the destination position. \param srcBegin  Start of the moved range. \param srcEnd  End of the moved range.
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		assert(afterDst.m_list == this &&
    Toshihiro Shimizu 890ddd
    			   srcBegin.m_list == this &&
    Toshihiro Shimizu 890ddd
    			   srcEnd.m_list == this);
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    		return move(afterDst.m_idx, srcBegin.m_idx, srcEnd.m_idx);
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	//-----------------------------------------------------------------------------------------
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	iterator insert(iterator it, const T &val) { return iterator(this, insert(it.m_idx, val)); }
    Toshihiro Shimizu 890ddd
    	iterator erase(iterator it) { return iterator(this, erase(it.m_idx)); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	template <typename iter=""></typename>
    Toshihiro Shimizu 890ddd
    	iterator insert(iterator it, Iter begin, Iter end) { return iterator(this, insert(it.m_idx, begin, end)); }
    Toshihiro Shimizu 890ddd
    	iterator erase(iterator begin, iterator end) { return iterator(this, erase(begin.m_idx, end.m_idx)); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	size_t push_front(const T &val) { return insert(m_begin, val); }
    Toshihiro Shimizu 890ddd
    	size_t push_back(const T &val) { return insert(_neg, val); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	void pop_front() { erase(m_begin); }
    Toshihiro Shimizu 890ddd
    	void pop_back() { erase(m_rbegin); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	T &front() { return m_vector[m_begin].value(); }
    Toshihiro Shimizu 890ddd
    	const T &front() const { return m_vector[m_begin].value(); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	T &back() { return m_vector[m_rbegin].value(); }
    Toshihiro Shimizu 890ddd
    	const T &back() const { return m_vector[m_rbegin].value(); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	iterator begin() { return iterator(this, m_begin); }
    Toshihiro Shimizu 890ddd
    	const_iterator begin() const { return const_iterator(this, m_begin); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	iterator last() { return iterator(this, m_rbegin); }
    Toshihiro Shimizu 890ddd
    	const_iterator last() const { return const_iterator(this, m_rbegin); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	iterator end() { return iterator(this, _neg); }
    Toshihiro Shimizu 890ddd
    	const_iterator end() const { return const_iterator(this, _neg); }
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #if (TCG_RVALUES_SUPPORT > 0)
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    	iterator insert(iterator it, T &&val)
    Toshihiro Shimizu 890ddd
    	{
    Toshihiro Shimizu 890ddd
    		return iterator(this, insert<t>(it.m_idx, std::forward<t>(val)));</t></t>
    Toshihiro Shimizu 890ddd
    	}
    Toshihiro Shimizu 890ddd
    	size_t push_front(T &&val) { return insert<t>(m_begin, std::forward<t>(val)); }</t></t>
    Toshihiro Shimizu 890ddd
    	size_t push_back(T &&val) { return insert<t>(_neg, std::forward<t>(val)); }</t></t>
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #endif
    Toshihiro Shimizu 890ddd
    };
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    } // namespace tcg
    Toshihiro Shimizu 890ddd
    Toshihiro Shimizu 890ddd
    #endif // TCG_LIST_H