Расширения std::vector
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:18
Оценка: 24 (2)
Вообщем за два года я так и не увидел чего-либо аналогичного, поэтому представляю на суд. Только ногами не бейте

исходные тексты "вырваны" из окружения, поэтому, естественно, просто так компилироваться не будут. В часности — assert_msg это мое изобретение, которое отсутсвует в стандарте.

t_container.h(cc)

t_smart_conteinter.h

t_handle.h(cc)
Здесь можно посмотреть, что из себя представляет t_smart_memory_object и t_smart_object_ptr

ptr.h(сс)

Все это дело собирается на BCB3/5. На днях пробовал с STLPort (4.5?) — вроде тоже все нормально.

Файлы вычищаю не полностью, поэтому там остались другие интересные штучки.

За каким я это сделал? — Что бы потом на вот такие вопросы
Автор: Fiend
Дата: 16.09.02
давать ссылку сюда, а не заниматься демагогией.

Заодно, может кто-нибудь предложит какие-нибудь улучшения.

Если есть вопросы — . Хотя ответы на это сообщение я тоже буду читать
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Source
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:19
Оценка:
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: t_container.h
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:21
Оценка:
////////////////////////////////////////////////////////////////////////////////
// классы оболочки вокруг STL контейнеров
// с более жестким контролем доступа при отладке
// и обеспечения обратной совместимости с BIDS
//                                            Kovalenko Dmitry. 11.10.2000

#ifndef _t_container_H_
#define _t_container_H_

#include <vector>
#include <structure/t_memory.h>

namespace structure{
////////////////////////////////////////////////////////////////////////////////
// class t_vector

template<class T, class Allocator=allocator<T> >
class t_vector:public vector<T,Allocator>
{
 private:
  typedef vector<T,Allocator>                    inherited_vector;

 public:
  typedef t_vector<T,Allocator>                  container_type;
  typedef inherited_vector::size_type            size_type;
  typedef inherited_vector::reference            reference;
  typedef inherited_vector::const_reference      const_reference;
  typedef inherited_vector::iterator             iterator;
  typedef inherited_vector::const_iterator       const_iterator;
  typedef inherited_vector::allocator_type       allocator_type;

  static const size_type npos;//-1

 public:
  explicit t_vector(const allocator_type& alloc=allocator_type())
   :inherited_vector(alloc){;}

  t_vector(const container_type& container)
   :inherited_vector(container){;}

  explicit t_vector(size_type n)
   :inherited_vector(n){;}

  t_vector(size_type n,const T& value,const allocator_type& alloc=allocator_type())
   :inherited_vector(n,value,alloc){;}

  //template<class const_iterator>
  t_vector(const_iterator first,const_iterator last,const allocator_type& alloc=allocator_type())
   :inherited_vector(first,last,alloc){;}

  container_type& operator = (const container_type& container)
   {
    inherited_vector::operator = (container);
    return *this;
   }

 public://selectors ------------------------------------------------------
 #ifndef NDEBUG
  reference at(size_type index)
   {
    assert_msg(index<size(),"index=="<<index<<"\nsize=="<<size());
    return inherited_vector::at(index);
   }

  const_reference at(size_type index)const
   {
    assert_msg(index<size(),"index=="<<index<<"\nsize=="<<size());
    return inherited_vector::at(index);
   }

  reference operator [] (size_type index)
   {
    assert_msg(index<size(),"index=="<<index<<"\nsize=="<<size());
    return inherited_vector::operator [](index);
   }

  const_reference operator [] (size_type index)const
   {
    assert_msg(index<size(),"index=="<<index<<"\nsize=="<<size());
    return inherited_vector::operator [](index);
   }

  reference       front ()       {assert(!empty());return inherited_vector::front();}
  const_reference front () const {assert(!empty());return inherited_vector::front();}

  reference       back()         {assert(!empty());return inherited_vector::back();}
  const_reference back()   const {assert(!empty());return inherited_vector::back();}
  
 #endif //ifndef NDEBUG
 public://modificators -----------------------------------------------------
 #ifndef NDEBUG
  iterator insert(iterator position,const T& x)
   {
    assert(position>=begin());
    assert(position<=end());
    return inherited_vector::insert(position,x);
   }

  void insert(iterator position,size_type n,const T& x)
   {
    assert(position>=begin());
    assert(position<=end());
    inherited_vector::insert(position,n,x);
   }

  void insert(iterator position,const_iterator first,const_iterator last)
   {
    assert(position>=begin());
    assert(position<=end());
    assert(first<=last);

    inherited_vector::insert(position,first,last);
   }

  iterator erase(iterator position)
   {
    assert(position>=begin());
    assert(position<end());
    return inherited_vector::erase(position);
   }

  iterator erase(iterator first,iterator last)
   {
    assert(first<=last);
    assert(first>=begin());
    assert(first<=end());
    assert(last>=begin());
    assert(last<=end());

    return inherited_vector::erase(first,last);
   }

  void pop_back()
   {
    assert(!empty());
    inherited_vector::pop_back();
   }
 #endif// ifndef NDEBUG
 public://BIDS compatibles -----------------------------------------------
  size_type GetItemsInContainer() const { return size();  }
  bool      IsEmpty()             const { return empty(); }
  int       BoundBase(int index)  const { return index;   }
  int       Find(const T& value)  const
   {
    const_iterator i=find(begin(),end(),value);
    return (i==end())?INT_MAX:(i-begin());
   }

  int Add(const T& value)
   {
    push_back(value);
    return 1;
   }

  int AddAt(const T& value,size_type index)
   {
    assert_msg(index<=size(),"AddAt: index=="<<index<<" size=="<<size());
    insert(begin()+index,value);
    return 1;
   }

  void Destroy(size_type index)
   {
    assert_msg(index<=size(),"Destroy: index=="<<index<<" size=="<<size());
    erase(begin()+index);
   }

  void Flush()
   {
    clear();
   }

