RefCounted.h
1 /*
2  * Copyright (C) 2006 by Marc Boris Duerner
3  * Copyright (C) 2010-2010 by Aloysius Indrayanto
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * As a special exception, you may use this file as part of a free
11  * software library without restriction. Specifically, if other files
12  * instantiate templates or use macros or inline functions from this
13  * file, or you compile this file and link it with other files to
14  * produce an executable, this file does not by itself cause the
15  * resulting executable to be covered by the GNU General Public
16  * License. This exception does not however invalidate any other
17  * reasons why the executable file might be covered by the GNU Library
18  * General Public License.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28  */
29 
30 #ifndef PT_REFCOUNTED_H
31 #define PT_REFCOUNTED_H
32 
33 #include <Pt/Api.h>
34 #include <Pt/Atomicity.h>
35 #include <Pt/NonCopyable.h>
36 
37 namespace Pt {
38 
39 class RefCounted : private NonCopyable
40 {
41  public:
42  RefCounted()
43  : _refs(0)
44  { }
45 
46  explicit RefCounted(unsigned refs)
47  : _refs(refs)
48  { }
49 
50  virtual ~RefCounted()
51  { }
52 
53  virtual unsigned addRef()
54  { return ++_refs; }
55 
56  virtual void release()
57  {
58  if(--_refs == 0)
59  delete this;
60  }
61 
62  unsigned refs() const
63  { return _refs; }
64 
65  private:
66  unsigned _refs;
67 };
68 
69 class AtomicRefCounted : private NonCopyable
70 {
71  public:
72  AtomicRefCounted()
73  : _refs(0)
74  { }
75 
76  explicit AtomicRefCounted(unsigned refs)
77  : _refs(refs)
78  { }
79 
80  virtual ~AtomicRefCounted()
81  { }
82 
83  virtual int addRef()
84  { return atomicIncrement(_refs); }
85 
86  virtual void release()
87  { if (atomicDecrement(_refs) == 0) delete this; }
88 
89  int refs() const
90  { return atomicGet(_refs); }
91 
92  private:
93  mutable volatile atomic_t _refs;
94 };
95 
96 } // namespace Pt
97 
98 #endif // PT_REFCOUNTED_H
99