Introduction
It seems very hard indeed to find anything on the net or in C++ STL books about how to implement a fully compliant STL container with class iterators, how to use the allocator etc. So now I've made this easy to understand example, which should more or less show it all. It models a linked list as the <
slist
> in SGI's STL implementation. Exception handling is not in this example, but it should be easy to add.
Background
It will be necessary to have a basic idea of how STL is used.
Using the code
Start by examining the stl_boost/my_container.hpp
along with the stl_boost/_test/_my_container.cpp
test examples. The code in my_container.hpp
is well documented and is intended as being used as a "self explaning working example". Hope to see some good general purpose STL-containers soon ... :-)
Here the most interesting part of the code is shown:
template < typename T, class A = std::allocator< T > >
class my_container
{
public:
typedef A allocator_type;
typedef typename A::value_type value_type;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::size_type size_type;
typedef typename A::difference_type difference_type;
private:
struct my_container_node
{
typedef my_container_node node_value_type;
typedef typename node_allocator::pointer node_pointer;
typedef typename node_allocator::const_pointer node_const_pointer;
typedef typename A::rebind< node_value_type >::other node_allocator;
node_pointer m_pNext;
T m_Data;
};
public:
template < bool bIsConst > class iterator_base
{
public:
typedef typename std::forward_iterator_tag iterator_category;
typedef typename A::value_type value_type;
typedef typename A::difference_type difference_type;
typedef typename tutils::select< bIsConst, const_pointer,
pointer >::result pointer;
typedef typename tutils::select< bIsConst, const_reference,
reference >::result reference;
typedef typename tutils::select< bIsConst, node_const_pointer,
node_pointer >::result node_pointer;
private:
node_pointer get_node_pointer() { return m_pNode; }
node_pointer m_pNode;
};
typedef iterator_base< false > iterator;
typedef iterator_base< true > const_iterator;
explicit my_container(const allocator_type& alloc)
: m_NodeAlloc(alloc), m_pFirst(0), m_pLast(0) {}
private:
node_pointer create_node(const_reference elem)
{
node_pointer pNode = m_NodeAlloc.allocate(1);
m_NodeAlloc.construct(pNode, node_value_type(elem));
return pNode;
}
void delete_node(node_pointer pNode)
{
m_NodeAlloc.destroy(pNode);
m_NodeAlloc.deallocate(pNode, 1);
}
node_allocator m_NodeAlloc;
node_pointer m_pFirst;
node_pointer m_pLast;
};