  void Reallocate(size_type n)
   {
    reserve(n);
   }
};//class t_vector

template<class T, class Allocator>
const t_vector<T,Allocator>::size_type t_vector<T,Allocator>::npos=-1;

////////////////////////////////////////////////////////////////////////////////
//class t_wrap_vector

//traits - wrap services
//                             types 
//data_type            - user type of data (T)
//value_type           -
//const_value_type     - user type of stored data (T*/T)
//assign_value_type    - type of add data (value_type,const_value_type)
//internal_value_type  - type for internal storage (value_type/void*)
//accessor_type        - type for element accessor (smart_pointer and etc.)
//                       required: sizeof(accessor_type==sizeof(value_type))
//const_accessor_type
//ref_accessor         - type of return accessor objects (accessor_type&)
//const_ref_accessor   -
//                            functions
//create element accessor
// ref_accessor_type    access(internal_value_type)
// const_ref_accessor   access(const internal_value_type)const
//
//init internal element value (NULL/0/etc)
// internal_value_type init_internal_value()
//
//assign element
// void assign(internal_value_type&,assign_pointer_type x)
//
//destroy element
// void desrtoy(internal_value_type&);

template<class traits,class Allocator>
class t_wrap_vector
{
 public:
  typedef Allocator                                      allocator_type;
  typedef typename  Allocator::size_type                 size_type;
  typedef typename  Allocator::difference_type           difference_type;

  static const size_type npos;//-1

 public:
  typedef traits                                         traits_type;

  typedef typename traits::data_type                     data_type;

  //type of container element (required by STL)
  typedef typename traits::value_type                    value_type;
  typedef typename traits::const_value_type              const_value_type;

  //any work with container element uses the accessor (required by STL)
  typedef typename traits::accessor_type*                pointer;
  typedef typename traits::const_accessor_type*          const_pointer;
  typedef typename traits::ref_accessor                  reference;
  typedef typename traits::const_ref_accessor            const_reference;

  //internal typedefs
  typedef typename traits::assign_value_type             assign_value_type;
  typedef typename traits::internal_value_type           internal_value_type;

  typedef typename traits::accessor_type                 accessor_type;
  typedef typename traits::const_accessor_type           const_accessor_type;
  typedef typename traits::ref_accessor                  ref_accessor;
  typedef typename traits::const_ref_accessor            const_ref_accessor;

  typedef t_wrap_vector<traits,Allocator>                wrap_vector_type;

 private:
  typedef t_vector<internal_value_type>                  internal_storage_type;
  typedef typename internal_storage_type::iterator       internal_iterator;
  typedef typename internal_storage_type::const_iterator const_internal_iterator;

 protected:
  traits_type           m_traits;
  internal_storage_type m_items;

 public:
  class iterator;
  class const_iterator;

  friend class iterator;
  friend class const_iterator;

 private: //define base class of iterators
#ifdef __BORLANDC__
 #if __BORLANDC__>=0x0550
  typedef _RW_STD::iterator<random_access_iterator_tag, accessor_type,
                            difference_type,
                            value_type,
                            ref_accessor>        __it;
  typedef _RW_STD::iterator<random_access_iterator_tag, accessor_type,
                            difference_type,
                            const_value_type,
                            const_ref_accessor>  __cit;
 #else
  typedef random_access_iterator<accessor_type,difference_type>          __it;
  typedef random_access_iterator<const_accessor_type,difference_type>    __cit;
 #endif
#else //!__BORLAND__
  struct __it
  {
   typedef wrap_vector_type::difference_type difference_type;//GCC warnings
  };
  struct __itc
  {
   typedef wrap_vector_type::difference_type difference_type;//GCC warnings
  };
#endif

 public: //Iterators -----------------------------------------------------
  class iterator:public __it
  {
    friend class wrap_vector_type;
    friend class const_iterator;

   protected:
    wrap_vector_type*    m_cntr;
    internal_iterator    m_i;

    iterator(wrap_vector_type* cntr,internal_iterator x)
     :m_cntr(cntr),m_i(x){;}

   public:
    iterator():m_cntr(NULL),m_i(NULL){;}

    bool operator == (const iterator& x)const {return m_i==x.m_i;}
    bool operator != (const iterator& x)const {return !(*this==x);}
    bool operator <= (const iterator& x)const {return m_i<=x.m_i;}
    bool operator <  (const iterator& x)const {return m_i<x.m_i;}
    bool operator >= (const iterator& x)const {return m_i>=x.m_i;}
    bool operator >  (const iterator& x)const {return m_i>x.m_i;}

    ref_accessor operator * () const
     {
      assert(m_cntr!=NULL);
      assert(m_i>=m_cntr->m_items.begin());
      assert(m_i<m_cntr->m_items.end());

      return m_cntr->m_traits.access(*m_i);
     }

    iterator& operator ++ ()    {++m_i;return *this;}
    iterator  operator ++ (int) {iterator tmp=*this;++m_i;return tmp;}
    iterator& operator -- ()    {m_i--;return *this;}
    iterator  operator -- (int) {iterator tmp=*this;--m_i;return tmp;}

    difference_type operator - (const iterator& x)const
     {return m_i-x.m_i;}

    iterator  operator +  (difference_type x) const
     {iterator tmp=*this;tmp.m_i+=x;return tmp;}

    iterator  operator -  (difference_type x) const
     {iterator tmp=*this;tmp.m_i-=x;return tmp;}

    iterator& operator += (difference_type x)
     {m_i+=x;return *this;}

    iterator& operator -= (difference_type x)
     {m_i-=x;return *this;}
  };//class iterator

  class const_iterator:public __cit
  {
   private:
    friend class wrap_vector_type;

   protected:
    const wrap_vector_type*    m_cntr;
    const_internal_iterator    m_i;

    const_iterator(const wrap_vector_type* cntr,const_internal_iterator x)
     :m_cntr(cntr),m_i(x){;}

   public:
    const_iterator():m_cntr(NULL),m_i(NULL){;}
    const_iterator(const iterator& x)
     :m_cntr(x.m_cntr),m_i(x.m_i){;}

    bool operator == (const const_iterator& x)const {return m_i==x.m_i;}
    bool operator != (const const_iterator& x)const {return !(*this==x);}
    bool operator <= (const const_iterator& x)const {return m_i<=x.m_i;}
    bool operator <  (const const_iterator& x)const {return m_i<x.m_i;}
    bool operator >= (const const_iterator& x)const {return m_i>=x.m_i;}
    bool operator >  (const const_iterator& x)const {return m_i>x.m_i;}

    const_ref_accessor operator * () const
     {
      assert(m_cntr!=NULL);
      assert(m_i>=m_cntr->m_items.begin());
      assert(m_i<m_cntr->m_items.end());
      return m_cntr->m_traits.access(*m_i);
     }

    const_iterator& operator ++ ()    {++m_i;return *this;}
    const_iterator  operator ++ (int) {const_iterator tmp=*this;++m_i;return tmp;}
    const_iterator& operator -- ()    {m_i--;return *this;}
    const_iterator  operator -- (int) {const_iterator tmp=*this;--m_i;return tmp;}

