c26e20553d
[SVN r47494]
504 lines
17 KiB
ReStructuredText
504 lines
17 KiB
ReStructuredText
++++++++++++++++++++++++++++++++++
|
|
|Boost| Pointer Container Library
|
|
++++++++++++++++++++++++++++++++++
|
|
|
|
.. |Boost| image:: boost.png
|
|
|
|
=========
|
|
Reference
|
|
=========
|
|
|
|
The documentation is divided into an explanation for
|
|
each container. When containers have the same interface, that common interface is explained only once,
|
|
but links are always provided to more relevant information.
|
|
Please make sure you understand
|
|
the `Clonable <reference.html#the-Clonable-concept>`_ concept and
|
|
the `Clone Allocator <reference.html#the-clone-allocator-concept>`_ concept.
|
|
|
|
- `Conventions <conventions.html>`_
|
|
- `The Clonable concept`_
|
|
- `The Clone Allocator concept`_
|
|
|
|
- `Class hierarchy`_:
|
|
|
|
- `reversible_ptr_container <reversible_ptr_container.html>`_
|
|
|
|
- `ptr_sequence_adapter <ptr_sequence_adapter.html>`_
|
|
|
|
- `ptr_vector <ptr_vector.html>`_
|
|
- `ptr_list <ptr_list.html>`_
|
|
- `ptr_deque <ptr_deque.html>`_
|
|
- `ptr_array <ptr_array.html>`_
|
|
|
|
- `associative_ptr_container <associative_ptr_container.html>`_
|
|
|
|
- `ptr_set_adapter <ptr_set_adapter.html>`_
|
|
- `ptr_multiset_adapter <ptr_multiset_adapter.html>`_
|
|
- `ptr_map_adapter <ptr_map_adapter.html>`_
|
|
- `ptr_multi_map_adapter <ptr_multimap_adapter.html>`_
|
|
|
|
- `ptr_set <ptr_set.html>`_
|
|
- `ptr_multi_set <ptr_multiset.html>`_
|
|
- `ptr_map <ptr_map.html>`_
|
|
- `ptr_multimap <ptr_multimap.html>`_
|
|
|
|
- `Serialization`_
|
|
- `Indirected functions <indirect_fun.html>`_
|
|
- `Insert iterators <ptr_inserter.html>`_
|
|
- `Class nullable`_
|
|
- `Exception classes`_
|
|
- `Disabling the use of exceptions`_
|
|
|
|
|
|
..
|
|
- Class `reversible_ptr_container <reversible_ptr_container.html>`_
|
|
- Class `associative_ptr_container <associative_ptr_container.html>`_
|
|
- `Pointer container adapters`_
|
|
|
|
- `ptr_sequence_adapter <ptr_sequence_adapter.html>`_
|
|
- `ptr_set_adapter <ptr_set_adapter.html>`_
|
|
- `ptr_multiset_adapter <ptr_multiset_adapter.html>`_
|
|
- `ptr_map_adapter <ptr_map_adapter.html>`_
|
|
- `ptr_multimap_adapter <ptr_multimap_adapter.html>`_
|
|
- `Sequence containers`_
|
|
|
|
- `ptr_vector <ptr_vector.html>`_
|
|
- `ptr_deque <ptr_deque.html>`_
|
|
- `ptr_list <ptr_list.html>`_
|
|
- `ptr_array <ptr_array.html>`_
|
|
- `Associative containers`_
|
|
|
|
- `ptr_set <ptr_set.html>`_
|
|
- `ptr_multiset <ptr_multiset.html>`_
|
|
- `ptr_map <ptr_map.html>`_
|
|
- `ptr_multimap <ptr_multimap.html>`_
|
|
|
|
|
|
|
|
The Clonable concept
|
|
++++++++++++++++++++
|
|
|
|
**Refinement of**
|
|
|
|
- Heap Allocable
|
|
- Heap Deallocable
|
|
|
|
The Clonable concept is introduced to formalize the requirements for
|
|
copying heap-allocated objects. A type ``T`` might be Clonable even though it
|
|
is not Assignable or Copy Constructible. Notice that many operations on
|
|
the containers do not even require the stored type to be Clonable.
|
|
|
|
**Notation**
|
|
|
|
======================= ============================================ =================== =====================
|
|
**Type** **Object** (``const`` or non-``const``) **Pointer** **Describes**
|
|
``T`` ``a`` ``ptr`` A Clonable type
|
|
======================= ============================================ =================== =====================
|
|
|
|
**Valid expressions**
|
|
|
|
===================================== =========================== ======================================================================================== ===================================
|
|
**Expression** **Type** **Semantics** **Postcondition**
|
|
``new_clone(a);`` ``T*`` Allocate a new object that can be considered equivalent to the ``a`` object ``typeid(*new_clone(a)) == typeid(a)``
|
|
``delete_clone(ptr);`` ``void`` Deallocate an object previously allocated with ``allocate_clone()``. Must not throw
|
|
===================================== =========================== ======================================================================================== ===================================
|
|
|
|
|
|
Default implementation
|
|
----------------------
|
|
|
|
In the ``<boost/ptr_container/clone_allocator.hpp>`` header a default implementation
|
|
of the two functions is given:
|
|
|
|
.. parsed-literal::
|
|
|
|
namespace boost
|
|
{
|
|
template< class T >
|
|
inline T* new_clone( const T& t )
|
|
{
|
|
return new T( t );
|
|
}
|
|
|
|
template< class T >
|
|
void delete_clone( const T* t )
|
|
{
|
|
checked_delete( t );
|
|
}
|
|
}
|
|
|
|
|
|
Notice that this implementation makes normal Copy Constructible classes automatically
|
|
Clonable unless ``operator new()`` or ``operator delete()`` are hidden.
|
|
|
|
The two functions represent a layer of indirection which is necessary to support
|
|
classes that are not Copy Constructible by default. Notice that the implementation
|
|
relies on argument-dependent lookup (ADL) to find the right version of
|
|
``new_clone()`` and ``delete_clone()``. This means that one does not need to overload or specialize
|
|
the function in the boost namespace, but it can be placed together with
|
|
the rest of the interface of the class. If you are implementing a class
|
|
inline in headers, remember to forward declare the functions.
|
|
|
|
**Warning: We are considering the removal of default implementation above. Therefore always make sure that you overload the functions for your types and do not rely on the defaults in any way.**
|
|
|
|
The Clone Allocator concept
|
|
+++++++++++++++++++++++++++
|
|
|
|
The Clone Allocator concept is introduced to formalize the way
|
|
pointer containers control memory of
|
|
the stored objects (and not the pointers to the stored objects).
|
|
The clone allocator allows
|
|
users to apply custom allocators/deallocators for the cloned objects.
|
|
|
|
More information can be found below:
|
|
|
|
.. contents:: :depth: 1
|
|
:local:
|
|
|
|
|
|
Clone Allocator requirements
|
|
----------------------------
|
|
|
|
**Notation**
|
|
|
|
===================== ============================================= ==================================================
|
|
**Type** **Object** (``const`` or non-``const``) **Describes**
|
|
``T`` ``a`` A type
|
|
``T*`` ``ptr`` A pointer to ``T``
|
|
===================== ============================================= ==================================================
|
|
|
|
**Valid expressions**
|
|
|
|
============================================== ============= ============================================================================= =============================================================
|
|
**Expression** **Type** **Semantics** **Postcondition**
|
|
``CloneAllocator::allocate_clone(a);`` ``T*`` Allocate a new object that can be considered equivalent to the
|
|
``a`` object ``typeid(*CloneAllocator::allocate_clone(a)) == typeid(a)``
|
|
``CloneAllocator::deallocate_clone(ptr);`` ``void`` Deallocate an object previously allocated with
|
|
``CloneAllocator::allocate_clone()`` or a compatible allocator.
|
|
Must not throw.
|
|
============================================== ============= ============================================================================= =============================================================
|
|
|
|
|
|
|
|
The library comes with two predefined clone allocators.
|
|
|
|
Class ``heap_clone_allocator``
|
|
------------------------------
|
|
|
|
This is the default clone allocator used by all pointer containers. For most
|
|
purposes you will never have to change this default.
|
|
|
|
**Definition**
|
|
|
|
.. parsed-literal::
|
|
|
|
namespace boost
|
|
{
|
|
struct heap_clone_allocator
|
|
{
|
|
template< class U >
|
|
static U* allocate_clone( const U& r )
|
|
{
|
|
return new_clone( r );
|
|
}
|
|
|
|
template< class U >
|
|
static void deallocate_clone( const U* r )
|
|
{
|
|
delete_clone( r );
|
|
}
|
|
};
|
|
}
|
|
|
|
Notice that the above definition allows you to support custom allocation
|
|
schemes by relying on ``new_clone()`` and ``delete_clone()``.
|
|
|
|
Class ``view_clone_allocator``
|
|
------------------------------
|
|
|
|
This class provides a way to remove ownership properties of the
|
|
pointer containers. As its name implies, this means that you can
|
|
instead use the pointer containers as a view into an existing
|
|
container.
|
|
|
|
**Definition**
|
|
|
|
.. parsed-literal::
|
|
|
|
namespace boost
|
|
{
|
|
struct view_clone_allocator
|
|
{
|
|
template< class U >
|
|
static U* allocate_clone( const U& r )
|
|
{
|
|
return const_cast<U*>(&r);
|
|
}
|
|
|
|
template< class U >
|
|
static void deallocate_clone( const U* )
|
|
{
|
|
// empty
|
|
}
|
|
};
|
|
}
|
|
|
|
.. **See also**
|
|
|
|
- `Changing the clone allocator <examples.html#changing-the-clone-allocator>`_
|
|
|
|
Class hierarchy
|
|
+++++++++++++++
|
|
|
|
The library consists of the following types of classes:
|
|
|
|
1. Pointer container adapters
|
|
|
|
..
|
|
|
|
2. Pointer containers
|
|
|
|
The pointer container adapters are used when you
|
|
want to make a pointer container starting from
|
|
your own "normal" container. For example, you
|
|
might have a map class that extends ``std::map``
|
|
in some way; the adapter class then allows you
|
|
to use your map class as a basis for a new
|
|
pointer container.
|
|
|
|
The library provides an adapter for each type
|
|
of standard container highlighted as links below:
|
|
|
|
- ``reversible_ptr_container``
|
|
|
|
- `ptr_sequence_adapter <ptr_sequence_adapter.html>`_
|
|
|
|
- ``ptr_vector``
|
|
- ``ptr_list``
|
|
- ``ptr_deque``
|
|
- ``ptr_array``
|
|
|
|
- ``associative_ptr_container``
|
|
|
|
- `ptr_set_adapter <ptr_set_adapter.html>`_
|
|
- `ptr_multiset_adapter <ptr_multiset_adapter.html>`_
|
|
- `ptr_map_adapter <ptr_map_adapter.html>`_
|
|
- `ptr_multi_map_adapter <ptr_multimap_adapter.html>`_
|
|
|
|
- ``ptr_set``
|
|
- ``ptr_multi_set``
|
|
- ``ptr_map``
|
|
- ``ptr_multimap``
|
|
|
|
|
|
The pointer containers of this library are all built using
|
|
the adapters. There is a pointer container
|
|
for each type of "normal" standard container highlighted as links below.
|
|
|
|
- ``reversible_ptr_container``
|
|
|
|
- ``ptr_sequence_adapter``
|
|
|
|
- `ptr_vector <ptr_vector.html>`_
|
|
- `ptr_list <ptr_list.html>`_
|
|
- `ptr_deque <ptr_deque.html>`_
|
|
- `ptr_array <ptr_array.html>`_
|
|
|
|
- ``associative_ptr_container``
|
|
|
|
- ``ptr_set_adapter``
|
|
- ``ptr_multiset_adapter``
|
|
- ``ptr_map_adapter``
|
|
- ``ptr_multi_map_adapter``
|
|
|
|
- `ptr_set <ptr_set.html>`_
|
|
- `ptr_multi_set <ptr_multiset.html>`_
|
|
- `ptr_map <ptr_map.html>`_
|
|
- `ptr_multimap <ptr_multimap.html>`_
|
|
|
|
Serialization
|
|
+++++++++++++
|
|
|
|
As of version 1.34.0 of Boost, the library supports
|
|
serialization via `Boost.Serialization`__.
|
|
|
|
.. __: ../../serialization/index.html
|
|
|
|
Of course, for serialization to work it is required
|
|
that the stored type itself is serializable. For maps, both
|
|
the key type and the mapped type must be serializable.
|
|
|
|
When dealing with serialization (and serialization of polymophic objects in particular),
|
|
pay special attention to these parts of Boost.Serialization:
|
|
|
|
1. Output/saving requires a const-reference::
|
|
|
|
//
|
|
// serialization helper: we can't save a non-const object
|
|
//
|
|
template< class T >
|
|
inline T const& as_const( T const& r )
|
|
{
|
|
return r;
|
|
}
|
|
...
|
|
Container cont;
|
|
|
|
std::ofstream ofs("filename");
|
|
boost::archive::text_oarchive oa(ofs);
|
|
oa << as_const(cont);
|
|
|
|
See `Compile time trap when saving a non-const value`__ for
|
|
details.
|
|
|
|
.. __: ../../serialization/doc/rationale.html#trap
|
|
|
|
2. Derived classes need to call ``base_object()`` function::
|
|
|
|
struct Derived : Base
|
|
{
|
|
template< class Archive >
|
|
void serialize( Archive& ar, const unsigned int version )
|
|
{
|
|
ar & boost::serialization::base_object<Base>( *this );
|
|
...
|
|
}
|
|
};
|
|
|
|
For details, see `Derived Classes`_.
|
|
|
|
.. _`Derived Classes`: ../../serialization/doc/tutorial.html#derivedclasses
|
|
|
|
3. You need to use ``BOOST_CLASS_EXPORT`` to register the
|
|
derived classes in your class hierarchy::
|
|
|
|
BOOST_CLASS_EXPORT( Derived )
|
|
|
|
See `Export Key`__ and `Object Tracking`_
|
|
for details.
|
|
|
|
.. __: ../../serialization/doc/traits.html#export
|
|
.. _`Object Tracking`: ../../serialization/doc/special.html
|
|
|
|
Remember these three issues and it might save you some trouble.
|
|
|
|
..
|
|
Map iterator operations
|
|
+++++++++++++++++++++++
|
|
|
|
The map iterators are a bit different compared to the normal ones. The
|
|
reason is that it is a bit clumsy to access the key and the mapped object
|
|
through i->first and i->second, and one tends to forget what is what.
|
|
Moreover, and more importantly, we also want to hide the pointer as much as possibble.
|
|
The new style can be illustrated with a small example::
|
|
|
|
typedef ptr_map<string,int> map_t;
|
|
map_t m;
|
|
m[ "foo" ] = 4; // insert pair
|
|
m[ "bar" ] = 5; // ditto
|
|
...
|
|
for( map_t::iterator i = m.begin(); i != m.end(); ++i )
|
|
{
|
|
*i += 42; // add 42 to each value
|
|
cout << "value=" << *i << ", key=" << i.key() << "n";
|
|
}
|
|
|
|
So the difference from the normal map iterator is that
|
|
|
|
- ``operator*()`` returns a reference to the mapped object (normally it returns a reference to a ``std::pair``, and
|
|
- that the key can be accessed through the ``key()`` function.
|
|
|
|
Class ``nullable``
|
|
++++++++++++++++++
|
|
|
|
The purpose of the class is simply to tell the containers
|
|
that null values should be allowed. Its definition is
|
|
trivial::
|
|
|
|
namespace boost
|
|
{
|
|
template< class T >
|
|
struct nullable
|
|
{
|
|
typedef T type;
|
|
};
|
|
}
|
|
|
|
Please notice that ``nullable`` has no effect on the containers
|
|
interface (except for ``is_null()`` functions). For example, it
|
|
does not make sense to do ::
|
|
|
|
boost::ptr_vector< boost::nullable<T> > vec;
|
|
vec.push_back( 0 ); // ok
|
|
vec.push_back( new boost::nullable<T> ); // no no!
|
|
boost::nullable<T>& ref = vec[0]; // also no no!
|
|
|
|
Exception classes
|
|
+++++++++++++++++
|
|
|
|
There are three exceptions that are thrown by this library. The exception
|
|
hierarchy looks as follows::
|
|
|
|
|
|
namespace boost
|
|
{
|
|
class bad_ptr_container_operation : public std::exception
|
|
{
|
|
public:
|
|
bad_ptr_container_operation( const char* what );
|
|
};
|
|
|
|
class bad_index : public bad_ptr_container_operation
|
|
{
|
|
public:
|
|
bad_index( const char* what );
|
|
};
|
|
|
|
class bad_pointer : public bad_ptr_container_operation
|
|
{
|
|
public:
|
|
bad_pointer();
|
|
bad_pointer( const char* what );
|
|
};
|
|
}
|
|
|
|
Disabling the use of exceptions
|
|
+++++++++++++++++++++++++++++++
|
|
|
|
As of version 1.34.0 of Boost, the library allows you to disable exceptions
|
|
completely. This means the library is more fit for domains where exceptions
|
|
are not used. Furthermore, it also speeds up a operations a little. Instead
|
|
of throwing an exception, the library simply calls `BOOST_ASSERT`__.
|
|
|
|
.. __: ../../utility/assert.html
|
|
|
|
To disable exceptions, simply define this macro before including any header::
|
|
|
|
#define BOOST_PTR_CONTAINER_NO_EXCEPTIONS 1
|
|
#include <boost/ptr_container/ptr_vector.hpp>
|
|
|
|
It is, however, recommended that you define the macro on the command-line, so
|
|
you are absolutely certain that all headers are compiled the same way. Otherwise
|
|
you might end up breaking the One Definition Rule.
|
|
|
|
If ``BOOST_NO_EXCEPTIONS`` is defined, then ``BOOST_PTR_CONTAINER_NO_EXCEPTIONS``
|
|
is also defined.
|
|
|
|
.. raw:: html
|
|
|
|
<hr>
|
|
|
|
**Navigate:**
|
|
|
|
- `home <ptr_container.html>`_
|
|
|
|
.. raw:: html
|
|
|
|
<hr>
|
|
|
|
:Copyright: Thorsten Ottosen 2004-2007. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__).
|
|
|
|
__ http://www.boost.org/LICENSE_1_0.txt
|
|
|
|
|