Lumiera  0.pre.03
»edit your freedom«
virtual-copy-support.hpp
Go to the documentation of this file.
1 /*
2  VIRTUAL-COPY-SUPPORT.hpp - helper to support copying of erased sub-types
3 
4  Copyright (C)
5  2015, 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 
14 
105 #ifndef LIB_META_VIRTUAL_COPY_SUPPORT_H
106 #define LIB_META_VIRTUAL_COPY_SUPPORT_H
107 
108 
109 #include "lib/error.hpp"
110 
111 #include <type_traits>
112 #include <utility>
113 
114 
115 namespace lib {
116 namespace meta{
117 
118  using std::move;
119 
120  using std::is_move_constructible;
121  using std::is_copy_constructible;
122  using std::is_copy_assignable;
123  using std::__and_;
124  using std::__not_;
125 
126  namespace error = lumiera::error;
127 
128 
129 
130  struct EmptyBase { };
131 
132  template<class IFA, class BASE = EmptyBase>
134  : public BASE
135  {
136  public:
137  virtual ~VirtualCopySupportInterface() { }
138 
139  virtual void copyInto (void* targetStorage) const =0;
140  virtual void moveInto (void* targetStorage) =0;
141  virtual void copyInto (IFA& target) const =0;
142  virtual void moveInto (IFA& target) =0;
143  };
144 
145 
146 
147  template<class I, class D, class B =I>
149  : public B
150  {
151  virtual void
152  copyInto (void*) const override
153  {
154  throw error::Logic{"Copy construction invoked but target is noncopyable"};
155  }
156 
157  virtual void
158  moveInto (void*) override
159  {
160  throw error::Logic{"Move construction invoked but target is noncopyable"};
161  }
162 
163  virtual void
164  copyInto (I&) const override
165  {
166  throw error::Logic{"Assignment invoked but target is not assignable"};
167  }
168 
169  virtual void
170  moveInto (I&) override
171  {
172  throw error::Logic{"Assignment invoked but target is not assignable"};
173  }
174  };
175 
176 
177  template<class I, class D, class B =I>
179  : public NoCopyMoveSupport<I,D,B>
180  {
181  virtual void
182  copyInto (void*) const override
183  {
184  throw error::Logic{"Copy construction invoked but target allows only move construction"};
185  }
186 
187  virtual void
188  moveInto (void* targetStorage) override
189  {
190  D& src = static_cast<D&> (*this);
191  new(targetStorage) D(move(src));
192  }
193  };
194 
195 
196  template<class I, class D, class B =I>
198  : public MoveSupport<I,D,B>
199  {
200  virtual void
201  copyInto (void* targetStorage) const override
202  {
203  D const& src = static_cast<D const&> (*this);
204  new(targetStorage) D(src);
205  }
206  };
207 
208 
209  template<class I, class D, class B =I>
211  : public CloneSupport<I,D,B>
212  {
213  virtual void
214  copyInto (I& target) const override
215  {
216  D& t = D::downcast(target);
217  D const& s = static_cast<D const&> (*this);
218  t = s;
219  }
220 
221  virtual void
222  moveInto (I& target) override
223  {
224  D& t = D::downcast(target);
225  D& s = static_cast<D&> (*this);
226  t = move(s);
227  }
228  };
229 
230 
231 
232 
233  namespace { // helpers to select suitable variant of copy support...
234 
235  template<class X>
237  : __and_<is_move_constructible<X>
238  ,__not_<is_copy_constructible<X>>
239  ,__not_<is_copy_assignable<X>>
240  >
241  { };
242 
243  template<class X>
245  : __and_<is_move_constructible<X>
246  ,is_copy_constructible<X>
247  ,__not_<is_copy_assignable<X>>
248  >
249  { };
250 
251  template<class X>
253  : __and_<is_move_constructible<X>
254  ,is_copy_constructible<X>
255  ,is_copy_assignable<X>
256  >
257  { };
258  }
259 
260 
261 
262 
266  template<class X, class SEL=void>
267  struct CopySupport
268  {
269  template<class I, class D, class B =I>
271  };
272 
273  template<class X>
274  struct CopySupport<X, enable_if<supports_only_move<X>> >
275  {
276  template<class I, class D, class B =I>
277  using Policy = MoveSupport<I,D,B>;
278  };
279 
280  template<class X>
281  struct CopySupport<X, enable_if<supports_cloning<X>> >
282  {
283  template<class I, class D, class B =I>
284  using Policy = CloneSupport<I,D,B>;
285  };
286 
287  template<class X>
288  struct CopySupport<X, enable_if<supports_copy_and_assignment<X>> >
289  {
290  template<class I, class D, class B =I>
292  };
293 
294 
295 
296 
297 }} // namespace lib::meta
298 #endif /*LIB_META_VIRTUAL_COPY_SUPPORT_H*/
Policy to pick a suitable implementation of "virtual copy operations".
Implementation namespace for support and library code.
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:83
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Lumiera error handling (C++ interface).