    difference_type operator - (const const_iterator& x)const
     {return m_i-x.m_i;}

    const_iterator  operator +  (difference_type x) const
     {const_iterator tmp=*this;tmp.m_i+=x;return tmp;}

    const_iterator  operator -  (difference_type x) const
     {const_iterator tmp=*this;tmp.m_i-=x;return tmp;}

    const_iterator& operator += (difference_type x)
     {m_i+=x;return *this;}

    const_iterator& operator -= (difference_type x)
     {m_i-=x;return *this;}
  };//class const_iterator

 private: //private copy operation ---------------------------------------
  t_wrap_vector(const wrap_vector_type&);
  wrap_vector_type& operator = (const wrap_vector_type&);

 protected: //services for low-level container ---------------------------
  iterator internal_erase(iterator position);
  iterator internal_erase(iterator first,iterator last);

 public:
  t_wrap_vector(){;}
 ~t_wrap_vector()
   {clear();}

  //Capacity -------------------------------------------------------------
  bool      empty()    const         {return m_items.empty();}
  size_type size()     const         {return m_items.size();}
  size_type max_size() const         {return m_items.max_size();}
  size_type capacity() const         {return m_items.capacity();}

  void      resize(size_type new_sz);

  void      reserve(size_type n)     {m_items.reserve(n);}

  //Iterators ------------------------------------------------------------
  iterator begin() {return iterator(this,m_items.begin());}
  iterator end()   {return iterator(this,m_items.end());}

  const_iterator begin() const {return const_iterator(this,m_items.begin());}
  const_iterator end()   const {return const_iterator(this,m_items.end());}

  //Element access -------------------------------------------------------
  ref_accessor        operator [] (size_type index);
  const_ref_accessor  operator [] (size_type index)const;

  ref_accessor        at (size_type index);
  const_ref_accessor  at (size_type index)const;

  ref_accessor        front()       {assert(!empty());return *begin();}
  const_ref_accessor  front() const {assert(!empty());return *begin();}

  ref_accessor        back()        {assert(!empty());return *(--end());}
  const_ref_accessor  back() const  {assert(!empty());return *(--end());}

  //Modifiers ------------------------------------------------------------
  iterator insert(iterator position);//insert NULL pointer
  void     insert(iterator position,size_type n);//insert n NULL pointers
  iterator insert(iterator position,assign_value_type x);
  void     push_back(assign_value_type x);

  iterator erase(iterator position);
  iterator erase(iterator first,iterator last);
  void     clear();
  void     pop_back();

 public: //BIDS compartibles ---------------------------------------------
  size_type           GetItemsInContainer()    const {return size();    }
  bool                IsEmpty()                const {return empty();   }
  int                 BoundBase(int index)     const {return index;     }

  ref_accessor        At (size_type index)           {return at(index); }
  const_ref_accessor  At (size_type index)     const {return at(index); }

  int Find(const const_value_type &x) const
   {
    const_iterator i=find(begin(),end(),x);
    return (i==end())?INT_MAX:(i-begin());
   }

  int Add(assign_value_type x)
   {
    push_back(x);
    return 1;
   }

  int AddAt(assign_value_type x,size_type index)
   {
    assert_msg(index<=size(),"AddAt: index=="<<index<<" size=="<<size());
    insert(begin()+index,x);
    return 1;
   }

  void Destroy(size_type index)
   {
    assert_msg(index<=size(),"Destroy: index=="<<index<<" size=="<<size());
    erase(begin()+index);
   }

  void Flush()
   {clear();}

  void Reallocate(size_type n)
   {reserve(n);}
};//class t_wrap_vector

template<class traits, class Allocator>
const t_wrap_vector<traits,Allocator>::size_type t_wrap_vector<traits,Allocator>::npos=-1;

////////////////////////////////////////////////////////////////////////////////
//class t_pointer_traits - service for management standart pointer

struct t_should_delete
{
 enum TDelete{NoDelete,Delete};
};

//T - user pointed data type
//TInternalData - type of internal pointed data (T(debug) or void(release))

template<class T,class TInternalData=T>
class t_pointer_traits:public t_should_delete
{
 public: //typedefs ------------------------------------------------------
  typedef T                    data_type;
  typedef T*                   value_type;
  typedef const T*             const_value_type;
  typedef T*                   assign_value_type;
  
#ifndef NDEBUG
  typedef TInternalData        internal_data_type;
  typedef TInternalData*       internal_value_type;
  typedef const TInternalData* const_internal_value_type;
#else
  typedef void                 internal_data_type;
  typedef void*                internal_value_type;
  typedef const void*          const_internal_value_type;
#endif

  typedef t_pointer_traits<T,TInternalData> pointer_traits_type;

 private: //private copy operatoins --------------------------------------
  t_pointer_traits(const pointer_traits_type&);
  pointer_traits_type& operator = (const pointer_traits_type&);

 private:
  //**********************************************************************
  //      xxx_accessor ограничивают набор операций над указателями,      *
  //                    хранящимися в контейнере.                        *
  //**********************************************************************

  //обертка вокруг указателя на объект ---------------------------
  class tag_accessor
  {
   private:
    tag_accessor(const tag_accessor&);
    const tag_accessor& operator = (const tag_accessor&);

    data_type* m_ptr;

   public:
    operator   data_type*  () const {return m_ptr;}
    data_type& operator *  () const {assert(m_ptr!=NULL);return *m_ptr;}
    data_type* operator -> () const {assert(m_ptr!=NULL);return m_ptr;}
  };//class t_pointer_traits::tag_accessor

  //обертка вокруг указателя на константный объект ---------------
  class tag_const_accessor
  {
   private:
    tag_const_accessor(const tag_const_accessor&);
    const tag_const_accessor& operator = (const tag_const_accessor&);

    const data_type* m_ptr;

   public:
    operator   const data_type*  () const {return m_ptr;}
    const data_type& operator *  () const {assert(m_ptr!=NULL);return *m_ptr;}
    const data_type* operator -> () const {assert(m_ptr!=NULL);return m_ptr;}
  };//class t_pointer_traits::tag_const_accessor

 public: //declare type of container access objects ----------------------
  typedef tag_accessor                               accessor_type;
  typedef const tag_const_accessor                   const_accessor_type;

  typedef tag_accessor&                              ref_accessor;
  typedef const tag_const_accessor&                  const_ref_accessor;

