any.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016 Martin Moene
3 //
4 // https://github.com/martinmoene/any-lite
5 //
6 // This code is licensed under the MIT License (MIT).
7 //
8 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
13 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14 // THE SOFTWARE.
15 
16 #pragma once
17 
18 #ifndef NONSTD_ANY_LITE_HPP
19 #define NONSTD_ANY_LITE_HPP
20 
21 #include <typeinfo>
22 #include <utility>
23 
24 #define any_lite_VERSION "0.0.0"
25 
26 // any-lite configuration:
27 
28 // any-lite alignment configuration:
29 
30 // Compiler detection (C++17 is speculative):
31 
32 #define any_CPP11_OR_GREATER ( __cplusplus >= 201103L )
33 #define any_CPP14_OR_GREATER ( __cplusplus >= 201402L )
34 #define any_CPP17_OR_GREATER ( __cplusplus >= 201700L )
35 
36 // half-open range [lo..hi):
37 #define any_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
38 
39 #if defined(_MSC_VER) && !defined(__clang__)
40 # define any_COMPILER_MSVC_VERSION (_MSC_VER / 100 - 5 - (_MSC_VER < 1900))
41 #else
42 # define any_COMPILER_MSVC_VERSION 0
43 #endif
44 
45 #if defined __GNUC__
46 # define any_COMPILER_GNUC_VERSION __GNUC__
47 #else
48 # define any_COMPILER_GNUC_VERSION 0
49 #endif
50 
51 // Presence of C++11 language features:
52 
53 #if any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 10
54 # define any_HAVE_NULLPTR 1
55 #endif
56 
57 #if any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 12
58 # define any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
59 # define any_HAVE_INITIALIZER_LIST 1
60 #endif
61 
62 #if any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 14
63 # define any_HAVE_CONSTEXPR_11 1
64 # define any_HAVE_NOEXCEPT 1
65 #endif
66 
67 // Presence of C++14 language features:
68 
69 #if any_CPP14_OR_GREATER
70 # define any_HAVE_CONSTEXPR_14 1
71 #endif
72 
73 // Presence of C++17 language features:
74 
75 // Presence of C++ library features:
76 
77 #if any_COMPILER_GNUC_VERSION
78 # define any_HAVE_TR1_TYPE_TRAITS 1
79 # define any_HAVE_TR1_ADD_CONST 1
80 # define any_HAVE_TR1_REMOVE_REFERENCE 1
81 #endif
82 
83 #if any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 9
84 # define any_HAVE_TYPE_TRAITS 1
85 # define any_HAVE_STD_ADD_CONST 1
86 # define any_HAVE_STD_REMOVE_REFERENCE 1
87 #endif
88 
89 // For the rest, consider VC14 as C++11 for any-lite:
90 
91 #if any_COMPILER_MSVC_VERSION >= 14
92 # undef any_CPP11_OR_GREATER
93 # define any_CPP11_OR_GREATER 1
94 #endif
95 
96 // C++ feature usage:
97 
98 #if any_HAVE_CONSTEXPR_11
99 # define any_constexpr constexpr
100 #else
101 # define any_constexpr /*constexpr*/
102 #endif
103 
104 #if any_HAVE_CONSTEXPR_14
105 # define any_constexpr14 constexpr
106 #else
107 # define any_constexpr14 /*constexpr*/
108 #endif
109 
110 #if any_HAVE_NOEXCEPT
111 # define any_noexcept noexcept
112 #else
113 # define any_noexcept /*noexcept*/
114 #endif
115 
116 #if any_HAVE_NULLPTR
117 # define any_nullptr nullptr
118 #else
119 # define any_nullptr NULL
120 #endif
121 
122 // additional includes:
123 
124 #if ! any_HAVE_NULLPTR
125 # include <cstddef>
126 #endif
127 
128 #if any_HAVE_INITIALIZER_LIST
129 # include <initializer_list>
130 #endif
131 
132 #if any_HAVE_TYPE_TRAITS
133 # include <type_traits>
134 #elif any_HAVE_TR1_TYPE_TRAITS
135 # include <tr1/type_traits>
136 #endif
137 
138 //
139 // in_place: code duplicated in any-lite, optional-lite, variant-lite:
140 //
141 
142 #if ! nonstd_lite_HAVE_IN_PLACE_TYPES
143 
144 namespace nonstd {
145 
146 namespace detail {
147 
148 template< class T >
150 
151 template< std::size_t I >
153 
154 } // namespace detail
155 
156 struct in_place_t {};
157 
158 template< class T >
160 {
161  return in_place_t();
162 }
163 
164 template< std::size_t I >
166 {
167  return in_place_t();
168 }
169 
170 // mimic templated typedef:
171 
172 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
173 #define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<I> )
174 
175 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
176 
177 } // namespace nonstd
178 
179 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
180 
181 //
182 // any:
183 //
184 
185 namespace nonstd { namespace any_lite {
186 
187 namespace detail {
188 
189 // C++11 emulation:
190 
191 #if any_HAVE_STD_ADD_CONST
192 
193 using std::add_const;
194 
195 #elif any_HAVE_TR1_ADD_CONST
196 
197 using std::tr1::add_const;
198 
199 #else
200 
201 template< class T > struct add_const { typedef const T type; };
202 
203 #endif // any_HAVE_ADD_CONST
204 
205 #if any_HAVE_STD_REMOVE_REFERENCE
206 
207 using std::remove_reference;
208 
209 #elif any_HAVE_TR1_REMOVE_REFERENCE
210 
211 using std::tr1::remove_reference;
212 
213 #else
214 
215 template< class T > struct remove_reference { typedef T type; };
216 template< class T > struct remove_reference<T&> { typedef T type; };
217 
218 #endif // any_HAVE_STD_REMOVE_REFERENCE
219 
220 } // namespace detail
221 
222 class bad_any_cast : public std::bad_cast
223 {
224 public:
225 #if any_CPP11_OR_GREATER
226  virtual const char* what() const any_noexcept
227 #else
228  virtual const char* what() const throw()
229 #endif
230  {
231  return "any-lite: bad any_cast";
232  }
233 };
234 
235 class any
236 {
237 public:
239  : content( any_nullptr )
240  {}
241 
242  any( any const & rhs )
243  : content( rhs.content ? rhs.content->clone() : any_nullptr )
244  {}
245 
246 #if any_CPP11_OR_GREATER
247 
248  any( any && rhs ) any_noexcept
249  : content( std::move( rhs.content ) )
250  {
251  rhs.content = any_nullptr;
252  }
253 
254  template< class ValueType, class T = typename std::decay<ValueType>::type, typename = typename std::enable_if< ! std::is_same<T, any>::value >::type >
255  any( ValueType && value ) any_noexcept
256  : content( new holder<T>( std::forward<ValueType>( value ) ) )
257  {}
258 
259  template< class T, class... Args, typename = typename std::enable_if< std::is_constructible<T, Args...>::value >::type >
260  explicit any( nonstd_lite_in_place_type_t(T), Args&&... args )
261  : content( new holder<T>( T( std::forward<Args>(args)... ) ) )
262  {}
263 
264  template< class T, class U, class... Args, typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type >
265  explicit any( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
266  : content( new holder<T>( T( il, std::forward<Args>(args)... ) ) )
267  {}
268 
269 #else
270 
271  template< class ValueType >
272  any( ValueType const & value )
273  : content( new holder<ValueType>( value ) )
274  {}
275 
276 #endif // any_CPP11_OR_GREATER
277 
279  {
280  reset();
281  }
282 
283  any & operator=( any const & rhs )
284  {
285  any( rhs ).swap( *this );
286  return *this;
287  }
288 
289 #if any_CPP11_OR_GREATER
290 
291  any & operator=( any && rhs ) any_noexcept
292  {
293  any( std::move( rhs ) ).swap( *this );
294  return *this;
295  }
296 
297  template< class ValueType, class T = typename std::decay<ValueType>::type, typename = typename std::enable_if< ! std::is_same<T, any>::value >::type >
298  any & operator=( ValueType && rhs )
299  {
300  any( std::forward<ValueType>( rhs ) ).swap( *this );
301  return *this;
302  }
303 
304  template< class T, class... Args >
305  void emplace( Args && ... args )
306  {
307  any( T( std::forward<Args>(args)... ) ).swap( *this );
308  }
309 
310  template< class T, class U, class... Args, typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type >
311  void emplace( std::initializer_list<U> il, Args&&... args )
312  {
313  any( T( il, std::forward<Args>(args)... ) ).swap( *this );
314  }
315 
316 #else
317 
318  template< class ValueType >
319  any & operator=( ValueType const & rhs )
320  {
321  any( rhs ).swap( *this );
322  return *this;
323  }
324 
325 #endif // any_CPP11_OR_GREATER
326 
328  {
329  delete content; content = any_nullptr;
330  }
331 
332  void swap( any & rhs ) any_noexcept
333  {
334  std::swap( content, rhs.content );
335  }
336 
337  bool has_value() const any_noexcept
338  {
339  return content != any_nullptr;
340  }
341 
342  const std::type_info & type() const any_noexcept
343  {
344  return has_value() ? content->type() : typeid( void );
345  }
346 
347  //
348  // non-standard:
349  //
350 
351  template< class ValueType >
352  const ValueType * to_ptr() const
353  {
354  return &( static_cast<holder<ValueType> *>( content )->held );
355  }
356 
357  template< class ValueType >
358  ValueType * to_ptr()
359  {
360  return &( static_cast<holder<ValueType> *>( content )->held );
361  }
362 
363 private:
365  {
366  public:
367  virtual ~placeholder()
368  {
369  }
370 
371  virtual std::type_info const & type() const = 0;
372 
373  virtual placeholder * clone() const = 0;
374  };
375 
376  template< typename ValueType >
377  class holder : public placeholder
378  {
379  public:
380  holder( ValueType const & value )
381  : held( value )
382  {}
383 
384 #if any_CPP11_OR_GREATER
385  holder( ValueType && value )
386  : held( std::move( value ) )
387  {}
388 #endif
389 
390  virtual std::type_info const & type() const
391  {
392  return typeid( ValueType );
393  }
394 
395  virtual placeholder * clone() const
396  {
397  return new holder( held );
398  }
399 
400  ValueType held;
401  };
402 
404 };
405 
406 inline void swap( any & x, any & y ) any_noexcept
407 {
408  x.swap( y );
409 }
410 
411 #if any_CPP11_OR_GREATER
412 
413 template< class T, class ...Args >
414 inline any make_any( Args&& ...args )
415 {
416  return any( in_place<T>, std::forward<Args>(args)...);
417 }
418 
419 template< class T, class U, class ...Args >
420 inline any make_any( std::initializer_list<U> il, Args&& ...args )
421 {
422  return any( in_place<T>, il, std::forward<Args>(args)...);
423 }
424 
425 #endif // any_CPP11_OR_GREATER
426 
427 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
428 template< class ValueType, typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type >
429 #else
430 template< class ValueType >
431 #endif
432 inline ValueType any_cast( any const & operand )
433 {
434  const ValueType * result = any_cast< typename detail::add_const< typename detail::remove_reference<ValueType>::type >::type >( &operand );
435 
436  if ( ! result )
437  {
438  throw bad_any_cast();
439  }
440 
441  return *result;
442 }
443 
444 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
445 template< class ValueType, typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type >
446 #else
447 template< class ValueType >
448 #endif
449 inline ValueType any_cast( any & operand )
450 {
451  const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
452 
453  if ( ! result )
454  {
455  throw bad_any_cast();
456  }
457 
458  return *result;
459 }
460 
461 #if any_CPP11_OR_GREATER
462 
463 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
464 template< class ValueType, typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type >
465 #else
466 template< class ValueType >
467 #endif
468 inline ValueType any_cast( any && operand )
469 {
470  const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
471 
472  if ( ! result )
473  {
474  throw bad_any_cast();
475  }
476 
477  return *result;
478 }
479 
480 #endif // any_CPP11_OR_GREATER
481 
482 template< class ValueType >
483 inline ValueType const * any_cast( any const * operand ) any_noexcept
484 {
485  return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
486 }
487 
488 template<class ValueType >
489 inline ValueType * any_cast( any * operand ) any_noexcept
490 {
491  return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
492 }
493 
494 } // namespace any_lite
495 
496 using namespace any_lite;
497 
498 } // namespace nonstd
499 
500 #endif // NONSTD_ANY_LITE_HPP
void swap(any &x, any &y) any_noexcept
Definition: any.hpp:406
any & operator=(ValueType const &rhs)
Definition: any.hpp:319
bool has_value() const any_noexcept
Definition: any.hpp:337
const ValueType * to_ptr() const
Definition: any.hpp:352
ValueType * any_cast(any *operand) any_noexcept
Definition: any.hpp:489
any make_any(Args &&...args)
any(ValueType const &value)
Definition: any.hpp:272
any(any const &rhs)
Definition: any.hpp:242
TFSIMD_FORCE_INLINE const tfScalar & y() const
void reset() any_noexcept
Definition: any.hpp:327
virtual placeholder * clone() const
Definition: any.hpp:395
holder(ValueType const &value)
Definition: any.hpp:380
placeholder * content
Definition: any.hpp:403
virtual std::type_info const & type() const
Definition: any.hpp:390
#define any_noexcept
Definition: any.hpp:113
virtual const char * what() const
Definition: any.hpp:228
#define nonstd_lite_in_place_type_t(T)
Definition: any.hpp:172
T value
void swap(any &rhs) any_noexcept
Definition: any.hpp:332
#define any_constexpr
Definition: any.hpp:101
Definition: any.hpp:144
TFSIMD_FORCE_INLINE const tfScalar & x() const
ValueType * to_ptr()
Definition: any.hpp:358
#define any_nullptr
Definition: any.hpp:119
any_constexpr any() any_noexcept
Definition: any.hpp:238
any & operator=(any const &rhs)
Definition: any.hpp:283
const std::type_info & type() const any_noexcept
Definition: any.hpp:342
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: any.hpp:159


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:16