//  (C) Porkolab 2003
//
//  A.5.8.
//   
//  Problems with auto_ptr



auto_ptr<int>  p1(new int(1));  // Ok
auto_ptr<int>  p2 = new int(2); // Error, explicit constructor



 *p2 = 5;   // Ok
++p2;       // Error, no pointer arithmetic



auto_ptr<int>  p1(new int(1));
auto_ptr<int>  p2(new int(2));

p2 = p1;        // delete 2, transfers ownership from p1



//  source and sink

auto_ptr<int> source(int n)
{
    auto_ptr<int> p(new int(n));
    ...
    return p;       // transfers ownership to the caller
}

void sink( auto_ptr<int>) { };

auto_ptr<int>  p1 = source(1);  // creat, get ownership

sink( p1 );     // gets ownership and delete 1 on return


// be care: for auto_ptr -s, copies are not equivalent


// is this correct?
template <class T>
void print( auto_ptr<T> p)
{
    if ( p.get() )
        cout << *p;
    else
        cout << "null";
}
...

auto_ptr<int>  p(new int);
*p = 4;
print(p);
*p = 5;     // runtime error
...

// keep ownership by const auto_ptr
const auto_ptr<int>  p(new int), q;
*p = 4;
print(p);   // compile-time error: cannot change ownership
*p = 5;     // ok: const of ownership 
 q = p;     // compile-time error: q const



// is this correct?
void f()
{
    vector< auto_ptr<int> >  v;

    v.push_back( auto_ptr<int>( new int(1) ) );
    v.push_back( auto_ptr<int>( new int(4) ) );
    v.push_back( auto_ptr<int>( new int(3) ) );
    v.push_back( auto_ptr<int>( new int(2) ) );

    sort( v.begin(), v.end() ); // ??? what about pivot element, etc...
}



//  auto_ptr as member

class B;

class A
{
private:
    B *p1;
    B *p2;
public:
    A( B b1, B b2) : p1(new B(b1)), p2(new B(b2))  {  }
    A( const A& rhs) : p1( new B(*rhs.p1)), p2( new B(*rhs.p2))  {  }
    A& operator=(const A& rhs)
    {
        *p1 = *rhs.p1;
        *p2 = *rhs.p2;
        return *this;
    }
    ~A()
    {
        delete p1;
        delete p2;
    }
};

class A
{
private:
    const auto_ptr<B> p1;
    const auto_ptr<B> p2;
public:
    A( B b1, B b2) : p1(new B(b1)), p2(new B(b2))  {  }
    A( const A& rhs) : p1( new B(*rhs.p1)), p2( new B(*rhs.p2))  {  }
    A& operator=(const A& rhs)
    {
        *p1 = *rhs.p1;
        *p2 = *rhs.p2;
        return *this;
    }
    // we do not need ~A(). 
    // why we need the copy constr, and operator= ?
};



// is this correct?
void f(int n)
{
    auto_ptr<int> p1(new int);
    auto_ptr<int> p2(new int[n]);
    ...
}   // delete  and not  delete[]  for  p2