Lumiera  0.pre.03
»edit your freedom«
wrapper.hpp
Go to the documentation of this file.
1 /*
2  WRAPPER.hpp - some smart wrapping and reference managing helper templates
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
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.
16 
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
41 #ifndef LIB_WRAPPER_H
42 #define LIB_WRAPPER_H
43 
44 #include "lib/error.hpp"
45 #include "lib/nocopy.hpp"
46 #include "lib/meta/function.hpp"
48 #include "lib/meta/util.hpp"
49 #include "lib/util.hpp"
50 
51 #include <functional>
52 
53 
54 namespace lib {
55 namespace wrapper {
56 
57  using util::unConst;
58  using util::isSameObject;
59  using lib::meta::_Fun;
60  using lumiera::error::LERR_(BOTTOM_VALUE);
61 
62  using std::function;
63 
64 
65 
70  template<typename T>
71  class ReturnRef
72  {
73  T& ref_;
74 
75  public:
76  ReturnRef(T& target) : ref_(target) { }
77  T& operator() () const { return ref_;}
78  };
79 
80  template<typename T>
82  refFunction (T& target)
83  {
84  return ReturnRef<T> (target);
85  }
86 
87 
88 
89 
90 
91 
109  template<typename TY>
111  {
112 
113  using TY_unconst = std::remove_const_t<TY>;
114 
115 
116  mutable
117  char content_[sizeof(TY)];
118  bool created_;
119 
120  template<typename REF>
121  void
122  build (REF&& ref)
123  {
124  new(&content_) TY{std::forward<REF> (ref)};
125  created_ = true;
126  }
127 
128  void
129  discard ()
130  {
131  if (created_) access().~TY();
132  created_ = false;
133  }
134 
135  TY&
136  access () const
137  {
138  return reinterpret_cast<TY&> (content_);
139  }
140 
141  TY_unconst&
142  access_unconst() const
143  {
144  return const_cast<TY_unconst&> (access());
145  }
146 
147  public:
148  ItemWrapper()
149  : created_(false)
150  { }
151 
152  explicit
153  ItemWrapper(TY const& o)
154  : created_(false)
155  {
156  build (o);
157  }
158  explicit
159  ItemWrapper(TY && ro)
160  : created_(false)
161  {
162  build (std::move(ro));
163  }
164 
165  ~ItemWrapper()
166  {
167  discard();
168  }
169 
170 
171  /* == copy and assignment == */
172 
173  ItemWrapper (ItemWrapper const& ref)
174  : created_(false)
175  {
176  if (ref.isValid())
177  build (*ref);
178  }
179  ItemWrapper (ItemWrapper && rref)
180  : created_(false)
181  {
182  if (rref.isValid())
183  {
184  build (std::move (*rref));
185  rref.discard();
186  }
187  }
188 
189  ItemWrapper&
190  operator= (ItemWrapper const& cref)
191  {
192  if (!cref.isValid())
193  discard();
194  else
195  this->operator= (*cref);
196 
197  return *this;
198  }
199  ItemWrapper&
200  operator= (ItemWrapper & ref)
201  {
202  return *this = (ItemWrapper const&)ref;
203  }
204  ItemWrapper&
205  operator= (ItemWrapper && rref)
206  {
207  if (!rref.isValid())
208  discard();
209  else
210  {
211  this->operator= (std::move(*rref));
212  rref.discard();
213  }
214 
215  return *this;
216  }
217 
226  template<typename X>
227  ItemWrapper&
228  operator= (X&& something)
229  {
230  if (!isSameObject (something, access() ))
231  {
232  discard();
233  build (std::forward<X>(something));
234  }
235  return *this;
236  }
237 
239  ItemWrapper&
241  {
242  discard();
243  build (TY());
244  return *this;
245  }
246 
247  operator bool() const
248  {
249  return isValid();
250  }
251 
252 
253  /* == value access == */
254  TY&
255  operator* () const
256  {
257  if (!created_)
258  throw lumiera::error::State ("accessing uninitialised value/ref wrapper"
259  , LERR_(BOTTOM_VALUE));
260  return access();
261  }
262 
263  TY*
264  operator-> () const
265  {
266  return & **this;
267  }
268 
269  bool
270  isValid () const
271  {
272  return created_;
273  }
274 
275  void
276  reset ()
277  {
278  discard();
279  }
280  };
281 
282 
288  template<typename TY>
289  class ItemWrapper<TY &>
290  {
291 
292  TY * content_;
293 
294 
295  public:
296  ItemWrapper()
297  : content_()
298  { }
299 
300  explicit
301  ItemWrapper(TY& o)
302  : content_( &o )
303  { }
304 
305  // using default copy and assignment
306 
307  operator bool() const { return isValid(); }
308 
309 
311  ItemWrapper&
312  operator= (TY& otherRef)
313  {
314  content_ = &otherRef;
315  return *this;
316  }
317 
318  ItemWrapper&
319  defaultInit()
320  {
321  reset();
322  return *this;
323  }
324 
325 
326  /* == value access == */
327  TY&
328  operator* () const
329  {
330  if (!content_)
331  throw lumiera::error::State ("accessing uninitialised reference wrapper"
332  , LERR_(BOTTOM_VALUE));
333  return *content_;
334  }
335 
336  bool
337  isValid () const
338  {
339  return bool(content_);
340  }
341 
342  void
343  reset ()
344  {
345  content_ = 0;
346  }
347  };
348 
349 
355  template<>
356  class ItemWrapper<void>
357  {
358  public:
359  ItemWrapper()
360  { }
361 
362  // using default copy and assignment
363 
364  operator bool() const { return true; }
365  bool isValid () const { return true; }
366  void reset () { /* NOP */ }
367 
369  void operator*() const { /* NOP */ }
370 
371  ItemWrapper&
372  defaultInit()
373  {
374  return *this;
375  }
376  };
377 
378 
379 
381  template<typename TY>
382  inline bool
384  {
385  return (!w1 && !w2)
386  || ( w1 && w2 && (*w1)==(*w2));
387  }
388  template<typename TY>
389  inline bool
390  operator!= (ItemWrapper<TY> const& w1, ItemWrapper<TY> const& w2)
391  {
392  return not (w1 == w2);
393  }
394 
395 
396 
397 
409  template<typename SIG>
411  : public function<SIG>
413  {
414  using Res = typename _Fun<SIG>::Ret;
416 
417  ResWrapper lastResult_;
418 
419 
420  Res
421  captureResult (Res res)
422  {
423  lastResult_ = res;
424  return res;
425  }
426 
427  public:
431 
442  template<typename FUN>
443  FunctionResult (FUN targetFunction)
444  {
445  using std::bind;
446  using std::placeholders::_1;
447  using lib::meta::func::chained;
448  // note: binding "this" mandates noncopyable
449  function<Res(Res)> doCaptureResult = bind (&FunctionResult::captureResult, this, _1 );
450  function<SIG> chainedWithResCapture = chained (targetFunction, doCaptureResult);
451 
452  function<SIG>::operator= (chainedWithResCapture); // define the function (baseclass)
453  }
454 
455 
456  Res& operator*() const { return *lastResult_; }
457  bool isValid () const { return lastResult_.isValid(); }
458 
459  explicit
460  operator bool() const { return isValid(); }
461  };
462 
463 
464 }} // namespace lib::wrap
465 #endif
Reference wrapper implemented as constant function, returning the (fixed) reference on invocation...
Definition: wrapper.hpp:71
FunctionResult()
default ctor yields an object locked to invalid state
Definition: wrapper.hpp:430
TY_unconst & access_unconst() const
< used to assign new buffer contents
Definition: wrapper.hpp:142
Simple and lightweight helpers for metaprogramming and type detection.
Extension of ItemWrapper: a function remembering the result of the last invocation.
Definition: wrapper.hpp:410
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
Helper for uniform access to function signature types.
Definition: function.hpp:108
Partial function application and building a complete function closure.
Universal value/ref wrapper accessible similar to a pointer.
Definition: wrapper.hpp:110
Implementation namespace for support and library code.
ItemWrapper & defaultInit()
implant a default-initialised instance of the payload type
Definition: wrapper.hpp:240
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:196
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Metaprogramming tools for transforming functor types.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Lumiera error handling (C++ interface).
FunctionResult(FUN targetFunction)
Create result-remembering functor by binding the given function.
Definition: wrapper.hpp:443
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:347