 public: //ownership states ----------------------------------------------
  TDelete m_owning;                  //state of ownership < --------- !!!!

 public: //constructor ---------------------------------------------------
  t_pointer_traits():m_owning(Delete)
   {
    assert(sizeof(value_type)==sizeof(accessor_type));
    assert(sizeof(value_type)==sizeof(const_accessor_type));
    assert(sizeof(value_type)==sizeof(internal_value_type));
   }

 public: //service functions ---------------------------------------------
  ref_accessor access(internal_value_type& x)const
   {return *reinterpret_cast<tag_accessor*>(&x);}

  const_ref_accessor access(const const_internal_value_type& x)const
   {return *reinterpret_cast<const tag_const_accessor*>(&x);}

  static internal_value_type init_internal_value()
   {return NULL;}

  void assign(internal_value_type &internal_value,assign_value_type value)
   {
    assert(internal_value==init_internal_value());
    internal_value=value;
   }

  void destroy(internal_value_type& internal_value)
  {
   if(m_owning!=NoDelete && internal_value!=NULL)
    delete reinterpret_cast<value_type>(internal_value);

   internal_value=init_internal_value();
  }
};//class t_pointer_traits

////////////////////////////////////////////////////////////////////////////////
//class t_ivector - indirect vector

template<class T,class TInternalData=void,class Allocator=t_void_allocator>
class t_ivector:public t_wrap_vector<t_pointer_traits<T,TInternalData>,Allocator>,
                public t_should_delete
{
 private:
  typedef t_ivector<T,TInternalData,Allocator>                          ivector_type;
  typedef t_wrap_vector<t_pointer_traits<T,TInternalData>,Allocator>    inherited_pointer_vector;

 public: //public typedefs
  typedef inherited_pointer_vector::iterator                  iterator;
  typedef inherited_pointer_vector::const_iterator            const_iterator;
  typedef inherited_pointer_vector::size_type                 size_type;

 private:
  t_ivector(const ivector_type&);
  t_ivector& operator = (const ivector_type&);

 public:
  t_ivector(){;}

 public:
  TDelete owning()          const  {return m_traits.m_owning;}
  void    owning(TDelete x)        {m_traits.m_owning=x;}

  //remove pointer without destroy its objects
  iterator detach(iterator position);

 public: //BIDS compartibles ---------------------------------------------
  TDelete OwnsElements()    const  {return owning();}
  void    OwnsElements(int x)
  {
  #if(defined(__BORLANDC__) && defined(INCLUDE_CLASSLIB_HEADER))
   assert(TShouldDelete::NoDelete==NoDelete);
   assert(TShouldDelete::NoDelete==0);
  #endif
   owning(x?Delete:NoDelete);
  }

  int Detach(size_type index);  //remove pointer without destroy its objects
};//class t_ivector

////////////////////////////////////////////////////////////////////////////////
//class t_counted_object_ptr_traits - service for management pointers of
// smart or COM-objects

//class traits_data declared typedefs with name
// data_type            - type of smart object (or COM-interface)
// accessor_type        - the smart pointer for type T
//                        IMPORTANT: sizeof(TPtr)==sizeof(T*)
//                        required implementation -
//                        set(T*)   - assign pointer
//                        Release() - release pointer
// internal_data_type   - type for internal an storage of the pointer on T
//                        (T*) - for debug / (void*) - for release
//                        IMPORTANT: sizeof(T*)==sizeof(TInternalData)


template<class traits_data>
class t_counted_object_ptr_traits
{
 public: //typedefs ------------------------------------------------------
  typedef traits_data                               traits_data_type;
  typedef traits_data::data_type                    data_type;
  typedef traits_data::data_type*                   value_type;
  typedef const traits_data::data_type*             const_value_type;
  typedef traits_data::data_type*                   assign_value_type;

 #ifndef NDEBUG
  typedef traits_data::internal_data_type           internal_data_type;
  typedef traits_data::internal_data_type*          internal_value_type;
  typedef const traits_data::internal_data_type*    const_internal_value_type;
 #else
  typedef void                                      internal_data_type;
  typedef void*                                     internal_value_type;
  typedef const void*                               const_internal_value_type;
 #endif

  typedef t_counted_object_ptr_traits<traits_data>  traits_type;

 private: //private copy operations --------------------------------------
  t_counted_object_ptr_traits(const traits_type&);
  traits_type& operator = (const traits_type&);

 public: //declare type of container access objects ----------------------
  typedef traits_data::accessor_type                accessor_type;
  typedef const traits_data::accessor_type          const_accessor_type;

  //IMPORTANT - We do not create a instance of access object.
  //            Instead of it we use reinterpret_cast for the stored pointer,
  //            and we use TPtr members for his management
  typedef accessor_type&                         ref_accessor;
  typedef const_accessor_type&                   const_ref_accessor;

 public: //constructor ---------------------------------------------------
  t_counted_object_ptr_traits()
  {
   assert(sizeof(value_type)==sizeof(accessor_type));
   assert(sizeof(value_type)==sizeof(const_accessor_type));
   assert(sizeof(value_type)==sizeof(internal_value_type));
  }

 public: //service functions ---------------------------------------------
  ref_accessor       access(internal_value_type& x)const
   {return *reinterpret_cast<accessor_type*>(&x);}

  const_ref_accessor access(const const_internal_value_type& x)const
   {return *reinterpret_cast<const_accessor_type*>(&x);}

  static internal_value_type init_internal_value()
   {return NULL;}

  void assign(internal_value_type &internal_value,assign_value_type value)
   {
    assert(internal_value==init_internal_value());//check empty pointer
    access(internal_value).set(value);
   }

  void destroy(internal_value_type& internal_value)
   {
    access(internal_value).Release();
   }
};//class t_counted_obj_ptr_traits

////////////////////////////////////////////////////////////////////////////////
//class t_counted_object_vector - only for inherited
// vector for smart or COM-objects
// implement copy operations

template<class traits_data,class Allocator=t_void_allocator>
class t_counted_object_vector:
 public t_wrap_vector<t_counted_object_ptr_traits<traits_data>,Allocator>
{
 protected: //typedefs ---------------------------------------------------
  typedef t_counted_object_vector<traits_data,Allocator>
            counted_vector_type;

  typedef t_wrap_vector<t_counted_object_ptr_traits<traits_data>,Allocator>
            pointer_vector_type;
            
 protected: //-------------------------------------------------------------
  t_counted_object_vector()
   {;}

 public:
  void assign(const pointer_vector_type& x);

  void append(const pointer_vector_type& x);
};//public t_counted_object_vector

////////////////////////////////////////////////////////////////////////////////
#include <structure/t_container.cc>//template class implementsions
////////////////////////////////////////////////////////////////////////////////
};//namespace structure
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: t_container.cc
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:23
Оценка:
////////////////////////////////////////////////////////////////////////////////
//implementations of template class from <t_container.h>
//                                      Коваленко Дмитрий. 30 января 2000 года.

