3
// This file is part of Bombono DVD project.
5
// Copyright (c) 2007-2008, 2010 Ilya Murav'jov
7
// This program is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with this program; if not, write to the Free Software
19
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#ifndef __MLIB_PTR_H__
23
#define __MLIB_PTR_H__
26
#include <boost/smart_ptr.hpp>
29
// Умные указатели: ptr::one и ptr::shared
31
// В силу нескольких причин, указанных ниже, использовать
32
// общеизвестные std::auto_ptr и boost::shared_ptr, неудобно;
33
// потому здесь определены их замены, ptr::one и ptr::shared.
34
// Однако синтаксис их api точно такой, же что и оригиналов,-
35
// get(), reset(), release(), use_count(), ...
38
// 1) std::auto_ptr неудобно использовать, потому что конструкция
40
// не скомпилируется; то же самое со boost::scoped_ptr - бедный интерфейс
41
// 2) почему ptr::one, а не ptr::auto? - Слово "auto" зарезервировано
42
// в языке C, хотя сейчас и не имеет никакого значения (исторически
43
// сложилось). Потому подобрано (короткое) слово "one" - "владеть одному,
44
// единолично", в противовес "shared" - "общее владение".
45
// 3) boost::shared_ptr "не хватает" возможности присваивать обычный указатель,-
46
// boost::shared_ptr<obj> s_ptr;
47
// s_ptr = (obj*)0; // ошибка компиляции
52
// std::auto_ptr<T> без изъянов
69
one(one<Y>& a): ptr(a.release()) {}
71
~one() { /*delete ptr*/ boost::checked_delete(ptr); }
73
// 1 присваивание указателя
81
one& operator=(one<Y>& a)
97
T* get() const { return ptr;}
115
// 2 для конструкции "if( ptr ) ..."
116
typedef T* (one::*ptr_to_bool_type)() const;
118
operator ptr_to_bool_type() const
120
return get() == 0 ? 0: &one::get;
124
// = boost::shared_ptr<T>
126
class shared: public boost::shared_ptr<T>
128
typedef boost::shared_ptr<T> my_parent;
131
// 0 Конструкторы, как у базы
132
// сгенерированные конструктор копирования и присваивания подходят
133
shared(): my_parent() {}
137
shared(Y* p): my_parent(p) {}
139
// will release p by calling d(p)
140
template<class Y, class D> shared(Y* p, D d): my_parent(p, d) {}
143
explicit shared(one<Y> & r): my_parent(r.release()) {}
146
shared(const shared<Y>& r)
149
// 1 присваивание указателя
150
shared& operator =(T* ptr)
156
// кострукторы приведения
158
shared(const shared<Y>& r, boost::detail::static_cast_tag t)
162
shared(const shared<Y>& r, boost::detail::const_cast_tag t)
166
shared(const shared<Y>& r, boost::detail::dynamic_cast_tag t)
171
template<class T, class U> shared<T> static_pointer_cast(shared<U> const & r)
173
return shared<T>(r, boost::detail::static_cast_tag());
176
template<class T, class U> shared<T> const_pointer_cast(shared<U> const & r)
178
return shared<T>(r, boost::detail::const_cast_tag());
181
template<class T, class U> shared<T> dynamic_pointer_cast(shared<U> const & r)
183
return shared<T>(r, boost::detail::dynamic_cast_tag());
186
// Базовый класс для объектов с ссылками (=> intrusive_ptr)
189
typedef boost::shared_ptr<bool> shared_bool;
192
long use_count() const
198
void intrusive_ptr_add_ref(base * p)
204
void intrusive_ptr_release(base * p)
206
if(--p->use_count_ == 0) delete p;
210
shared_bool weak_indicator() { return is_exist_; }
215
base(): use_count_(0), is_exist_(new bool(true)) {}
223
//boost::detail::atomic_count use_count_;
225
shared_bool is_exist_;
228
base & operator=(base const &);
232
// ptr::weak_intrusive<>
233
// В связке с ptr::base дает аналог boost::weak_ptr<>, только
234
// для boost::intrusive_ptr<>
237
class weak_intrusive: public std::pair<T*, boost::shared_ptr<const bool> >
239
typedef boost::shared_ptr<const bool> bool_type;
240
typedef std::pair<T*, bool_type> my_parent;
241
typedef boost::intrusive_ptr<T> intrusive_ptr;
244
weak_intrusive(T* t = 0)
250
weak_intrusive(const weak_intrusive<Y> & r): my_parent(r) {}
253
weak_intrusive& operator = (const weak_intrusive<Y> & r)
255
this->first = r.first;
256
this->second = r.second;
261
weak_intrusive(const boost::intrusive_ptr<Y> & r)
266
intrusive_ptr lock() const { return intrusive_ptr( expired() ? 0 : this->first ); }
269
return !(*this->second);
277
this->second = this->first->weak_indicator();
279
this->second = bool_type(new const bool(false));
283
using boost::static_pointer_cast;
284
using boost::const_pointer_cast;
285
using boost::dynamic_pointer_cast;
290
#endif // __MLIB_PTR_H__