// file      : Utility/ReferenceCounting/Interface.hpp
// author    : Boris Kolpackov <boris@kolpackov.net>
// copyright : Copyright (c) 2002-2003 Boris Kolpackov
// license   : http://kolpackov.net/license.html

namespace Utility
{
  namespace ReferenceCounting
  {
    // Interface to a reference-countable object. Note that _remove_ref ()
    // member function has a no-throw semantic. Even though it can lead to
    // a diagnostic loss it was made no-throw because it has a destructor
    // semantic.

    class Interface
    {
    public:
      typedef
      unsigned long
      count_t;

      typedef
      ExH::System::Exception
      SystemException;

      class Exception_ {};
      typedef
      ExH::Compound<Exception_, ExH::Logic::DescriptiveException>
      Exception;

    public:
      virtual void
      add_ref () const throw (Exception, SystemException) = 0;

      virtual void
      remove_ref () const throw () = 0;

      virtual count_t
      refcount_value () const throw (Exception, SystemException) = 0;

    protected:
      Interface () throw ();

      virtual
      ~Interface () throw ();

    protected:
      virtual void
      add_ref_i () const throw (Exception, SystemException) = 0;

      virtual bool
      remove_ref_i () const throw (Exception, SystemException) = 0;

      virtual count_t
      refcount_value_i () const throw (Exception, SystemException) = 0;

    private:
      // Copy semanic is not supported.
      Interface (Interface const&) throw ();
      Interface&
      operator= (Interface const&) throw ();
    };

    template <typename Type>
    Type*
    add_ref (Type* ptr)
      throw (Interface::Exception, Interface::SystemException);
  }
}