// ------------------------------------------------------------------------
/*
	author: Jaap Suter
    
    Copyright (C) Electronic Arts Canada Inc. 2002.  All rights reserved.	
*/
// ------------------------------------------------------------------------

/*! \file */

#include "reveal/smart_ptr/unit_test.h"
#include "reveal/smart_ptr/scoped_ptr.h"
#include "reveal/smart_ptr/scoped_array.h"

namespace Reveal {
    namespace SmartPtr {
        namespace UnitTest {

bool TestScopedPtr();
bool TestScopedArray();

// ------------------------------------------------------------------------
bool Test()
{
    return TestScopedPtr() 
		&& TestScopedArray();
}




// ------------------------------------------------------------------------
// Class used by the unit-test;
// ------------------------------------------------------------------------
class UserDefinedType
{
public:
    UserDefinedType( bool& alive ) : mAlive( alive ) { mAlive = true; }
    ~UserDefinedType() { mAlive = false; }
private:
	UserDefinedType& operator = ( const UserDefinedType& );
    bool& mAlive;
};

// ------------------------------------------------------------------------
bool TestScopedPtr()
{
    //  Test it with a built-in type;
    {
        int* rawPtr = new int;
        ScopedPtr< int > p( rawPtr );
        if ( p.Get() != rawPtr ) return false;
        if ( &*p.Get() != rawPtr ) return false;
        p.Reset();
        if ( p.Get() != 0 )  return false;
    }

    // Test it with a user-defined type;
    {
        bool alive = false;
        {
            UserDefinedType *rawPtr = new UserDefinedType( alive );
            ScopedPtr< UserDefinedType > p( rawPtr ); 
            if ( p.Get() != rawPtr ) return false;
            if ( &*p.Get() != rawPtr ) return false;
            
            ScopedPtr< UserDefinedType >().Swap( p );
            if ( alive ) return false;
        }
    }

    // Test destruction on scope exit;
    {
        bool alive = false;
        {
            ScopedPtr< UserDefinedType > p( new UserDefinedType( alive ) );
        }
        if ( alive ) return false;
    }

    // Unit test succeeded;
    return true;
}

// ------------------------------------------------------------------------
bool TestScopedArray()
{
    int* rawPtr = new int[ 16 ];
    ScopedArray< int > p( rawPtr );
    if ( p.Get() != rawPtr ) return false;
    if ( &*p.Get() != rawPtr ) return false;
	p[ 0 ] = 3;
	if ( p[ 0 ] != 3 ) return false;
    p.Reset();
    if ( p.Get() != 0 )  return false;
 
    // Unit test succeeded;
    return true;
}

        } // Namespace UnitTest
    } // Namespace SmartPtr
} // Namespace Reveal
