From 08a67ea98afa56f09cc3ff89a144563f40de964c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20J=C3=B8rgen=20Ottosen?= Date: Fri, 10 Mar 2006 09:14:55 +0000 Subject: [PATCH] doc update [SVN r33300] --- doc/associative_ptr_container.html | 307 ++++++++++++++++++++++++-- doc/conventions.html | 329 +++++++++++++++++++++++++--- doc/examples.html | 317 +++++++++++++++++++++++++-- doc/faq.html | 321 +++++++++++++++++++++++++-- doc/guidelines.html | 283 +++++++++++++++++++++++- doc/headers.html | 283 +++++++++++++++++++++++- doc/indirect_fun.html | 283 +++++++++++++++++++++++- doc/ptr_array.html | 325 +++++++++++++++++++++++++-- doc/ptr_array.rst | 11 + doc/ptr_container.html | 299 ++++++++++++++++++++++++- doc/ptr_deque.html | 323 +++++++++++++++++++++++++-- doc/ptr_deque.rst | 13 +- doc/ptr_list.html | 308 +++++++++++++++++++++++++- doc/ptr_list.rst | 6 + doc/ptr_map.html | 283 +++++++++++++++++++++++- doc/ptr_map_adapter.html | 314 +++++++++++++++++++++++++-- doc/ptr_map_adapter.rst | 8 +- doc/ptr_multimap.html | 283 +++++++++++++++++++++++- doc/ptr_multimap_adapter.html | 310 +++++++++++++++++++++++++- doc/ptr_multimap_adapter.rst | 7 +- doc/ptr_multiset.html | 283 +++++++++++++++++++++++- doc/ptr_multiset_adapter.html | 310 +++++++++++++++++++++++++- doc/ptr_multiset_adapter.rst | 9 +- doc/ptr_sequence_adapter.html | 329 ++++++++++++++++++++++++++-- doc/ptr_sequence_adapter.rst | 12 + doc/ptr_set.html | 283 +++++++++++++++++++++++- doc/ptr_set_adapter.html | 310 +++++++++++++++++++++++++- doc/ptr_set_adapter.rst | 9 +- doc/ptr_vector.html | 320 +++++++++++++++++++++++++-- doc/ptr_vector.rst | 10 +- doc/reference.html | 337 +++++++++++++++++++++++++--- doc/reversible_ptr_container.html | 338 ++++++++++++++++++++++++++--- doc/reversible_ptr_container.rst | 8 +- doc/todo.txt | 46 ++-- doc/tutorial.html | 315 +++++++++++++++++++++++++-- 35 files changed, 7208 insertions(+), 324 deletions(-) diff --git a/doc/associative_ptr_container.html b/doc/associative_ptr_container.html index 5eb6eff..e24cf22 100644 --- a/doc/associative_ptr_container.html +++ b/doc/associative_ptr_container.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

Boost Pointer Container Library

-
-

Class associative_ptr_container

+
+

Class associative_ptr_container

This section describes all the common operations for all associative pointer containers (in addition to reversible_ptr_container):

    @@ -81,10 +360,10 @@ namespace boost } // namespace 'boost'
-
-

Semantics

-
-

Semantics: typedefs

+
+

Semantics

+
+

Semantics: typedefs

  • typedef ... key_type;

    @@ -112,8 +391,8 @@ given ptr_set<T>
-
-

Semantics: observers

+
+

Semantics: observers

  • key_compare key_comp() const;

  • @@ -126,8 +405,8 @@ given ptr_set<T>
-
-

Semantics: modifiers

+
+

Semantics: modifiers

  • template< typename InputIterator > void insert( InputIterator first, InputIterator last );

    @@ -182,8 +461,8 @@ given ptr_set<T>
-
-

Semantics: algorithms

+
+

