# Introduction

This library provides standard-like containers that are suitable for storing pointers to both polymorphic and non-polymorphic objects. For each of the standard containers there is a pointer container equivalent that takes ownership of the stored pointers in an exception safe manner. In this respect it is intended to solve the so-called polymorphic class problem.

The main advantages are <itemizedlist>

- Exception-safe and fool proof pointer storage and manipulation.
.
- Exception-guarantees are generally much better than with standard containers (at least the strong guarantee
- Notational convinience compared to the use of containers of smart pointers.
- Iterators are automatically indirected so the comparison operations can be kept on object basis instead of making/adding pointer based variants.
- No memory-overhead as containers of smart_pointers can have.
- Faster than using containers of smart pointers.
- Provides an elegant solution to `vector< vector<T> >` performance problems; simply use `ptr_vector< vector<T> >`

Below is given some example that show how the usage compares to a container of smart pointers:

        using namespace boost;
        using namespace std;

        class Poly
        {
        public:
            virtual ~Poly() {}
            void foo() { doFoo(); }
        private:
            virtual void doFoo()
            {
                int i;
                ++i;
            }
        };

        //
        // one doesn't need to introduce new names or live with long ones
        //
        typedef shared_ptr<Poly> PolyPtr;

        //
        // one doesn't need to write this anymore
        //
        struct PolyPtrOps
        {
          void operator()( const PolyPtr & a )
            { a->foo(); }
        };

        int main()
        {
            enum { size = 2000000 };
            vector<PolyPtr>    svec
            ptr_vector<Poly>   pvec;

            for( int i = 0; i < size; ++i )
            {
                svec.push_back( PolyPtr( new Poly ) );
                pvec.push_back( new Poly );  // no extra syntax
            }

            for_each( svec.begin(), svec.end(), PolyPtrOps() );

            for_each( pvec.begin(), pvec.end(), mem_fun_ref( &Poly::foo ) );
         }