Lumiera  0.pre.03
»edit your freedom«
scoped-holder.hpp
Go to the documentation of this file.
1 /*
2  SCOPED-HOLDER.hpp - general purpose wrapper for dealing with ownership problems
3 
4  Copyright (C)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
48 #ifndef LIB_SCOPED_HOLDER_H
49 #define LIB_SCOPED_HOLDER_H
50 
51 #include "lib/error.hpp"
52 
53 #include <memory>
54 
55 
56 namespace lib {
57 
58 
59 
60 
66  template<class B>
68  : public std::unique_ptr<B>
69  {
70  typedef std::unique_ptr<B> _Parent;
71 
72  static B* must_be_null (_Parent const& ptr)
73  {
74  if (ptr)
75  throw lumiera::error::Logic("ScopedPtrHolder protocol violation: "
76  "attempt to copy from non-null.");
77  return 0;
78  }
79 
80  public:
82  : _Parent{}
83  { }
84 
85  template<class SU>
86  explicit ScopedPtrHolder (SU * p) // never throws
87  : _Parent(p)
88  { }
89 
90  template<class SU>
91  explicit ScopedPtrHolder (std::unique_ptr<SU> pu) // never throws
92  : _Parent(pu.release())
93  { }
94 
95  ScopedPtrHolder (ScopedPtrHolder const& ref)
96  : _Parent(must_be_null (ref))
97  { }
98 
100  operator= (ScopedPtrHolder const& ref)
101  {
102  must_be_null (*this);
103  must_be_null (ref);
104  return *this;
105  }
106 
107  friend void
108  transfer_control (ScopedPtrHolder& from, ScopedPtrHolder& to)
109  {
110  if (!from) return;
111  TRACE (test, "transfer_control<ScopedPtrHolder>... from=%p to=%p",&from, &to);
112  must_be_null (to);
113  to.swap(from);
114  }
115  };
116 
117 
118 
119 
133  template<class TY>
135  {
136  char content_[sizeof(TY)];
137  char created_;
138 
139 
140  static char
141  must_be_empty (ScopedHolder<TY> const& ref)
142  {
143  if (ref)
144  throw lumiera::error::Logic("ScopedHolder protocol violation: "
145  "copy operation after having invoked create().");
146  return 0;
147  }
148 
149  public:
150  ScopedHolder()
151  : created_(0)
152  { }
153 
154  ~ScopedHolder() { clear(); }
155 
156 
157  TY&
158  create ()
159  {
160  ASSERT (!created_);
161  TY * obj = new(content_) TY();
162  ++created_;
163  return *obj;
164  }
165 
166  TY&
167  create (TY const& o)
168  {
169  ASSERT (!created_);
170  TY * obj = new(content_) TY(o);
171  ++created_;
172  return *obj;
173  }
174 
175  void
176  clear ()
177  {
178  if (created_)
179  get()->~TY();
180  created_ = false;
181  }
182 
183 
184  ScopedHolder (ScopedHolder const& ref)
185  : created_(must_be_empty (ref))
186  { }
187 
188  ScopedHolder&
189  operator= (ScopedHolder const& ref)
190  {
191  must_be_empty (*this);
192  must_be_empty (ref);
193  return *this;
194  }
195 
196 
197  TY&
198  operator* () const
199  {
200  ASSERT (created_);
201  return (TY&) content_;
202  }
203 
204  TY*
205  operator-> () const
206  {
207  ASSERT (created_);
208  return (TY*) &content_;
209  }
210 
211  TY* get() const // never throws
212  {
213  return (TY*) &content_;
214  }
215 
216 
217 
218  explicit operator bool() const { return created_; }
219  bool operator! () const { return not created_; }
220 
221 
222  friend void
223  transfer_control (ScopedHolder& from, ScopedHolder& to)
224  {
225  if (!from) return;
226  TRACE (test, "transfer_control<ScopedHolder>... from=%p to=%p",&from, &to);
227  must_be_empty (to);
228  to.create();
229  try
230  {
231  transfer_control(*from,*to); // note: assumed to have no side-effect in case it throws
232  from.clear();
233  return;
234  }
235  catch(...)
236  {
237  to.clear();
238  WARN (test, "transfer_control operation aborted.");
239  throw;
240  }
241  }
242  };
243 
244 
245 
246 
247 } // namespace lib
248 #endif
Definition: run.hpp:40
Implementation namespace for support and library code.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Inline buffer holding and owning an object similar to unique_ptr.
TY & create(TY const &o)
Lumiera error handling (C++ interface).
Extension to std::unique_ptr, allowing copy operations on empty pointers (i.e.