#ifndef _t_container_CC_
#define _t_container_CC_

#ifndef _t_container_H_
#error ("this file must be include after <t_container.h>")
#endif

////////////////////////////////////////////////////////////////////////////////
//inline members of t_wrap_vector
 
template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::iterator
t_wrap_vector<traits,Allocator>::internal_erase(iterator position)
{
 return iterator(this,m_items.erase(position.m_i));
}

template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::iterator
t_wrap_vector<traits,Allocator>::internal_erase(iterator first,iterator last)
{
 return iterator(this,m_items.erase(first.m_i,last.m_i));
}

// Capacity --------------------------------------------------------------
template<class traits,class Allocator>
void t_wrap_vector<traits,Allocator>::resize(size_type new_size)
{
 if(new_size>size())
  insert(end(),new_size-size());
 else
 if(new_size<size())
  erase(begin()+new_size,end());
}

// Element access --------------------------------------------------------
template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::ref_accessor
t_wrap_vector<traits,Allocator>::operator [] (size_type index)
{
 assert_msg(index<size(),"index=="<<index<<" size=="<<size());
 return m_traits.access(m_items[index]);
}

template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::const_ref_accessor
t_wrap_vector<traits,Allocator>::operator [] (size_type index) const
{
 assert_msg(index<size(),"index=="<<index<<" size=="<<size());
 return m_traits.access(m_items[index]);
}

template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::ref_accessor
t_wrap_vector<traits,Allocator>::at (size_type index)
{
 assert_msg(index<size(),"index=="<<index<<" size=="<<size());
 return m_traits.access(m_items[index]);
}

template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::const_ref_accessor
t_wrap_vector<traits,Allocator>::at (size_type index) const
{
 assert_msg(index<size(),"index=="<<index<<" size=="<<size());
 return m_traits.access(m_items[index]);
}

//Modifiers --------------------------------------------------------------
template<class traits,class Allocator>
RELEASE_CODE(inline)
t_wrap_vector<traits,Allocator>::iterator t_wrap_vector<traits,Allocator>::insert(iterator position)
{
 assert(position>=begin());
 assert(position<=end());

 return iterator(this,m_items.insert(position.m_i,NULL));
}

template<class traits,class Allocator>
RELEASE_CODE(inline)
void t_wrap_vector<traits,Allocator>::insert(iterator position,size_type n)
{
 assert(position>=begin());
 assert(position<=end());

 m_items.insert(position.m_i,n,m_traits.init_internal_value());
}

template<class traits,class Allocator>
t_wrap_vector<traits,Allocator>::iterator
t_wrap_vector<traits,Allocator>::insert(iterator position,assign_value_type x)
{
 assert(position>=begin());
 assert(position<=end());

 internal_iterator tmp=m_items.insert(position.m_i,m_traits.init_internal_value());
 m_traits.assign(*tmp,x);

 return iterator(this,tmp);
}

template<class traits,class Allocator>
t_wrap_vector<traits,Allocator>::iterator
t_wrap_vector<traits,Allocator>::erase(iterator position)
{
 assert(position>=begin());
 assert(position<end());

 m_traits.destroy(*position.m_i);

 return internal_erase(position);
}

template<class traits,class Allocator>
t_wrap_vector<traits,Allocator>::iterator
t_wrap_vector<traits,Allocator>::erase(iterator first,iterator last)
{
 assert(first<=last);
 assert(first>=begin());
 assert(first<=end());
 assert(last>=begin());
 assert(last<=end());

 //destroy pointed elements
 for(internal_iterator i=first.m_i;i!=last.m_i;i++)
  m_traits.destroy(*i);

 return internal_erase(first,last);
}

template<class traits,class Allocator>
inline void t_wrap_vector<traits,Allocator>::clear()
{
 erase(begin(),end());
}

template<class traits,class Allocator>
inline void t_wrap_vector<traits,Allocator>::push_back(assign_value_type x)
{
 insert(end(),x);
}

template<class traits,class Allocator>
inline void t_wrap_vector<traits,Allocator>::pop_back()
{
 assert(!empty());
 erase(end()-1);
}

////////////////////////////////////////////////////////////////////////////////
//class t_ivector

template<class T,class TInternalData,class Allocator>
RELEASE_CODE(inline)
t_ivector<T,TInternalData,Allocator>::iterator
t_ivector<T,TInternalData,Allocator>::detach(iterator position)
{
 assert(position>=begin());
 assert(position<end());

 return internal_erase(position);
}

template<class T,class TInternalData,class Allocator>
int t_ivector<T,TInternalData,Allocator>::Detach(size_type index)
{
 if(index>=size())
  return 0;

 detach(begin()+index);
 return 1;
}

////////////////////////////////////////////////////////////////////////////////
//class t_counted_object_vector

template<class traits_data,class Allocator>
void t_counted_object_vector<traits_data,Allocator>::
 assign(const pointer_vector_type& x )
{
 if(&x==this)
  return;
  
 resize(x.size());

 assert(size()==x.size());

 const_iterator si(x.begin());//source
 const_iterator se(x.end());

 iterator       di(begin()); //destination

 for(;si!=se;++di,++si)
  (*di)=(*si);
}

template<class traits_data,class Allocator>
void t_counted_object_vector<traits_data,Allocator>::
 append(const pointer_vector_type& x )
{
 reserve(size()+x.size());

 size_type c=x.size();

 for(size_type i=0;i!=c;i++)
  push_back(x[i]);
}

////////////////////////////////////////////////////////////////////////////////
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: t_smart_container.h
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:25
Оценка:
////////////////////////////////////////////////////////////////////////////////
//Containers for pointers of smart objects
//                                     Kovalenko Dmitry. February 3, 2001.

#ifndef _t_smart_container_H_
#define _t_smart_container_H_

#include <structure\t_container.h>
#include <structure\t_handle.h>

