    // 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);
      }
    }