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 #include <cstddef>
53 
54 
55 namespace lib {
56 namespace wrapper {
57 
58  using util::unConst;
59  using util::isSameObject;
60  using lib::meta::_Fun;
61  using LERR_(BOTTOM_VALUE);
62 
63  using std::function;
64 
65 
66 
71  template<typename T>
72  class ReturnRef
73  {
74  T& ref_;
75 
76  public:
77  ReturnRef(T& target) : ref_(target) { }
78  T& operator() () const { return ref_;}
79  };
80 
81  template<typename T>
83  refFunction (T& target)
84  {
85  return ReturnRef<T> (target);
86  }
87 
88 
89 
90 
91 
92 
110  template<typename TY>
112  {
113 
114  using TY_unconst = std::remove_const_t<TY>;
115 
116 
117  alignas(TY) mutable
118  std::byte content_[sizeof(TY)];
119 
120  bool created_;
121 
122  template<typename REF>
123  void
124  build (REF&& ref)
125  {
126  new(&content_) TY{std::forward<REF> (ref)};
127  created_ = true;
128  }
129 
130  void
131  discard ()
132  {
133  if (created_) access().~TY();
134  created_ = false;
135  }
136 
137  TY&
138  access () const
139  {
140  return * std::launder (reinterpret_cast<TY*> (&content_));
141  }
142 
143  TY_unconst&
144  access_unconst() const
145  {
146  return const_cast<TY_unconst&> (access());
147  }
148 
149  public:
150  ItemWrapper()
151  : created_(false)
152  { }
153 
154  explicit
155  ItemWrapper(TY const& o)
156  : created_(false)
157  {
158  build (o);
159  }
160  explicit
161  ItemWrapper(TY && ro)
162  : created_(false)
163  {
164  build (std::move(ro));
165  }
166 
167  ~ItemWrapper()
168  {
169  discard();
170  }
171 
172 
173  /* == copy and assignment == */
174 
175  ItemWrapper (ItemWrapper const& ref)
176  : created_(false)
177  {
178  if (ref.isValid())
179  build (*ref);
180  }
181  ItemWrapper (ItemWrapper && rref)
182  : created_(false)
183  {
184  if (rref.isValid())
185  {
186  build (std::move (*rref));
187  rref.discard();
188  }
189  }
190 
191  ItemWrapper&
192  operator= (ItemWrapper const& cref)
193  {
194  if (!cref.isValid())
195  discard();
196  else
197  this->operator= (*cref);
198 
199  return *this;
200  }
201  ItemWrapper&
202  operator= (ItemWrapper & ref)
203  {
204  return *this = (ItemWrapper const&)ref;
205  }
206  ItemWrapper&
207  operator= (ItemWrapper && rref)
208  {
209  if (!rref.isValid())
210  discard();
211  else
212  {
213  this->operator= (std::move(*rref));
214  rref.discard();
215  }
216 
217  return *this;
218  }
219 
228  template<typename X>
229  ItemWrapper&
230  operator= (X&& something)
231  {
232  if (!isSameObject (something, access() ))
233  {
234  discard();
235  build (std::forward<X>(something));
236  }
237  return *this;
238  }
239 
241  ItemWrapper&
243  {
244  discard();
245  build (TY());
246  return *this;
247  }
248 
249  operator bool() const
250  {
251  return isValid();
252  }
253 
254 
255  /* == value access == */
256  TY&
257  operator* () const
258  {
259  if (!created_)
260  throw lumiera::error::State ("accessing uninitialised value/ref wrapper"
261  , LERR_(BOTTOM_VALUE));
262  return access();
263  }
264 
265  TY*
266  operator-> () const
267  {
268  return & **this;
269  }
270 
271  bool
272  isValid () const
273  {
274  return created_;
275  }
276 
277  void
278  reset ()
279  {
280  discard();
281  }
282  };
283 
284 
290  template<typename TY>
291  class ItemWrapper<TY &>
292  {
293 
294  TY * content_;
295 
296 
297  public:
298  ItemWrapper()
299  : content_()
300  { }
301 
302  explicit
303  ItemWrapper(TY& o)
304  : content_( &o )
305  { }
306 
307  // using default copy and assignment
308 
309  operator bool() const { return isValid(); }
310 
311 
313  ItemWrapper&
314  operator= (TY& otherRef)
315  {
316  content_ = &otherRef;
317  return *this;
318  }
319 
320  ItemWrapper&
321  defaultInit()
322  {
323  reset();
324  return *this;
325  }
326 
327 
328  /* == value access == */
329  TY&
330  operator* () const
331  {
332  if (!content_)
333  throw lumiera::error::State ("accessing uninitialised reference wrapper"
334  , LERR_(BOTTOM_VALUE));
335  return *content_;
336  }
337 
338  bool
339  isValid () const
340  {
341  return bool(content_);
342  }
343 
344  void
345  reset ()
346  {
347  content_ = 0;
348  }
349  };
350 
351 
357  template<>
358  class ItemWrapper<void>
359  {
360  public:
361  ItemWrapper()
362  { }
363 
364  // using default copy and assignment
365 
366  operator bool() const { return true; }
367  bool isValid () const { return true; }
368  void reset () { /* NOP */ }
369 
371  void operator*() const { /* NOP */ }
372 
373  ItemWrapper&
374  defaultInit()
375  {
376  return *this;
377  }
378  };
379 
380 
381 
383  template<typename TY>
384  inline bool
386  {
387  return (!w1 && !w2)
388  || ( w1 && w2 && (*w1)==(*w2));
389  }
390  template<typename TY>
391  inline bool
392  operator!= (ItemWrapper<TY> const& w1, ItemWrapper<TY> const& w2)
393  {
394  return not (w1 == w2);
395  }
396 
397 
398 
399 
409  template<typename SIG>
411  : public function<SIG>
413  {
414  using Res = typename _Fun<SIG>::Ret;
416 
417  ResWrapper lastResult_;
418 
419  public:
421  FunctionResult() = default;
422 
429  template<typename FUN>
430  FunctionResult (FUN&& targetFunction)
431  : function<SIG>{lib::meta::func::chained
432  ( std::forward<FUN> (targetFunction)
433  , [this](Res res) -> Res
434  {
435  lastResult_ = res;
436  return std::forward<Res> (res);
437  })}
438  { }
439 
441  Res& operator*() const { return *lastResult_; }
442  bool isValid () const { return lastResult_.isValid(); }
443 
444  explicit
445  operator bool() const { return isValid(); }
446  };
447 
448 
449 }} // namespace lib::wrap
450 #endif
Reference wrapper implemented as constant function, returning the (fixed) reference on invocation...
Definition: wrapper.hpp:72
TY_unconst & access_unconst() const
< used to assign new buffer contents
Definition: wrapper.hpp:144
Simple and lightweight helpers for metaprogramming and type detection.
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
FunctionResult(FUN &&targetFunction)
Create result-remembering functor by outfitting a copy of the given function with an adaptor to captu...
Definition: wrapper.hpp:430
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:111
Implementation namespace for support and library code.
ItemWrapper & defaultInit()
implant a default-initialised instance of the payload type
Definition: wrapper.hpp:242
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
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...
Extension of ItemWrapper: a function remembering the result of the last invocation.
Definition: wrapper.hpp:410
Lumiera error handling (C++ interface).
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:372