namespace structure{ 
////////////////////////////////////////////////////////////////////////////////
//struct t_smart_vec_traits_data

template<class T>
struct t_smart_vec_traits_data
{
 typedef T                       data_type;
 typedef void                    internal_data_type;
 typedef t_smart_object_ptr<T>   accessor_type;
};

////////////////////////////////////////////////////////////////////////////////
//class t_smart_vector - container of smart objects

template<class T,class Allocator=t_void_allocator,class traits_data=t_smart_vec_traits_data<T> >
class t_smart_vector:public t_counted_object_vector<traits_data,Allocator>
{
 private:
  typedef t_smart_vector<T,Allocator,traits_data> smart_vector_type;

 public:
  t_smart_vector(){;}

  t_smart_vector(const smart_vector_type& x);

  smart_vector_type& operator = (const smart_vector_type& x);
};//class t_smart_vector

////////////////////////////////////////////////////////////////////////////////
//class t_smart_vector - implementation

template<class T,class Allocator,class traits_data>
RELEASE_CODE(inline)
t_smart_vector<T,Allocator,traits_data>::t_smart_vector(const smart_vector_type& x)
{
 assign(x);
}

template<class T,class Allocator,class traits_data>
RELEASE_CODE(inline)
t_smart_vector<T,Allocator,traits_data>&
t_smart_vector<T,Allocator,traits_data>::operator = (const smart_vector_type& x)
{
 assign(x);
 return *this;
}

////////////////////////////////////////////////////////////////////////////////
};//namespace structure
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: t_handle.h
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:27
Оценка:
////////////////////////////////////////////////////////////////////////////////
//Базовые классы управления ресурсами.
//                                                   Коваленко Дмитрий. 98 год.
#ifndef _t_handle_H_
#define _t_handle_H_

#include <structure/t_memory.h>

namespace structure{
////////////////////////////////////////////////////////////////////////////////
//containing classes

//базовый класс для построение объектов с подсчетом ссылок пользователей
class t_smart_object;

//наследует t_smart_object. обеспечивает уничтожение динамически созданных объектов
//при обнулении счетчика ссылок
class t_smart_memory_object;

//t_smart_memory с указанием менеджера распределения памяти
template<class Allocator=t_void_allocator>
class t_smem_obj;

//конструирование SmartMemory-класса
template<class TBaseClass,class Allocator=t_void_allocator>
class t_smem_obj_maker;

//смарт-указатель для объектов классов построенных на базе t_smart_object
//template<class T,class TInternalPointer=T*,class TCounter=t_smart_object_counter> c
// class t_smart_object_ptr;

//обслуживание дескрипторов с явным счетчиком ссылок
//ни какого контроля за значением счетчика нет
template<class T>
struct t_handle_counter;

//шаблон для автоматического управления установкой и сброса флага
template<class TFlag,class TSetValue,class TResetValue>
class t_auto_switch;

////////////////////////////////////////////////////////////////////////////////
// облегченные варианты COM объекта

class t_smart_object
{
 private:
  t_smart_object(const t_smart_object&);
  t_smart_object& operator = (const t_smart_object&);
  
 private:
  long m_cntRef;

 protected: //только для наследования
  t_smart_object():m_cntRef(0){;}

  virtual ~t_smart_object(){assert(m_cntRef==0);}

 public:
  virtual long add_ref(){return ::InterlockedIncrement(&m_cntRef);}

  virtual long release(){return ::InterlockedDecrement(&m_cntRef);}

 public:
  long get_cntRef() const {return m_cntRef;}

};//class t_smart_object

///////////////////////////////////////////////////////////////////////////////
// упрошенный вариант COM-объекта

class t_smart_memory_object:public t_smart_object
{
 private:
  t_smart_memory_object(const t_smart_memory_object&);
  t_smart_memory_object& operator = (const t_smart_memory_object&);

  DEBUG_CODE(bool m_is_destroyed;)

 protected:
  t_smart_memory_object()
  {
   DEBUG_CODE(m_is_destroyed=false);
  }

 public:
  long release();

};//class t_smart_memory_object

////////////////////////////////////////////////////////////////////////////////
//class t_smem_object

template<class Allocator>
class t_smem_obj:public t_smart_memory_object
{
 private:
  typedef t_smem_obj<Allocator>         smem_obj_type;

  t_smem_obj(const smem_obj_type&);
  smem_obj_type& operator = (const smem_obj_type&);

 public: //typedefs --------------------------------------------------------
  typedef Allocator                                allocator_type;

 protected: //только для наследования
  t_smem_obj(){;}

 public:
  void* operator new (size_t sz)
   {return allocator_type().allocate(sz);}

  void operator delete (void* pv)
   {allocator_type().deallocate(pv,0);}
};//class t_smem_obj

////////////////////////////////////////////////////////////////////////////////
//template class t_smem_obj_maker

template<class TBaseClass,class Allocator>
class t_smem_obj_maker:public TBaseClass,
                       public t_smem_obj<Allocator>
{
 private:
  typedef t_smem_obj_maker<TBaseClass,Allocator> TSmartClass;

  t_smem_obj_maker(const TSmartClass&);

  TSmartClass& operator = (const TSmartClass&);

  //disable static create and create in stack
 ~t_smem_obj_maker(){;}

 public:
  t_smem_obj_maker(){;}

};//class t_smem_obj_maker

////////////////////////////////////////////////////////////////////////////////
//стандартный аргумент шаблона smart указателя для увеличения и уменьшения
//ссылок на smart объекты

template<class T>
struct t_smart_ptr_traits_data
{
 typedef T           item_type;
 typedef T*          internal_pointer_type;

 static long increment_cntRef(t_smart_object* ptr)
  {assert(ptr!=NULL);return ptr->add_ref();}

 static long decrement_cntRef(t_smart_object* ptr)
  {assert(ptr!=NULL);return ptr->release();}
};//struct t_smart_ptr_traits_data

///////////////////////////////////////////////////////////////////////////////
// класс-указатель на t_smart_object

//#ifndef NDEBUG
//#define RET_SMART_OBJ(TypeSmartObj) t_smart_object_ptr<TypeSmartObj>
//#else
//#define RET_SMART_OBJ(TypeSmartObj) TypeSmartObj*
//#endif

template<class T,class traits_data=t_smart_ptr_traits_data<T> >
class t_smart_object_ptr
{
 public: //typedef
  typedef traits_data                         traits_data_type;
  typedef traits_data::item_type              item_type;
  typedef traits_data::internal_pointer_type  internal_pointer_type;