Semantics: algorithms

  • iterator       find( const Key& x );

  • diff --git a/doc/conventions.html b/doc/conventions.html index 11a4dcc..78fb469 100644 --- a/doc/conventions.html +++ b/doc/conventions.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
    @@ -14,7 +293,7 @@

    There are a few design decisions that will affect how the classes are used. Besides these the classes are much like normal standard containers and provides almost the same interface. The new conventions are:

    -
    + -
    -

    Null pointers are not allowed by default

    +
    +

    Null pointers are not allowed by default

    If the user tries to insert the null pointer, the operation will throw a bad_pointer exception (see Example 1).

    Use nullable to allow null pointers.

    @@ -45,8 +324,8 @@ boost::ptr_vector< boost::nullable<animal> > vec; vec.push_back( 0 ); // ok
    -
    -

    All default iterators apply an extra layer of indirection

    +
    +

    All default iterators apply an extra layer of indirection

    This is done to make the containers easier and safer to use. It promotes a kind of pointer-less programming and the user of a class needs not worry about @@ -56,58 +335,58 @@ useful in rare cases. For example, whenever ptr_begin() will return an iterator that allows one to iterate over the stored pointers.

    -
    -

    All comparison operations are done on the pointed to objects and not at the pointer level

    +
    +

    All comparison operations are done on the pointed to objects and not at the pointer level

    For example, in ptr_set<T> the ordering is by default done by boost::ptr_less<T> which compares the indirected pointers. Similarly, operator==() for container<Foo> compares all objects with operator==(const Foo&, const Foo&).

    -
    -

    The containers are neither Copy Constructible nor Assignable

    +
    +

    The containers are neither Copy Constructible nor Assignable

    This is because cloning a lot of pointers can be a very expensive operation; instead functions are provided to transfer ownership. If a deep-copy is needed anyway, every container has a clone() member function (see Example 3).

    -
    -

    Stored elements are required to be Clonable for a subset of the operations

    +
    +

    Stored elements are required to be Clonable for a subset of the operations

    This is because most polymorphic objects cannot be copied directly, but they can often be so by a use of a member function (see Example 4). Often it does not even make sense to clone an object in which case a large subset of the operations are still workable.

    -
    -

    Whenever objects are inserted into a container, they are cloned before insertion

    +
    +

    Whenever objects are inserted into a container, they are cloned before insertion

    This is necessary because all pointer containers take ownerships of stored objects (see Example 5).

    -
    -

    Whenever pointers are inserted into a container, ownership is transferred to the container

    +
    +

    Whenever pointers are inserted into a container, ownership is transferred to the container

    All containers take ownership of the stored pointers and therefore a container needs to have its own copies (see Example 5).

    -
    -

    Ownership can be transferred from a container on a per pointer basis

    +
    +

    Ownership can be transferred from a container on a per pointer basis

    This can of course also be convenient. Whenever it happens, an SmartContainer::auto_type object is used to provide an exception-safe transfer (see Example 6).

    -
    -

    Ownership can be transferred from a container to another container on a per iterator range basis

    +
    +

    Ownership can be transferred from a container to another container on a per iterator range basis

    This makes it possible to exchange data safely between different pointer containers without cloning the objects again (see Example 7).

    -
    -

    A container can be cheaply returned from functions either by making a clone or by giving up ownership of the container

    +
    +

    A container can be cheaply returned from functions either by making a clone or by giving up ownership of the container

    Two special member functions, clone() and release(), both return an auto_ptr<SmartContainer> which can be assigned to another pointer container. This effectively reduces the cost of returning a container to one heap-allocation plus a call to swap() (see Example 3).

    -
    -

    Iterators are invalidated as in the corresponding standard container

    +
    +

    Iterators are invalidated as in the corresponding standard container

    Because the containers in this library wrap standard containers, the rules for invalidation of iterators are the same as the rules of the corresponding standard container.

    diff --git a/doc/examples.html b/doc/examples.html index 9847fd0..7840b5b 100644 --- a/doc/examples.html +++ b/doc/examples.html @@ -3,16 +3,295 @@ - + Boost Pointer Container Library - +

    Boost Pointer Container Library

    Examples

    Some examples are given here and in the accompanying test files:

    -
    + -
    -

    1. Null pointers cannot be stored in the containers

    +
    +

    1. Null pointers cannot be stored in the containers

     my_container.push_back( 0 );            // throws bad_ptr 
     my_container.replace( an_iterator, 0 ); // throws bad_ptr
     my_container.insert( an_iterator, 0 );  // throws bad_ptr                                                                 
     
    -
    -

    2. Iterators and other operations return indirected values

    +
    +

    2. Iterators and other operations return indirected values

     ptr_vector<X> pvec; 
     std::vector<X*> vec;
    @@ -45,8 +324,8 @@ pvec.begin()->foo();     // no indirection needed
     pvec.front()  = X();     // no indirection needed
     
    -
    -

    3. Copy-semantics of pointer containers

    +
    +

    3. Copy-semantics of pointer containers

     ptr_vector<T> vec1; 
     ...
    @@ -57,8 +336,8 @@ vec1 = vec2;                        // compile time error: 'operator=()' not def
     ptr_vector<T> vec3( vec1 );         // compile time error: copy-constructor not defined 
     
    -
    -

    4. Making a non-copyable type Clonable

    +
    +

    4. Making a non-copyable type Clonable

      // a class that has no normal copy semantics
     class X : boost::noncopyable { public: X* clone() const; ... };
    @@ -74,8 +353,8 @@ vec2 = vec1.clone();                                 // 'clone()' requires cloni
     vec2.insert( vec2.end(), vec1.begin(), vec1.end() ); // inserting always means inserting clones 
     
    -
    -

    5. Objects are cloned before insertion, inserted pointers are owned by the container

    +
    +

    5. Objects are cloned before insertion, inserted pointers are owned by the container

     class X { ... };                     // assume 'X' is Clonable 
     X x;                                 // and 'X' can be stack-allocated 
    @@ -86,8 +365,8 @@ list.push_back( new X );             // always give the pointer directly to the
     list.push_back( &x );                // don't do this!!! 
     
    -
    -

    6. Transferring ownership of a single element

    +
    +

    6. Transferring ownership of a single element

     ptr_deque<T>                    deq; 
     typedef ptr_deque<T>::auto_type auto_type;
    @@ -99,8 +378,8 @@ auto_type ptr2 = deq.release( deq.begin() + 2 ); // use an iterator to determine
     ptr            = deq.release_front();            // supported for 'ptr_list' and 'ptr_deque'
     
    -
    -

    7. Transferring ownership of pointers between different pointer containers

    +
    +

    7. Transferring ownership of pointers between different pointer containers

     ptr_list<X> list; ptr_vector<X> vec;
     ...
    @@ -111,8 +390,8 @@ list.transfer( list.begin(), vec.begin(), vec );           // make the first ele
     vec.transfer( vec.end(), list.begin(), list.end(), list ); // put all the lists element into the vector                                 
     
    -
    -

    8. Selected test files

    +
    +

    8. Selected test files

    diff --git a/doc/faq.html b/doc/faq.html index 26eaa63..07b8540 100644 --- a/doc/faq.html +++ b/doc/faq.html @@ -3,15 +3,294 @@ - +Boost Pointer Container Library - +

    Boost Pointer Container Library

    FAQ

    -
    + -
    -

    Since a pointer container is not Copy Constructible and Assignable, I cannot put them into standard containers; what do I do?

    + -
    -

    Calling assign() is very costly and I do not really need to store cloned objects; I merely need to overwrite the existing ones; what do I do?

    + -
    -

    Which mutating algorithms are safe to use with pointers?

    +
    +

    Which mutating algorithms are safe to use with pointers?

    Any mutating algorithm that moves elements around by swapping them. An important example is std::sort(); examples of unsafe algorithms are std::unique() and std::remove().

    -
    -

    Why does ptr_map<T>::insert()/replace() take two arguments (the key and the pointer) instead of one std::pair? And why is the key passed by non-const reference?

    +
    +

    Why does ptr_map<T>::insert()/replace() take two arguments (the key and the pointer) instead of one std::pair? And why is the key passed by non-const reference?

    This is the only way the function can be implemented in an exception-safe manner; since the copy-constructor of the key might throw, and since function arguments are not guaranteed to be evaluated from left to right, we need to ensure that evaluating the first argument does not throw. Passing the key as a reference achieves just that.

    -
    -

    When instantiating a pointer container with a type T, is T then allowed to be incomplete at that point?

    +
    +

    When instantiating a pointer container with a type T, is T then allowed to be incomplete at that point?

    No. This is a distinct property of shared_ptr which implies some overhead.

    However, one can leave T incomplete in the header file:

    @@ -68,14 +347,14 @@ class X { ptr_deque<Foo> container; ... }
     ...
     
    -
    -

    Why do iterator-range inserts give the strong exception-safety guarantee?

    +
    +

    Why do iterator-range inserts give the strong exception-safety guarantee?

    Is this not very inefficient? It is because it is actually affordable to do so; the overhead is one heap-allocation which is relatively small compared to cloning N objects.

    -
    -

    What is the polymorphic class problem?

    +
    +

    What is the polymorphic class problem?

    The problem refers to the relatively troublesome way C++ supports Object Oriented programming in connection with containers of pointers to polymorphic objects. In a language without garbage collection, you end up @@ -83,8 +362,8 @@ using either a container of pointer pointers or a container that takes ownership of the pointers. The hard part is to find a safe, fast and elegant solution.

    -
    -

    Are the pointer containers faster and do they have a better memory footprint than a container of pointer pointers?

    +
    +

    Are the pointer containers faster and do they have a better memory footprint than a container of pointer pointers?

    The short answer is yes: they are faster and they do use less memory; in fact, they are the only way to obtain the zero-overhead hallmark of C++. Smart pointers usually have one word or more of memory overhead per @@ -94,8 +373,8 @@ your objects are big, then the memory overhead is often negligible, but if you have many small objects, it is not. Further reading can be found in these references: [11] and [12].

    -
    -

    When the stored pointers cannot be 0, how do I allow this "empty" behavior anyway?

    +
    +

    When the stored pointers cannot be 0, how do I allow this "empty" behavior anyway?

    Storing a null-pointer among a list of pointers does not fit well into the Object Oriented paradigm. The most elegant design is to use the Null-Object Pattern where one basically makes a concrete class with dummy implementations of the virtual functions. See [13] for details.

    diff --git a/doc/guidelines.html b/doc/guidelines.html index 8ac18cf..fbb2147 100644 --- a/doc/guidelines.html +++ b/doc/guidelines.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
    diff --git a/doc/headers.html b/doc/headers.html index 91cdc73..a952110 100644 --- a/doc/headers.html +++ b/doc/headers.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
    diff --git a/doc/indirect_fun.html b/doc/indirect_fun.html index 5878a50..d701193 100644 --- a/doc/indirect_fun.html +++ b/doc/indirect_fun.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
    diff --git a/doc/ptr_array.html b/doc/ptr_array.html index ca0e288..307fee9 100644 --- a/doc/ptr_array.html +++ b/doc/ptr_array.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

    Boost Pointer Container Library

    -
    -

    Class ptr_array

    +
    +

    Class ptr_array

    A ptr_array<T,size> is a pointer container that uses an underlying boost::array<void*,size> to store the pointers. The class is useful when there is no requirement of dynamic expansion and when absolute no overhead is tolerable.

    @@ -68,7 +347,11 @@ namespace boost template< size_t idx > auto_type replace( T* r ); + template< size_t idx, class U > + auto_type replace( std::auto_ptr<U> r ); auto_type replace( size_t idx, T* r ); + template< class U > + auto_type replace( size_t idx, std::auto_ptr<U> r ); public: // pointer container requirements std::auto_ptr<ptr_array> clone() const; @@ -82,10 +365,10 @@ namespace boost } // namespace 'boost'
    -
    -

    Semantics

    -
    -

    Semantics: construct/copy/destroy

    +
    +

    Semantics

    +
    +

    Semantics: construct/copy/destroy

    • ptr_array();

      @@ -103,8 +386,8 @@ namespace boost
    -
    -

    Semantics: element access

    +
    +

    Semantics: element access

    • T&       front();

    • @@ -163,8 +446,8 @@ namespace boost
    -
    -

    Semantics: modifiers

    +
    +

    Semantics: modifiers

    • void swap( ptr_array& r );

      @@ -195,6 +478,13 @@ namespace boost
    +
  • template< size_t idx, class U > auto_type replace( std::auto_ptr<U> r );

    +
    +
      +
    • Effects: return replace<idx>( r.release() );
    • +
    +
    +
  • auto_type replace( size_t idx, T* r );

      @@ -205,10 +495,17 @@ namespace boost
  • +
  • template< class U > auto_type replace( size_t idx, std::auto_ptr<U> r );

    +
    +
      +
    • Effects: return replace( idx, r.release() );
    • +
    +
    +
  • -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • std::auto_ptr<ptr_array>  clone() const;

      diff --git a/doc/ptr_array.rst b/doc/ptr_array.rst index 5b9e451..a717fcb 100755 --- a/doc/ptr_array.rst +++ b/doc/ptr_array.rst @@ -72,7 +72,11 @@ of dynamic expansion and when absolute no overhead is tolerable. template< size_t idx > auto_type replace( T* r ); + template< size_t idx, class U > + auto_type replace( std::auto_ptr r ); auto_type replace( size_t idx, T* r ); + template< class U > + auto_type replace( size_t idx, std::auto_ptr r ); public: // `pointer container requirements`_ std::auto_ptr clone() const; @@ -186,6 +190,10 @@ Semantics: modifiers - Throws: ``bad_pointer`` if ``x == 0``. - Exception safety: Strong guarantee + +- ``template< size_t idx, class U > auto_type replace( std::auto_ptr r );`` + + - Effects: ``return replace( r.release() );`` - ``auto_type replace( size_t idx, T* r );`` @@ -197,7 +205,10 @@ Semantics: modifiers - Exception safety: Strong guarantee +- ``template< class U > auto_type replace( size_t idx, std::auto_ptr r );`` + - Effects: ``return replace( idx, r.release() );`` + .. _`pointer container requirements`: Semantics: pointer container requirements diff --git a/doc/ptr_container.html b/doc/ptr_container.html index cd7d0d3..8170fe9 100644 --- a/doc/ptr_container.html +++ b/doc/ptr_container.html @@ -3,12 +3,291 @@ - + Boost Pointer Container Library - +
      @@ -29,8 +308,8 @@
    Thorsten Ottosen 2004-2005. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt).
    -
    -

    Overview

    +
    +

    Overview

    Boost.Pointer Container provides containers for holding heap-allocated objects in an exception-safe manner and with minimal overhead. The aim of the library is in particular to make OO programming @@ -71,8 +350,8 @@ and designs for dealing with OO specific problems

  • References
