123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- ++++++++++++++++++++++++++++++++++
- |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
|