  typedef t_smart_object_ptr<T,traits_data>   smart_pointer_type;

 private:
  internal_pointer_type m_ptr;

 public:
  t_smart_object_ptr():m_ptr(NULL){;}

  //конструктор копирования
  explicit t_smart_object_ptr(const smart_pointer_type& ptr)
   :m_ptr(NULL)
  {set(ptr.ptr());}

  //конструктор копирования
  explicit t_smart_object_ptr(item_type* ptr)
   :m_ptr(NULL)
  {set(ptr);}

  //по-нормальному, смарт-указатель не должен наследоваться
  //поэтому деструктор не виртуальный 
  ~t_smart_object_ptr()
  {
   Release();
  }

  smart_pointer_type& set(item_type* ptr);

  smart_pointer_type& set(const smart_pointer_type& ptr)
  {
   return set(ptr.ptr());
  }

  void Release();

  T* ptr() const {return m_ptr;}

  smart_pointer_type& operator = (item_type* ptr)
  {
   return set(ptr);                           // оператор копирования
  }

  smart_pointer_type& operator = (const smart_pointer_type& ptr)
  {
   return set(ptr);                           // оператор копирования
  }

  bool operator == (const smart_pointer_type& ptr)const
  {
   return this==&ptr;
  }

  item_type* operator -> () const {assert((bool)m_ptr);return m_ptr;}
  item_type& operator *  () const {assert((bool)m_ptr);return *m_ptr;}

  operator item_type* ()    const {return ptr();}

  bool operator !    () const {return !m_ptr;}
       operator bool () const {return (bool)m_ptr;}
  
};//class t_smart_object_ptr

////////////////////////////////////////////////////////////////////////////////
// struct t_handle_counter

template<class T>
struct t_handle_counter
{
 typedef t_handle_counter<T> handle_counter;

 T    m_Data;
 LONG m_cntRef;

 t_handle_counter(){m_cntRef=0;}
 t_handle_counter(const handle_counter& counter)
  {*this=counter;}
 t_handle_counter(const T& Data)
  {*this=Data;}

 handle_counter& operator = (const handle_counter& counter)
  {
   m_Data=counter.m_Data;
   m_cntRef=counter.m_cntRef;

   return *this;
  }

 handle_counter& operator = (const T& Data)
  {
   m_Data=Data;
   m_cntRef=1;

   return *this;
  }

 bool operator == (const handle_counter& counter)const
  {return this==&counter;}

 LONG AddRef() {return ::InterlockedIncrement(&m_cntRef);}
 LONG Release(){return (m_cntRef<=0)?0: ::InterlockedDecrement(&m_cntRef);}
};//class t_handle_counter

////////////////////////////////////////////////////////////////////////////////
//class t_auto_switch_ex

template<class TFlag,class TSetValue=TFlag,class TResetValue=TFlag>
class t_auto_switch
{
 private:
  typedef t_auto_switch<TFlag,TSetValue,TResetValue> type_auto_switch;

  t_auto_switch(const type_auto_switch&);
  t_auto_switch& operator = (const type_auto_switch&);

  TFlag&            m_flag;
  const TResetValue m_reset_value;

 public:
  t_auto_switch(TFlag& flag,TSetValue set_value,TResetValue reset_value)
   :m_flag(flag),
    m_reset_value(reset_value)
  {
   m_flag=set_value;
  }

  t_auto_switch(TFlag& flag,TSetValue set_value)
   :m_flag(flag),
    m_reset_value(flag)
  {
   m_flag=set_value;
  }

 ~t_auto_switch()
  {
   m_flag=m_reset_value;
  }

  TFlag& data()
   {return m_flag;}

  const TResetValue& restored()const
   {return m_reset_value;}
};//class t_auto_switch

////////////////////////////////////////////////////////////////////////////////
};//namespace structure
////////////////////////////////////////////////////////////////////////////////
#include <structure/t_handle.cc>
////////////////////////////////////////////////////////////////////////////////
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: t_handle.cc
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:29
Оценка:
////////////////////////////////////////////////////////////////////////////////
//Реализация шаблонов <t_handle.h>
//                                    Коваленко Дмитрий. 19 сентября 2002 года.

#ifndef _t_handle_CC_
#define _t_handle_CC_

namespace structure{
////////////////////////////////////////////////////////////////////////////////
//class t_smart_memory_object

long t_smart_memory_object::release()
{
 assert(!m_is_destroyed);

 long cntRef;

 if((cntRef=t_smart_object::release())==0)
 {
  DEBUG_CODE(m_is_destroyed=true;)
  delete this;
 }

 return cntRef;
}//release

////////////////////////////////////////////////////////////////////////////////
//class t_smart_object_ptr

template<class T,class traits_data>
t_smart_object_ptr<T,traits_data>&
 t_smart_object_ptr<T,traits_data>::set(item_type* ptr)
{
 if((bool)ptr)
  traits_data::increment_cntRef(ptr);//->add_ref();

 Release();

 m_ptr=ptr;

 return *this;
}

//------------------------------------------------------------------------------
template<class T,class traits_data>
void t_smart_object_ptr<T,traits_data>::Release()
{
 if((bool)m_ptr)
 {
  internal_pointer_type old_ptr=m_ptr;

  m_ptr=NULL;

  traits_data::decrement_cntRef(old_ptr);//->release();
 }
}

////////////////////////////////////////////////////////////////////////////////
};//namespace structure

#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: ptr.h
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:33
Оценка:
////////////////////////////////////////////////////////////////////////////////
//Реализация смарт указаталей для работы с COM объектами
//                                                   Коваленко Дмитрий. 98 год.
#ifndef _PTR_H_
#define _PTR_H_

#include <ole_lib/ole_base.h>

#ifndef _t_container_H_
#include <structure/t_container.h>
#endif

namespace ole_lib{
////////////////////////////////////////////////////////////////////////////////
//Список классов

//смарт-указатель на COM объект без поддержки QueryInterface
template<class T> class IPtr2;

//вектор смарт-указателей на COM объекты
template<class T,class Allocator,class TInternalData> class t_iptr2_vector;

////////////////////////////////////////////////////////////////////////////////
//helper functions

template<class ISource,class IDest>
HRESULT CopyComInterface(ISource* pISource,IDest** pIDest);

template<class I1,class I2>
bool IsEqualComObject(I1* p1,I2* p2);

template<class I>
void ReleaseComInterface(I* &pI);

////////////////////////////////////////////////////////////////////////////////
//class IPtr2 - без использования QueryInterface

template<class T>
class IPtr2
{
 private:
  T* m_ptr;

