NoRefPtrRegister.h

См. документацию.
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

SourceForge.net Logo
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой  doxygen 1.5.3