// Copyright 2020 Siemens Digital Industries Software
// ==================================================
// Copyright 2009.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================
// Copyright 2020 Siemens Digital Industries Software
/** 
    @file 
    Implementation of reference counter for shared_ptr.
    
    @note This class should not be used as such. 
    <br>Use the class #SharedPtr instead.
*/

/*
Background: 
    Base implementation copied from NX. The code was copied as this class was available in 
latest NX libraries which are currently not supported in Tc.
The implementation in NX uses code from Boost library, hence a reference to Boost license in included.

Changes were made to NX code to conform it to Tc. These changes include :
    - namespace change
    - using default heap instead of SM.
    - remove support for custom allocator. This was NX specific extension, not present in std::tr1
    - cosmetic changes like separating class declaration and definition for clarity.
    - comment support for custom deleter. std::tr1 provides this but we arent supporting it at the moment.
*/

/* Boost license: as base implementation comes for Boost, including its license.

  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
  Copyright 2004-2005 Peter Dimov

 Distributed under the Boost Software License, Version 1.0. 
 (See copy at http://www.boost.org/LICENSE_1_0.txt)
*/

#ifndef TEAMCENTER_BASE_UTILS_SHARED_PTR_COUNTED_IMPL_HXX
#define TEAMCENTER_BASE_UTILS_SHARED_PTR_COUNTED_IMPL_HXX

#if 0 // uncomment when adding support for customer deleter. more details below.
#include <typeinfo>         // std::type_info in get_deleter
#endif 

#include <base_utils/CheckedDelete.hxx> // checked_delete
#include <base_utils/SharedPtrCountedBase.hxx>  // base class

namespace Teamcenter
{
namespace Internal
{
    /** Implements a reference counter for shared_ptr.
        No support for a custom deallocator. uses delete operator.
    */
    template< class X > class SharedPtrCountedBaseImpl_p: public SharedPtrCountedBase
    {
        typedef SharedPtrCountedBaseImpl_p< X > this_type;

    public:
        inline explicit SharedPtrCountedBaseImpl_p( X* px );
        inline virtual void dispose(); // nothrow        
        inline virtual void * get_deleter( std::type_info const & );

    private:
        X* px_;        // contained pointer.

        SharedPtrCountedBaseImpl_p( SharedPtrCountedBaseImpl_p const & );
        SharedPtrCountedBaseImpl_p & operator= ( SharedPtrCountedBaseImpl_p const & );
    };

//// Implementation details for SharedPtrCountedBaseImpl_p
 
    template< class X> inline SharedPtrCountedBaseImpl_p<X>::SharedPtrCountedBaseImpl_p( X* px )
        : px_( px )
    {

    }

    template< class X > inline void SharedPtrCountedBaseImpl_p<X>::dispose()
    {
        checked_delete( px_ );
    }

    template< class X > inline void* SharedPtrCountedBaseImpl_p<X>::get_deleter( std::type_info const & )
    {
        return 0;
    }

#if 0   // Would be required when we have full std::tr1 support. See SharedPtr.hxx for more information.
    template< class P, class D > class SharedPtrCountedBaseImpl_pd: public Teamcenter::Internal::SharedPtrCountedBase
    {
    private:

        P ptr; // copy constructor must not throw
        D del; // copy constructor must not throw

        SharedPtrCountedBaseImpl_pd( SharedPtrCountedBaseImpl_pd const & );
        SharedPtrCountedBaseImpl_pd & operator= ( SharedPtrCountedBaseImpl_pd const & );

        typedef SharedPtrCountedBaseImpl_pd< P, D > this_type;

    public:
        // pre: d(p) must not throw

        SharedPtrCountedBaseImpl_pd( P p, D d ): ptr( p ), del( d )
        {
        }

        virtual void dispose() // nothrow
        {
            del( ptr );
        }

        virtual void * get_deleter( std::type_info const & ti )
        {
            return ti == typeid( D )? &del: 0;
        }
    };
#endif 

} // end namespace Internal
} // end namespace Teamcenter

#endif //TEAMCENTER_BASE_UTILS_SHARED_PTR_COUNTED_IMPL_HXX
