Вообщем за два года я так и не увидел чего-либо аналогичного, поэтому представляю на суд. Только ногами не бейте
исходные тексты "вырваны" из окружения, поэтому, естественно, просто так компилироваться не будут. В часности — assert_msg это мое изобретение, которое отсутсвует в стандарте.
t_container.h(cc)
t_vector - оболочка вокруг std::vector для обеспечения совместимости с BIDS (было такое у Borland) и жестокого котроля за корректностью истользования. В принципе мало чего интересного
t_wrap_vector - реализация вектора, который обеспечивает доступ к данным через "аксессоры". Например, есть struct VARIANT и class TVariant с идентичной бинарной структурой. Храним VARIANT, обращаемся через TVariant. В качестве примеров — t_ivector и t_counted_object_vector
t_ivector - вектор для хранения указателей. Настальгия по TIArray из BIDS, только на базе std::vector<void*>. Используется очень просто — vector<TMyClass>. Можно указывать — владеет контейнер содержимым или нет.
t_counted_object_vector - базовый класс для вектора smart-указателей. Маленький шедевр, которым до сих пор горжусь. В качестве реального использования см. t_smart_vector из <t_smart_container.h> и t_iptr2_vector из <ptr.h> для COM-объектов
t_smart_conteinter.h
t_smart_conteiner - контейнер для smart-указателей на объекты, производные от t_smart_memory_object (t_handle.h(cc))
t_handle.h(cc)
Здесь можно посмотреть, что из себя представляет t_smart_memory_object и t_smart_object_ptr
ptr.h(сс)
IPtr2 - вариация на тему смарт-указатель на COM объект
t_iptr2_vector — вектор смарт-указателей на базе IPtr2
Все это дело собирается на BCB3/5. На днях пробовал с STLPort (4.5?) — вроде тоже все нормально.
Файлы вычищаю не полностью, поэтому там остались другие интересные штучки.
За каким я это сделал? — Что бы потом на вот такие
вопросыАвтор: Fiend Дата: 16.09.02
давать ссылку сюда, а не заниматься демагогией.
Заодно, может кто-нибудь предложит какие-нибудь улучшения.
Если есть вопросы —
. Хотя ответы на это сообщение я тоже буду читать
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
// классы оболочки вокруг 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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
//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
////////////////////////////////////////////////////////////////////////////////
//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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
//Базовые классы управления ресурсами.
// Коваленко Дмитрий. 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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
//Реализация шаблонов <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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
//Реализация смарт указаталей для работы с 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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
////////////////////////////////////////////////////////////////////////////////
//Реализация шаблонов <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
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить