strusBase  0.17
reference.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Patrick P. Frey
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
10 #ifndef _STRUS_REFERENCE_HPP_INCLUDED
11 #define _STRUS_REFERENCE_HPP_INCLUDED
12 #include <cstdlib>
13 #include <stdexcept>
14 #include <new>
15 
16 namespace strus
17 {
18 
21 template <class Object>
22 class Reference
23 {
24 public:
27  :m_obj(0),m_refcnt(0){}
29  Reference( Object* obj_, bool doThrow=true)
30  :m_obj(0),m_refcnt(0)
31  {
32  if (obj_) try
33  {
34  m_refcnt = newRefCnt();
35  m_obj = obj_;
36  }
37  catch (const std::bad_alloc&)
38  {
39  delete obj_;
40  if (doThrow) throw std::bad_alloc();
41  }
42  }
44  Reference( const Reference& o)
45  :m_obj(o.m_obj),m_refcnt(o.m_refcnt)
46  {
47  if (m_refcnt) ++*m_refcnt;
48  }
49 
52  {
53  freeRef();
54  }
55 
58  {
59  m_obj = o.m_obj;
60  m_refcnt = o.m_refcnt;
61  if (m_refcnt) ++*m_refcnt;
62  return *this;
63  }
64 
66  void reset( Object* obj_=0)
67  {
68  if (!m_refcnt)
69  {
70  if (obj_)
71  {
72  try
73  {
74  m_refcnt = newRefCnt();
75  }
76  catch (const std::bad_alloc&)
77  {
78  delete obj_;
79  return;
80  }
81  }
82  }
83  else if (*m_refcnt == 1)
84  {
85  delete m_obj;
86  }
87  else if (obj_)
88  {
89  int* rc = newRefCnt();
90  freeRef();
91  m_refcnt = rc;
92  }
93  else
94  {
95  freeRef();
96  m_refcnt = 0;
97  }
98  m_obj = obj_;
99  }
100 
102  Object* operator->() {return m_obj;}
104  const Object* operator->() const {return m_obj;}
106  Object& operator*() {return *m_obj;}
108  const Object& operator*() const {return *m_obj;}
109 
111  const Object* get() const {return m_obj;}
113  Object* get() {return m_obj;}
114 
117  Object* release()
118  {
119  if (m_refcnt && *m_refcnt == 1)
120  {
121  --*m_refcnt;
122  Object* rt = m_obj;
123  std::free( m_refcnt);
124  m_refcnt = 0;
125  m_obj = 0;
126  return rt;
127  }
128  else if (m_refcnt)
129  {
130  throw std::logic_error( "cannot release shared object (having more than one reference)");
131  }
132  else
133  {
134  return 0;
135  }
136  }
137 
138  unsigned int refcnt() const
139  {
140  return m_refcnt?(*m_refcnt):0;
141  }
142 
143 private:
144  int* newRefCnt()
145  {
146  int* rt = (int*)std::malloc(sizeof(int));
147  if (!rt) throw std::bad_alloc();
148  *rt = 1;
149  return rt;
150  }
151  void freeRef()
152  {
153  if (m_refcnt && --*m_refcnt == 0)
154  {
155  delete m_obj;
156  std::free( m_refcnt);
157  m_refcnt = 0;
158  m_obj = 0;
159  }
160  }
161 
162 private:
163  Object* m_obj;
164  mutable int* m_refcnt;
165 };
166 
167 }
168 #endif
169 
Reference()
Default constructor.
Definition: reference.hpp:26
Object * operator->()
Object access operator.
Definition: reference.hpp:102
void reset(Object *obj_=0)
Reinitialize the local value of the reference and dispose the old value if not referenced by others...
Definition: reference.hpp:66
Object & operator*()
Object access operator.
Definition: reference.hpp:106
Object * release()
Release object reference and return the pointer to the object (with ownership) if this is possible...
Definition: reference.hpp:117
Shared pointer template with non thread-safe reference counting.
Definition: reference.hpp:22
~Reference()
Destructor.
Definition: reference.hpp:51
Reference & operator=(const Reference &o)
Assignment operator.
Definition: reference.hpp:57
Reference(const Reference &o)
Copy constructor.
Definition: reference.hpp:44
unsigned int refcnt() const
Definition: reference.hpp:138
const Object & operator*() const
Object access operator.
Definition: reference.hpp:108
const Object * operator->() const
Object access operator.
Definition: reference.hpp:104
Reference(Object *obj_, bool doThrow=true)
Constructor.
Definition: reference.hpp:29