 public:
  typedef IPtr2<T> interface_pointer;
  typedef T        type_interface;

 public:
  IPtr2():m_ptr(NULL){;}
  IPtr2(const interface_pointer& Ptr2):m_ptr(NULL) {*this=Ptr2;}
  IPtr2(T* ptr):m_ptr(NULL){*this=ptr;}

 ~IPtr2(){Release();}

 public:
  HRESULT QueryInterface(REFIID riid,void** ppv);

  void Release();

  void Terminate() //"экстренное" освобождение указателя
  {
   m_ptr=NULL;
  }
  
  interface_pointer& set (T* ptr);

  interface_pointer& set (const interface_pointer& Ptr2)
  {
   return set(Ptr2.ptr());
  }

  interface_pointer& operator = (const interface_pointer& Ptr2)
  {
   return set(Ptr2.ptr());
  }

  interface_pointer& operator = (T* ptr)
  {
   return set(ptr);
  }

  bool operator == (const interface_pointer& Ptr2) const
  {
   return this==&Ptr2;
  }

  T* operator -> () const {assert(m_ptr!=NULL);return m_ptr;}
     operator T* () const {return m_ptr;}

  bool operator !    () const {return m_ptr==NULL;}
       operator bool () const {return m_ptr!=NULL;}

  T*      ptr() const {return m_ptr;}
  T* &ref_ptr() {Release();return m_ptr;}

  HRESULT CopyTo(T** pptr)const
  {
   return CopyComInterface(ptr(),pptr);
  }

  bool IsEqualObject(IUnknown* pUnk)const
  {
   return IsEqualComObject(static_cast<IUnknown*>(ptr()),pUnk);
  }
}; //template class IPtr2

typedef IPtr2<IUnknown> IUnknownPtr; 

////////////////////////////////////////////////////////////////////////////////
//struct t_iptr2_vec_trats_data

template<class T>
struct t_iptr2_vec_traits_data
{
 typedef T              data_type;
 typedef void           internal_data_type;
 typedef IPtr2<T>       accessor_type;
};

////////////////////////////////////////////////////////////////////////////////
//class t_iptr2_vector

template<class T,class Allocator=structure::t_void_allocator,class traits_data=t_iptr2_vec_traits_data<T> >
class t_iptr2_vector:
 public structure::t_counted_object_vector<traits_data,Allocator>
{
 public://typedefs
  typedef t_iptr2_vector<T,Allocator,traits_data> type_iptr2_vector;

 public:
  t_iptr2_vector(){;}

  t_iptr2_vector(const type_iptr2_vector& x);

  type_iptr2_vector& operator = (const type_iptr2_vector& x);
};

////////////////////////////////////////////////////////////////////////////////
};//namespace ole_lib
////////////////////////////////////////////////////////////////////////////////
#include <ole_lib/ptr.cc>
////////////////////////////////////////////////////////////////////////////////
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: ptr.cc
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.02 16:35
Оценка:
////////////////////////////////////////////////////////////////////////////////
//Реализация шаблонов <ole_lib/ptr.h>
//                                     Коваленко Дмитрий. 28 декабря 2001 года.
#ifndef _ptr_CC_
#define _ptr_CC_

namespace ole_lib{
////////////////////////////////////////////////////////////////////////////////
//helper functions

template<class ISource,class IDest>
HRESULT CopyComInterface(ISource* pISource,IDest** pIDest)
{
 assert(pIDest!=NULL);

 if(pIDest==NULL)
  return E_POINTER;

 if((*pIDest=pISource)!=NULL)
  (*pIDest)->AddRef();

 return S_OK;
}//CopyComInterface

template<class I1,class I2>
bool IsEqualComObject(I1* p1,I2* p2)
{
 if(!p1 && !p2)
  return true;

 if(!p1 || !p2)
  return false;

 IUnknownPtr spUnk1;
 IUnknownPtr spUnk2;

 //в отладочной версии проверяем все и вся...
 DEBUG_CODE(HRESULT hr);

 DEBUG_CODE(hr=)p1->QueryInterface(IID_IUnknown,(void**)&spUnk1.ref_ptr());
 assert(hr==S_OK);
 assert((bool)spUnk1);

 DEBUG_CODE(hr=)p2->QueryInterface(IID_IUnknown,(void**)&spUnk2.ref_ptr());
 assert(hr==S_OK);
 assert((bool)spUnk2);

 return spUnk1.ptr()==spUnk2.ptr();
}//IsEqualComObject

//освобождение и присвоение NULL
template<class I>
void ReleaseComInterface(I* &pI)
{
 if(pI!=NULL)
 {
  I* _pI=pI;
  pI=NULL;

  _pI->Release();
 }
}//ReleaseComInterface

////////////////////////////////////////////////////////////////////////////////
//template class IPtr2

template<class T>
HRESULT IPtr2<T>::QueryInterface(REFIID riid,void** ppv)
{
 if(ppv==NULL)
  return E_POINTER;

*ppv=NULL;

 return ptr()?ptr()->QueryInterface(riid,ppv):E_FAIL;
}

template<class T>
void IPtr2<T>::Release()
{
 if(m_ptr)
 {
  T* ptr=m_ptr;    //такой механизм освобождения необходим при самоблокировке
  m_ptr=NULL;      //объекта в памяти

  ptr->Release();
 }
}

template<class T>
IPtr2<T>& IPtr2<T>::set(T* ptr)
{
 if(ptr==m_ptr) return *this;

 T* pOld=m_ptr;
 m_ptr=ptr;

 if(m_ptr)
  m_ptr->AddRef();

 if(pOld)
  pOld->Release();

 return *this;
}

////////////////////////////////////////////////////////////////////////////////
//template class t_iptr2_vector

template<class T,class Allocator,class traits_data>
RELEASE_CODE(inline)
t_iptr2_vector<T,Allocator,traits_data>::t_iptr2_vector(const type_iptr2_vector& x)
{
 assign(x);
}

template<class T,class Allocator,class traits_data>
RELEASE_CODE(inline)
t_iptr2_vector<T,Allocator,traits_data>&
t_iptr2_vector<T,Allocator,traits_data>::operator = (const type_iptr2_vector& x)
{
 assign(x);
 return *this;
}

////////////////////////////////////////////////////////////////////////////////
};//namespace ole_lib
#endif
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.