/*
 * @copyright (C) HERMES SoftLab, 2009. All rights reserved.
 */
#if !defined(INTRINSIC_PTR_HPP_FILE_GUARD)
#define INTRINSIC_PTR_HPP_FILE_GUARD


/**

@defgroup smartptr Smart Pointers

This module contains various smart pointers.

*/

namespace cool
{


/**
 * @ingroup smartptr
 * @brief Shared pointer with reference counter embedded in allocated block.
 *
 * <b>This is a pre-release version which was not yet fully tested</b>
 *
 * @c intrinsic_ptr class template creates a dynamic C++ object using @c new
 * expression and internally stores a pointer to it. This pointer may be shared
 * with other @c intrinsic_ptr instances. The object is guaranteed to be
 * deleted when the last @c intrinsic_ptr pointing to it is destroyed or
 * reset.
 *
 * Every @c intrinsic_ptr meets the @b CopyConstructible and @b Assignable
 * requirements of C++ Standard Library, so can be used in standard library
 * containers. Comparison operators are supplied so that @c intrinsic_ptr
 * works with the standard library's associative containers.
 *
 * Because @c intrinsic_ptr uses reference counting, cycles of @c intrinsic_ptr
 * will not be reclaimed. For example, if @c A holds an @c intrinsic_ptr to
 * itself, <tt>A</tt>'s use count will never drop to zero.
 *
 * Unlike other types of shared pointers which either use an external
 * reference count allocated separatelly (@c boost::shared_ptr) or use
 * intrusive approach where reference count is part of the pointed to object
 * (@c boost::intrusive_ptr), @c intrinsic_ptr tries to bring advantages of
 * both approaches together but also tries to avoid drawbacks of either.
 * With @c intrinsic_ptr the reference count is part of the memory block
 * allocated for the object, but without the object being aware of it.
 *
 * To make this approach feasible, @c intrinsic_ptr must allocate slightly
 * more memory than the amount required for the object itself, but this
 * memory is allocated within the same memory block used for the object and
 * with a single memory allocation. This means that there is no extra memory
 * allocation for the reference count. Note that to allocate memory properly
 * the allocation must be done internally by @c intrinsic_ptr and at the same
 * time as the object to be pointed to  is created. This makes
 * @c intrinsic_ptr responsible not only for destruction
 * but also for creation of the pointed to object. The latter is an unique
 * feature of <tt>intrinsic_ptr</tt>, not usually found with other smart
 * pointer designs.
 *
 * As result, @c intrinsic_ptr is as efficient as @c boost::intrusive_ptr
 * (often even more as most user level code uses locking mechanisms to
 * achieve thread safety), and almost as versatile as @c boost::shared_ptr. The
 * only situations that cannot be handled by @c intrinsic_ptr are APIs which
 * return preconstructed objects or preallocated memory. This includes all
 * third party object factories.
 * Custom object factories can be implemented to use @c intrinsic_ptr
 * internally to construct objects. In all other situations
 * @c intrinsic_ptr can replace <tt>boost::shared_ptr</tt>, often with
 * notable performance gains.
 *
 * <b>Exception Safety</b>@n
 *
 * The @c intrusive_ptr methods have been designed not to affect the entire
 * program's state if the exception is thrown either by pointed-to object
 * or any of the methods. This guarantees that there are no observable
 * side effects. The only exception ever thrown by <tt>intrinsic_ptr</tt>'s
 * methods is <tt>std::bad_alloc</tt>, except for the constructors and @c reset
 * methods, which will propagate any exception that may be thrown from the
 * pointed-to object's constructor.
 *
 * Note that this statement about execption saefty is true only if the type
 * @c T meets the  requirements as stated below - in particular, the behavior
 * is undefined if the desctructor of @c T throws an exception during
 * the destruction of pointed to instance.
 *
 * <b>Thread Safety</b>@n
 *
 * @c intrusive_ptr is safe to use in multi-threaded programs. The only exposed
 * points are updates to shared reference counter, which are guarded by
 * lightweight synchronization primitives such as atomic operations, critical
 * sections or spinlocks. The choice of particular technique is platform
 * dependent, but on most supported plaforms the thread safety is achieved
 * using lock-free techniques.
 *
 * Note that the thread safety of @c intrusive_ptr does not imply
 * thread safety of pointed to type @c T - the pointed to object must use of
 * thread safety mechnisms if needed.
 *
 * <b>Requirements For Object Type T:</b>@n
 *   @li @c T may be an incomplete type at the point of @c intrusive_ptr<T>
 *       declaration. @c T must be complete type when a non-empty instance of
 *       @c intrusive_ptr<T> is created.
 *   @li <tt>~T()</tt> must not throw
 *
 * <b>Requirements For Allocator Type:</b>@n
 *   @li The @c Allocator must be a class template, providing the interface
 *   of @c std::allocator, and must satisfy other requirements specified
 *   in section 20.1.5 of 2003 Edition of C++ Language Standard.
 *
 */
template<class T, class Allocator = std::allocator<T> > class intrinsic_ptr
{
};  // intrinsic_ptr



/**
 * @ingroup smartptr
 * @brief Pointer type conversion cast.
 *
 * Converts pointer of one type into pointer of another type.
 *
 * @b Requirements: @n
 * The expression <tt>static_cast<Y*>(p.get())</tt> must be well-formed.
 *
 * @return If @c p is empty, returns an empty @c intrinsic_ptr<Y>, otherwise
 *  an @c intrinsic_ptr<Y> that stores a copy of
 *  <tt>static_cast<Y*>(p.get())</tt> and <em>shares ownership</em> with
 *  <tt>p</tt>.
 *
 * @exception none  Does not throw.
 *
 * @note This function template constructs @c intrinsic_ptr<Y, A>
 * pointer type with allocator type @c A deduced from the original pointer
 * <tt>p</tt>. To use different allocator type, see the function template
 * version with four template parameters.
 */
template<typename Y, typename U, typename AU>
intrinsic_ptr<Y, AU> static_pointer_cast(intrinsic_ptr<U, AU> const& p)
{
}
/**
 * @ingroup smartptr
 * @brief Pointer type conversion cast.
 *
 * Converts pointer of one type into pointer of another type.
 *
 * @b Requirements: @n
 * The expression <tt>static_cast<Y*>(p.get())</tt> must be well-formed.
 *
 * @return If @c p is empty, returns an empty @c intrinsic_ptr<Y>, otherwise
 *  an @c intrinsic_ptr<Y> that stores a copy of
 *  <tt>static_cast<Y*>(p.get())</tt> and <em>shares ownership</em> with
 *  <tt>p</tt>.
 *
 * @exception none  Does not throw.
 *
 * @note This function template constructs @c intrinsic_ptr<Y, AY> pointer
 * with the @c AY allocator type explicitly stated by the user. Note that the
 * choice of allocator type in this case is lexical only, as the
 * @c intrinsic_ptr guarantees that the object will be destructed using the
 * same allocator type it was constructed with.
 */
template<typename Y, typename AY, typename U, typename AU>
intrinsic_ptr<Y, AY> static_pointer_cast(intrinsic_ptr<U, AU> const& p)
{
}
} // namespace


#endif