-
-

Motivation

+
+

Motivation

Whenever a programmer wants to have a container of pointers to heap-allocated objects, there is usually only one exception-safe way: to make a container of pointer pointers like boost::shared_ptr. @@ -105,8 +384,8 @@ now it is possible for pop_back()

  • Less flexible than containers of smart pointers like boost::shared_ptr
  • -
    -

    Acknowledgements

    +
    +

    Acknowledgements

    The following people have been very helpful:

    • Bjørn D. Rasmussen for unintentionally motivating me to start this library
    • @@ -124,8 +403,8 @@ which is used internally
    • Pavel Chikulaev for comments and bug-fixes
    -
    -

    References

    +
    +

    References

    diff --git a/doc/ptr_deque.html b/doc/ptr_deque.html index a658cb1..964c7c8 100644 --- a/doc/ptr_deque.html +++ b/doc/ptr_deque.html @@ -3,15 +3,294 @@ - +Boost Pointer Container Library - +

    Boost Pointer Container Library

    -
    -

    Class ptr_deque

    +
    +

    Class ptr_deque

    A ptr_deque<T> is a pointer container that uses an underlying std:deque<void*> to store the pointers.

    See also:

    @@ -51,10 +330,14 @@ namespace boost public: // modifiers void push_front( T* x ); + template< class U > + void push_front( std::auto_ptr<U> x ); auto_type pop_front(); public: // pointer container requirements - auto_type replace( size_type idx, T* x ); + auto_type replace( size_type idx, T* x ); + template< class U > + auto_type replace( size_type idx, std::auto_ptr<U> x ); bool is_null( size_type idx ) const; }; @@ -62,10 +345,10 @@ namespace boost } // namespace 'boost'
    -
    -

    Semantics

    -
    -

    Semantics: modifiers

    +
    +

    Semantics

    +
    +

    Semantics: modifiers

    • void push_front( T* x );

      @@ -77,6 +360,13 @@ namespace boost
    +
  • template< class U > void push_front( std::auto_ptr<U> x );

    +
    +
      +
    • Effects: push_front( x.release() );
    • +
    +
    +
  • -
    -

    Semantics: lookup

    +
    +

    Semantics: lookup

    • T& operator[]( const key_type& key );

      @@ -105,8 +393,8 @@ namespace boost
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • bool transfer( iterator object, ptr_map_adapter& from );

      diff --git a/doc/ptr_map_adapter.rst b/doc/ptr_map_adapter.rst index 0555cbc..4d51b17 100755 --- a/doc/ptr_map_adapter.rst +++ b/doc/ptr_map_adapter.rst @@ -44,7 +44,9 @@ of the interface from ``associative_ptr_container``. { public: // `modifiers`_ - std::pair insert( key_type& k, value_type x ); + std::pair insert( key_type& k, T* x ); + template< class U > + std::pair insert( const key_type& k, std::auto_ptr x ); public; // `lookup`_ T& operator[]( const key_type& key ); @@ -82,6 +84,10 @@ Semantics: modifiers - Exception safety: Strong guarantee +- ``template< class U > std::pair insert( const key_type& k, std::auto_ptr x );`` + + - Equivalent to (but without the ``const_cast``): ``return insert( const_cast(k), x.release() );`` + .. - ``std::pair insert( key_type& k, const_reference x );`` diff --git a/doc/ptr_multimap.html b/doc/ptr_multimap.html index 6275f9e..f99cbdf 100644 --- a/doc/ptr_multimap.html +++ b/doc/ptr_multimap.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
      diff --git a/doc/ptr_multimap_adapter.html b/doc/ptr_multimap_adapter.html index 89a4ff5..4e70626 100644 --- a/doc/ptr_multimap_adapter.html +++ b/doc/ptr_multimap_adapter.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

      Boost Pointer Container Library

      -
      -

      Class ptr_multimap_adapter

      +
      +

      Class ptr_multimap_adapter

      This class is used to build custom pointer containers with an underlying multimap-like container. The interface of the class is an extension of the interface from associative_ptr_container.

      @@ -41,7 +320,9 @@ namespace boost { public: // modifiers - iterator insert( key_type& k, T* x ); + iterator insert( key_type& k, T* x ); + template< class U > + iterator insert( const key_type&, std::auto_ptr<U> x ); public: // pointer container requirements void transfer( iterator object, ptr_multimap_adapter& from ); @@ -55,10 +336,10 @@ namespace boost } // namespace 'boost'
      -
      -

      Semantics

      -
      -

      Semantics: modifiers

      +
      +

      Semantics

      +
      +

      Semantics: modifiers

      • iterator insert( key_type& k, T* x );

        @@ -70,6 +351,13 @@ namespace boost
    • +
    • template< class U > iterator insert( const key_type& k, std::auto_ptr<U> x );

      +
      +
        +
      • Equivalent to (but without the const_cast): return insert( const_cast<key_type&>(k), x.release() );
      • +
      +
      +
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • void transfer( iterator object, ptr_multimap_adapter& from );

      diff --git a/doc/ptr_multimap_adapter.rst b/doc/ptr_multimap_adapter.rst index 9f1c18c..70512c3 100755 --- a/doc/ptr_multimap_adapter.rst +++ b/doc/ptr_multimap_adapter.rst @@ -45,7 +45,9 @@ __ ptr_container.html#map-iterator-operations { public: // `modifiers`_ - iterator insert( key_type& k, T* x ); + iterator insert( key_type& k, T* x ); + template< class U > + iterator insert( const key_type&, std::auto_ptr x ); public: // `pointer container requirements`_ void transfer( iterator object, ptr_multimap_adapter& from ); @@ -77,6 +79,9 @@ Semantics: modifiers - Exception safety: Strong guarantee +- ``template< class U > iterator insert( const key_type& k, std::auto_ptr x );`` + + - Equivalent to (but without the ``const_cast``): ``return insert( const_cast(k), x.release() );`` .. - ``iterator insert( key_type& k, const_reference x );`` diff --git a/doc/ptr_multiset.html b/doc/ptr_multiset.html index ea74a77..a6ba240 100644 --- a/doc/ptr_multiset.html +++ b/doc/ptr_multiset.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
      diff --git a/doc/ptr_multiset_adapter.html b/doc/ptr_multiset_adapter.html index 57505b5..e07508b 100644 --- a/doc/ptr_multiset_adapter.html +++ b/doc/ptr_multiset_adapter.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

      Boost Pointer Container Library

      -
      -

      Class ptr_multiset_adapter

      +
      +

      Class ptr_multiset_adapter

      This class is used to build custom pointer containers with an underlying multiset-like container. The interface of the class is an extension of the interface from associative_ptr_container.

      @@ -40,7 +319,9 @@ namespace boost { public: // modifiers - iterator insert( Key* x ); + iterator insert( Key* x ); + template< class Key2 > + iterator insert( std::auto_ptr<Key2> x ); public: // pointer container requirements void transfer( iterator object, ptr_multiset_adapter& from ); @@ -54,10 +335,10 @@ namespace boost } // namespace 'boost'
      -
      -

      Semantics

      -
      -

      Semantics: modifiers

      +
      +

      Semantics

      +
      +

      Semantics: modifiers

      • iterator insert( key_type* x );

        @@ -69,6 +350,13 @@ namespace boost
    • +
    • template< class Key2 > iterator insert( std::auto_ptr<Key2> x );

      +
      +
        +
      • Effects: return insert( x.release() );
      • +
      +
      +
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • void transfer( iterator object, ptr_multiset_adapter& from );

      diff --git a/doc/ptr_multiset_adapter.rst b/doc/ptr_multiset_adapter.rst index 443d3cc..2a64c5f 100755 --- a/doc/ptr_multiset_adapter.rst +++ b/doc/ptr_multiset_adapter.rst @@ -43,7 +43,9 @@ of the interface from ``associative_ptr_container``. { public: // `modifiers`_ - iterator insert( Key* x ); + iterator insert( Key* x ); + template< class Key2 > + iterator insert( std::auto_ptr x ); public: // `pointer container requirements`_ void transfer( iterator object, ptr_multiset_adapter& from ); @@ -75,6 +77,11 @@ Semantics: modifiers - Exception safety: Strong guarantee + +- ``template< class Key2 > iterator insert( std::auto_ptr x );`` + + - Effects: ``return insert( x.release() );`` + .. - ``iterator insert( const key_type& x );`` diff --git a/doc/ptr_sequence_adapter.html b/doc/ptr_sequence_adapter.html index 4f4af2d..93ac4fd 100644 --- a/doc/ptr_sequence_adapter.html +++ b/doc/ptr_sequence_adapter.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

      Boost Pointer Container Library

      -
      -

      Class ptr_sequence_adapter

      +
      +

      Class ptr_sequence_adapter

      This section describes all the common operations for all the pointer sequences:

        @@ -57,8 +336,12 @@ namespace boost public: // modifiers void push_back( T* x ); + template< class U > + void push_back( std::auto_ptr<U> x ); auto_type pop_back(); iterator insert( iterator position, T* x ); + template< class U > + iterator insert( iterator position, std::auto_ptr<U> x ); template< class InputIterator > void insert( iterator position, InputIterator first, InputIterator last ); template< class InputRange > @@ -117,10 +400,10 @@ namespace boost } // namespace 'boost'
      -
      -

      Semantics

      -
      -

      Semantics: construct/copy/destroy

      +
      +

      Semantics

      +
      +

      Semantics: construct/copy/destroy

      • template< class InputIterator > void assign( InputIterator first, InputIterator last );

        @@ -163,8 +446,8 @@ Postconditions: size() == sz Exception safety: Strong guarantee -->
      -
      -

      Semantics: element access

      +
      +

      Semantics: element access

      • T& front();

        @@ -204,8 +487,8 @@ Exception safety: Strong guarantee -->
      -
      -

      Semantics: modifiers

      +
      +

      Semantics: modifiers

      • void push_back( T* x );

        @@ -217,6 +500,13 @@ Exception safety: Strong guarantee -->
    • +
    • template< class U > void push_back( std::auto_ptr<U> x );

      +
      +
        +
      • Effects: push_back( x.release() );
      • +
      +
      +
    +
  • template< class U > iterator insert( iterator position, std::auto_ptr<U> x );

    +
    +
      +
    • Effects: return insert( position, x.release() );
    • +
    +
    +
  • -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    You cannot use transfer() to move elements between two different types of containers. This is to avoid problems with different allocators. The requirement might be @@ -357,8 +654,8 @@ takes place before before<

    -
    -

    Semantics: algorithms

    +
    +

    Semantics: algorithms

    The general requirement for these algorithms is that the container does not contain any nulls.

      diff --git a/doc/ptr_sequence_adapter.rst b/doc/ptr_sequence_adapter.rst index 2497536..a8dd651 100755 --- a/doc/ptr_sequence_adapter.rst +++ b/doc/ptr_sequence_adapter.rst @@ -63,8 +63,12 @@ __ reversible_ptr_container.html public: // `modifiers`_ void push_back( T* x ); + template< class U > + void push_back( std::auto_ptr x ); auto_type pop_back(); iterator insert( iterator position, T* x ); + template< class U > + iterator insert( iterator position, std::auto_ptr x ); template< class InputIterator > void insert( iterator position, InputIterator first, InputIterator last ); template< class InputRange > @@ -230,6 +234,10 @@ Semantics: modifiers - Exception safety: Strong guarantee +- ``template< class U > void push_back( std::auto_ptr x );`` + + - Effects: ``push_back( x.release() );`` + .. - ``void push_back( const T& x );`` @@ -260,6 +268,10 @@ Semantics: modifiers - Throws: ``bad_pointer`` if ``x == 0`` - Exception safety: Strong guarantee + +- ``template< class U > iterator insert( iterator position, std::auto_ptr x );`` + + - Effects: ``return insert( position, x.release() );`` .. - ``iterator insert( iterator position, const T& x );`` diff --git a/doc/ptr_set.html b/doc/ptr_set.html index 82fcee9..c509c87 100644 --- a/doc/ptr_set.html +++ b/doc/ptr_set.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
      diff --git a/doc/ptr_set_adapter.html b/doc/ptr_set_adapter.html index 95696ee..6cfe7d0 100644 --- a/doc/ptr_set_adapter.html +++ b/doc/ptr_set_adapter.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

      Boost Pointer Container Library

      -
      -

      Class ptr_set_adapter

      +
      +

      Class ptr_set_adapter

      This class is used to build custom pointer containers with an underlying set-like container. The interface of the class is an extension of the interface from associative_ptr_container.

      @@ -40,7 +319,9 @@ namespace boost { public: // modifiers - std::pair<iterator,bool> insert( Key* x ); + std::pair<iterator,bool> insert( Key* x ); + template< class Key2 > + std::pair<iterator,bool> insert( std::auto_ptr<Key2> x ); public: // pointer container requirements bool transfer( iterator object, ptr_set_adapter& from ); @@ -54,10 +335,10 @@ namespace boost } // namespace 'boost'
      -
      -

      Semantics

      -
      -

      Semantics: modifiers

      +
      +

      Semantics

      +
      +

      Semantics: modifiers

      • std::pair<iterator,bool> insert( key_type* x );

        @@ -69,6 +350,13 @@ namespace boost
      +
    • template< class Key2 > std::pair<iterator,bool>  insert( std::auto_ptr<Key2> x );

      +
      +
        +
      • Effects: return insert( x.release() );
      • +
      +
      +
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • bool transfer( iterator object, ptr_set_adapter& from );

      diff --git a/doc/ptr_set_adapter.rst b/doc/ptr_set_adapter.rst index 731c04b..acd1d61 100755 --- a/doc/ptr_set_adapter.rst +++ b/doc/ptr_set_adapter.rst @@ -43,7 +43,9 @@ of the interface from ``associative_ptr_container``. { public: // `modifiers`_ - std::pair insert( Key* x ); + std::pair insert( Key* x ); + template< class Key2 > + std::pair insert( std::auto_ptr x ); public: // `pointer container requirements`_ bool transfer( iterator object, ptr_set_adapter& from ); @@ -74,6 +76,11 @@ Semantics: modifiers - Throws: bad_pointer if ``x == 0`` - Exception safety: Strong guarantee + +- ``template< class Key2 > std::pair insert( std::auto_ptr x );`` + + - Effects: ``return insert( x.release() );`` + .. - ``std::pair insert( const key_type& x );`` diff --git a/doc/ptr_vector.html b/doc/ptr_vector.html index 1adfea5..3bc6702 100644 --- a/doc/ptr_vector.html +++ b/doc/ptr_vector.html @@ -3,15 +3,294 @@ - + Boost Pointer Container Library - +

      Boost Pointer Container Library

      -
      -

      Class ptr_vector

      +
      +

      Class ptr_vector

      A ptr_vector<T> is a pointer container that uses an underlying std::vector<void*> to store the pointers.

      See also:

      @@ -57,17 +336,19 @@ namespace boost const T& at( size_type n ) const; public: // pointer container requirements - auto_type replace( size_type idx, T* x ); + auto_type replace( size_type idx, T* x ); + template< class U > + auto_type replace( size_type idx, std::auto_ptr<U> x ); bool is_null( size_type idx ) const; }; } // namespace 'boost'
      -
      -

      Semantics

      -
      -

      Semantics: construction

      +
      +

      Semantics

      +
      +

      Semantics: construction

      • ptr_vector( size_type to_reserve );

        @@ -79,8 +360,8 @@ of size least to_reserve
      -
      -

      Semantics: capacity

      +
      +

      Semantics: capacity

      • size_type capacity() const;

        @@ -102,8 +383,8 @@ of size least to_reserve
      -
      -

      Semantics: element access

      +
      +

      Semantics: element access

      • T& operator[]( size_type n );

      • @@ -123,14 +404,14 @@ of size least to_reserve
      • Requirements: n < size()
      • Effects: Returns a reference to the n'th element
      • -
      • Throws: bad_index if n >=size()
      • +
      • Throws: bad_index if n >= size()
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • auto_type replace( size_type idx, T* x );

      @@ -142,6 +423,13 @@ of size least to_reserve
    • +
    • template< class U > auto_type replace( size_type idx, std::auto_ptr<U> x );

      +
      +
        +
      • Effects: return replace( idx, x.release() );
      • +
      +
      +
    • bool is_null( size_type idx ) const;

        diff --git a/doc/ptr_vector.rst b/doc/ptr_vector.rst index 8515ddb..5ffd1fd 100755 --- a/doc/ptr_vector.rst +++ b/doc/ptr_vector.rst @@ -59,7 +59,9 @@ to store the pointers. const T& at( size_type n ) const; public: // `pointer container requirements`_ - auto_type replace( size_type idx, T* x ); + auto_type replace( size_type idx, T* x ); + template< class U > + auto_type replace( size_type idx, std::auto_ptr x ); bool is_null( size_type idx ) const; }; @@ -122,7 +124,7 @@ Semantics: element access - Effects: Returns a reference to the ``n``'th element - - Throws: ``bad_index`` if ``n >=size()`` + - Throws: ``bad_index`` if ``n >= size()`` .. _`pointer container requirements`: @@ -140,6 +142,10 @@ Semantics: pointer container requirements - Exception safety: Strong guarantee +- ``template< class U > auto_type replace( size_type idx, std::auto_ptr x );`` + + - Effects: ``return replace( idx, x.release() );`` + - ``bool is_null( size_type idx ) const;`` - Requirements: ``idx < size()`` diff --git a/doc/reference.html b/doc/reference.html index c6c7c2e..9e38297 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
        @@ -50,8 +329,8 @@ the Clone
      • Class nullable
      • Exception classes
      -
      -

      The Clonable concept

      +
      +

      The Clonable concept

      Refinement of

      • Copy Constructible
      • @@ -105,8 +384,8 @@ the containers does not even require the stored type to be Clonable.

    -
    -

    Default implementation

    +
    +

    Default implementation

    In the <boost/ptr_container/clone_allocator.hpp> header a default implementation of the two functions is given:

    @@ -136,23 +415,23 @@ the rest of the interface of the class.  If you are implementing a class
     inline in headers, remember to forward declare the functions.

    -
    -

    The Clone Allocator concept

    +
    +

    The Clone Allocator concept

    The Clone Allocator concept is introduced to formalize the way pointer containers controls 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:

    -
    + -
    -

    Clone Allocator requirements

    +
    +

    Clone Allocator requirements

    Notation

    @@ -199,8 +478,8 @@ users to apply custom allocators/deallocators for the cloned objects.

    The library comes with two predefined clone allocators.

    -
    -

    Class heap_clone_allocator

    +
    +

    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

    @@ -226,8 +505,8 @@ namespace boost

    Notice that the above definition allows you to support custom allocation schemes by relying on new_clone() and delete_clone().

    -
    -

    Class view_clone_allocator

    +
    +

    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 @@ -258,8 +537,8 @@ namespace boost

    -
    -

    Pointer container adapters

    +
    +

    Pointer container adapters

    The pointer container adapters are used when you want to make a pointer container starting from your own "normal" container. For example, you @@ -277,13 +556,13 @@ of standard container:

  • ptr_multimap_adapter
  • -
    -

    Pointer containers

    +
    +

    Pointer containers

    The pointer containers of this library are all built using the pointer container adapters. There is a pointer container for each type of "normal" standard container:

    -
    -

    Sequence containers

    +
    +

    Sequence containers

    • ptr_vector
    • @@ -293,8 +572,8 @@ for each type of "normal" standard container:

    -
    -

    Associative containers

    +
    +

    Associative containers

    • ptr_set
    • @@ -305,8 +584,8 @@ for each type of "normal" standard container:

    -
    -

    Map iterator operations

    +
    +

    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. @@ -330,8 +609,8 @@ for( map_t::iterator i = m.begin(); i != m.end(); ++i )

  • that the key can be accessed through the key() function.
  • -
    -

    Class nullable

    +
    +

    Class nullable

    The purpose of the class is simply to tell the containers that null values should be allowed. Its definition is trivial:

    @@ -354,8 +633,8 @@ vec.push_back( new boost::nullable<T> ); // no no boost::nullable<T>& ref = vec[0]; // also no no
    -
    -

    Exception classes

    +
    +

    Exception classes

    There are three exceptions that are thrown by this library. The exception hierarchy looks as follows:

    diff --git a/doc/reversible_ptr_container.html b/doc/reversible_ptr_container.html
    index 510983d..e86d070 100644
    --- a/doc/reversible_ptr_container.html
    +++ b/doc/reversible_ptr_container.html
    @@ -3,15 +3,294 @@
     
     
     
    -
    +
     Boost Pointer Container Library
    -
    +
     
     
     

    Boost Pointer Container Library

    -
    -

    Class reversible_ptr_container

    +
    +

    Class reversible_ptr_container

    This class is not a real class that can be found in the library. Its purpose is to present the general interface of all the pointer containers.

    Navigate:

    @@ -74,7 +353,9 @@ namespace boost public: // pointer container requirements - auto_type replace( iterator position, T* x ); + auto_type replace( iterator position, T* x ); + template< class U > + auto_type replace( iterator position, std::auto_ptr<U> x ); std::auto_ptr<reversible_ptr_container> clone() const; std::auto_ptr<reversible_ptr_container> release(); auto_type release( iterator position ); @@ -122,10 +403,10 @@ namespace boost } // namespace 'boost'
    -
    -

    Semantics

    -
    -

    Semantics: typedefs

    +
    +

    Semantics

    +
    +

    Semantics: typedefs

    Notice how these two types differ:

    • typedef T* value_type;

      @@ -175,8 +456,8 @@ T* release();

      The destructor will delete the stored object. It might help to think it is just an std::auto_ptr<T>.

    -
    -

    Semantics: construct/copy/destroy

    +
    +

    Semantics: construct/copy/destroy

    • reversible_ptr_container();

      @@ -235,8 +516,8 @@ think it is just an std::auto_ptr
    -
    -

    Semantics: iterators

    +
    +

    Semantics: iterators

    See also: iterator invalidation

    • iterator begin();

      @@ -281,8 +562,8 @@ think it is just an std::auto_ptr
    -
    -

    Semantics: capacity

    +
    +

    Semantics: capacity

    • size_type size() const;

      @@ -310,8 +591,8 @@ think it is just an std::auto_ptr
    -
    -

    Semantics: modifiers

    +
    +

    Semantics: modifiers

    • void swap( reversible_ptr_container& r );

      @@ -332,8 +613,8 @@ think it is just an std::auto_ptr
    -
    -

    Semantics: pointer container requirements

    +
    +

    Semantics: pointer container requirements

    • auto_type replace( iterator position, T* x );

      @@ -345,6 +626,13 @@ think it is just an std::auto_ptr
    +
  • template<class U> auto_type replace( iterator position, std::auto_ptr<U> x );

    +
    +
      +
    • Effects: return replace( position, x.release() )
    • +
    +
    +
  • std::auto_ptr< reversible_ptr_container > clone() const;

      @@ -377,8 +665,8 @@ think it is just an std::auto_ptr
  • -
    -

    Semantics: comparison

    +
    +

    Semantics: comparison

    These functions compare the underlying range of objects. So

    @@ -387,8 +675,8 @@ operation( const ptr_container& l, const ptr_container& r );
     

    has the effect one would expect of normal standard containers. Hence objects are compared and not the pointers to objects.

    -
    -

    Semantics: clonability

    +
    +

    Semantics: clonability

    • template< class T, class CloneAllocator > reversible_ptr_container<T,CA,VPC>* @@ -403,8 +691,8 @@ objects are compared and not the pointers to objects.

    -
    -

    Semantics: null predicate

    +
    +

    Semantics: null predicate

    • template< class Iterator > bool is_null( Iterator i );

      diff --git a/doc/reversible_ptr_container.rst b/doc/reversible_ptr_container.rst index 1df8889..51dd2e7 100755 --- a/doc/reversible_ptr_container.rst +++ b/doc/reversible_ptr_container.rst @@ -72,7 +72,9 @@ Its purpose is to present the general interface of all the pointer containers. public: // `pointer container requirements`_ - auto_type replace( iterator position, T* x ); + auto_type replace( iterator position, T* x ); + template< class U > + auto_type replace( iterator position, std::auto_ptr x ); std::auto_ptr clone() const; std::auto_ptr release(); auto_type release( iterator position ); @@ -319,6 +321,10 @@ Semantics: pointer container requirements - Throws: ``bad_ptr_container_operation`` if the container is empty and ``bad_pointer`` if ``x == 0``. - Exception safety: Strong guarantee + +- ``template< class U > auto_type replace( iterator position, std::auto_ptr x );`` + + - Effects: ``return replace( position, x.release() );`` - ``std::auto_ptr< reversible_ptr_container > clone() const;`` diff --git a/doc/todo.txt b/doc/todo.txt index 7af74a6..171b578 100755 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -1,40 +1,34 @@ -Hi, -------------------- +2. add new ptr_map typedefs -10) Specify difference between assignment from an input_iterator (basic exception safety guarantee) - and any other iterator (strong exception safety guarantee). Provide a iterator wrapper - which implement the input_iterator concept to achieve that particular performance characteristic: - vector.assign( fast_copy_iterator( other.begin() ), other.end() ); +3. remove ptr_map iterators description -20) Add two sources and a discussion on defaults: http://www.gotw.ca/gotw/054.htm, http://www.codeproject.com/vcpp/stl/vector_vs_deque.asp +4. ptr_map definition -45) update all functions with correct exception specs +5. small usage exmaple with each class -46) add description to erase() which returns end in some circumstances +7. update concept for clonable: typeid(x) == typeid(clone) -47) Consider if list implemetation of multi-insert can benefit - from strong exception-safety. - -74) consider simple static assert by nesting a typedef a la -T::boost_indirect_container +8. use static class hierarchy to ease navigation -74.5) a new function in map: auto_type replace( key&, T* );? +9. guidelines on good OO programming: -75) toturial: + 1. base classes abstract + + 2. make virtuals private -ptr_map: + 3. derive from boost::copyable -add default constructor + 4. don't allow nulls if you can avoid it, Null Object -map[ "foo" ].set_data( "Bla bla", 6 ); +10. update tutorial to show boost::assign link -boost.assign -support: +11. should find_key() be added to ptr_map? -ptr_insert( ptr_map )( "foo", "bla bla", 3 ) - ( "bar", "foo", 3 ); - - +12. serialization -76) use boost::get_pointer() to retrieve - the pointer withint dereferenceing. +13. no exceptions + + + + \ No newline at end of file diff --git a/doc/tutorial.html b/doc/tutorial.html index c6a23ea..f262834 100644 --- a/doc/tutorial.html +++ b/doc/tutorial.html @@ -3,9 +3,288 @@ - + Boost Pointer Container Library - +
      @@ -26,8 +305,8 @@ that you read it all from top to bottom.

    • New functions
    • Algorithms
    -
    -

    Basic usage

    +
    +

    Basic usage

    The most important aspect of a pointer container is that it manages memory for you. This means that you in most cases do not need to worry about deleting memory.

    @@ -76,8 +355,8 @@ the_zoo.add_animal( new bird("dodo") );

    Thus we heap-allocate all elements of the container and never rely on copy-semantics.

    -
    -

    Indirected interface

    +
    +

    Indirected interface

    As particular feature of the pointer containers is that the query interface is indirected. For example,

    @@ -101,8 +380,8 @@ ptr_vec::iterator i = vec.begin();
     i->eat(); // no indirection needed
     
    -
    -

    Sequence containers

    +
    +

    Sequence containers

    The sequence containers used when you do not need to keep an ordering on your elements. You can basically expect all operations of the normal standard containers @@ -129,8 +408,8 @@ boost::ptr_vector<animal> animals( 10u );

    will reserve room for 10 animals.

    -
    -

    Associative containers

    +
    +

    Associative containers

    To keep an ordering on our animals, we could use a ptr_set:

     boost::ptr_set<animal> set;
    @@ -176,8 +455,8 @@ animals["bobo"].set_name("bobo");
     

    This requires a default constructor for animals and a function to do the initialization, in this case set_name();

    -
    -

    Null values

    +
    +

    Null values

    By default, if you try to insert null into a container, an exception is thrown. If you want to allow nulls, then you must say so explicitly when declaring the container variable

    @@ -210,8 +489,8 @@ for( animals_type::size_type i = 0u;

    Note that it is meaningless to insert null into ptr_set and ptr_multiset.

    -
    -

    Clonability

    +
    +

    Clonability

    In OO programming it is typical to prohibit copying of objects; the objects may sometimes be allowed to be clonable; for example,:

    @@ -249,8 +528,8 @@ another_zoo.insert( another_zoo.begin(), zoo.begin(), zoo.end() );
     zoo_type yet_another_zoo = zoo.clone();
     
    -
    -

    New functions

    +
    +

    New functions

    Given that we know we are working with pointers, a few new functions make sense. For example, say you want to remove an animal from the zoo

    @@ -321,8 +600,8 @@ catch( boost::bad_ptr_container_operation& e ) }
    -
    -

    Algorithms

    +
    +

    Algorithms

    Unfortunately it is not possible to use pointer containers with mutating algorithms from the standard library. However, the most useful ones