00001 /* 00002 * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события 00003 * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru 00004 * _______________________________________________________________________________ 00005 * Разрешено свободное использование, копирование, распространение, изменение 00006 * (изменение сведений об авторских правах запрещено). Запрещена продажа и 00007 * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об 00008 * авторских правах на программу (или сведениях о программе, об авторах, 00009 * использованных средствах разработки и т.д.) должна быть указана информация 00010 * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е. 00011 * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора. 00012 */ 00013 00014 #ifndef CNTM_NOREFPTRREGISTER_H 00015 #define CNTM_NOREFPTRREGISTER_H 00016 #include <Cntm/RefCount/Internal/NoRefPtrStorage.h> 00017 #include <Cntm/RefCount/RefPtr.h> 00018 #include <Cntm/Containers/Register.h> 00019 00020 namespace Cntm 00021 { 00022 00023 /** 00024 * Это шаблонный класс перечня, хранящий не ссылочные (обычные) указатели на объекты, однако принимающий и перечисляющий ссылочные указатели. Когда происходит сохранение значения в перечне, ссылочный указатель преобразуется в обычный, когда происходит перечисление эл-тов - наоборот - из обычного в ссылочный. При этом следует учитывать, что если ссылочный объект находится в удаляемом состоянии, то в результате преобразования обычного указателя к ссылочному, последний примет значение NULL, однако перечислитель автоматически пропускает указатели на NULL, т.о. текущее значение перечислителя никогда не будет равняться NULL. В качестве параметра шаблона указывается тип объекта. 00025 * 00026 * Данный класс может использоваться, когда требуется такая регистрация ссылочных объектов, которая не приводила бы к хранению ссылок на объекты. В этом случае при создании объект регистрирует себя в перечне, а перед уничтожением - уничтожает регистрацию (например, в деструкторе). В какой бы момент не происходило перечисление, если на объект есть ссылки, то будет возвращен ссылочный указатель на этот объект, если объект находится в удаляемом состоянии, но он еще не изъял свой указатель из перечня, то при перечислении он будет пропущен, если же объект изъял свой указатель из перечня, то он уже не будет перечислен. 00027 * 00028 * Класс обеспечивает многопоточность. 00029 * @author Овсеевич Р. 00030 * \ingroup Containers 00031 */ 00032 template < typename T > 00033 class NoRefPtrRegister: public Register < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > 00034 { 00035 public: 00036 00037 typedef Register < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > RegisterType; 00038 00039 /** 00040 * Класс перечислителя. Наследует класс перечислителя перечня. 00041 * 00042 * Переопределяет метод Next() и операторы ->() и ++(). 00043 * \ingroup Containers 00044 */ 00045 class Enumerator: public Register < RefPtr < T >, SpecUtils::NoRefPtrStorage < T > > ::Enumerator 00046 { 00047 public: 00048 00049 /** 00050 * Оператор позволяет получить доступ к членам объекта, на который указывает текущее значение перечислителя. 00051 * 00052 * Следует помнить, что если при перечислении метод Next() вернул true, то гарантируется, что текущее значение перечислителя не содержит NULL. 00053 */ 00054 const RefPtr < T > & operator-> () const 00055 { 00056 return Enumerator::Current(); 00057 } 00058 00059 /** 00060 * Перейти к следующему эл-ту. Вызывает функцию Next(). См. функцию Next(). 00061 */ 00062 Enumerator& operator++ () 00063 { 00064 Next(); 00065 return *this; 00066 } 00067 00068 /** 00069 * Практически во всем совпадает с функцией Next() предка (Register::Enumerator::Next()) за исключением того, что ссылочные указатели, содержащие NULL, автоматически пропускаются при перечислении, т.о. текущее значение никогда не будет содержать указатель на NULL. 00070 */ 00071 bool Next() 00072 { 00073 while (RegisterType::Enumerator::Next()) 00074 if (Enumerator::Current()) return true; 00075 return false; 00076 } 00077 00078 protected: 00079 00080 friend class NoRefPtrRegister; 00081 00082 /** 00083 * Конструктор. Используется перечнем для инициализации перечислителя. 00084 */ 00085 Enumerator(RegisterType * Reg, bool DynamicExpanded): 00086 RegisterType::Enumerator(Reg, DynamicExpanded) {} 00087 }; 00088 00089 /** 00090 * Получить объект перечислителя для доступа к эл-там. 00091 * @param DynamicExpanded - true (значение по умолчанию) - перечислитель будет перечислять эл-ты, добавленные в перечень после создания перечислителя, false - перечислитель будет переслять только те эл-ты, которые были в перечне на момент создания перечислителя (удаленные эл-ты перечислитель не перечисляет в любом случае). 00092 */ 00093 Enumerator GetEnumerator(bool DynamicExpanded = true) const 00094 { 00095 return Enumerator(const_cast<NoRefPtrRegister*>(this), DynamicExpanded); 00096 } 00097 }; 00098 00099 } 00100 00101 #endif //CNTM_NOREFPTRREGISTER_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |