11 #ifndef NONSTD_ANY_LITE_HPP
12 #define NONSTD_ANY_LITE_HPP
14 #define any_lite_MAJOR 0
15 #define any_lite_MINOR 1
16 #define any_lite_PATCH 0
18 #define any_lite_VERSION any_STRINGIFY(any_lite_MAJOR) "." any_STRINGIFY(any_lite_MINOR) "." any_STRINGIFY(any_lite_PATCH)
20 #define any_STRINGIFY( x ) any_STRINGIFY_( x )
21 #define any_STRINGIFY_( x ) #x
25 #define any_ANY_DEFAULT 0
26 #define any_ANY_NONSTD 1
29 #if !defined( any_CONFIG_SELECT_ANY )
30 # define any_CONFIG_SELECT_ANY ( any_HAVE_STD_ANY ? any_ANY_STD : any_ANY_NONSTD )
35 #ifndef any_CONFIG_NO_EXCEPTIONS
36 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
37 # define any_CONFIG_NO_EXCEPTIONS 0
39 # define any_CONFIG_NO_EXCEPTIONS 1
47 # if defined(_MSVC_LANG ) && !defined(__clang__)
48 # define any_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
50 # define any_CPLUSPLUS __cplusplus
54 #define any_CPP98_OR_GREATER ( any_CPLUSPLUS >= 199711L )
55 #define any_CPP11_OR_GREATER ( any_CPLUSPLUS >= 201103L )
56 #define any_CPP14_OR_GREATER ( any_CPLUSPLUS >= 201402L )
57 #define any_CPP17_OR_GREATER ( any_CPLUSPLUS >= 201703L )
58 #define any_CPP20_OR_GREATER ( any_CPLUSPLUS >= 202000L )
62 #if any_CPP17_OR_GREATER && defined(__has_include )
63 # if __has_include( <any> )
64 # define any_HAVE_STD_ANY 1
66 # define any_HAVE_STD_ANY 0
69 # define any_HAVE_STD_ANY 0
72 #define any_USES_STD_ANY ( (any_CONFIG_SELECT_ANY == any_ANY_STD) || ((any_CONFIG_SELECT_ANY == any_ANY_DEFAULT) && any_HAVE_STD_ANY) )
78 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
79 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
83 #if any_CPP17_OR_GREATER
92 using std::in_place_t;
93 using std::in_place_type_t;
94 using std::in_place_index_t;
96 #define nonstd_lite_in_place_t( T) std::in_place_t
97 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
98 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
100 #define nonstd_lite_in_place( T) std::in_place_t{}
101 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
102 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
106 #else // any_CPP17_OR_GREATER
116 template< std::
size_t K >
129 template< std::
size_t K >
141 template< std::
size_t K >
149 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
150 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
151 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
153 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
154 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
155 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
159 #endif // any_CPP17_OR_GREATER
160 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
177 using std::bad_any_cast;
180 #else // any_USES_STD_ANY
197 #if defined(_MSC_VER ) && !defined(__clang__)
198 # define any_COMPILER_MSVC_VER (_MSC_VER )
199 # define any_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
201 # define any_COMPILER_MSVC_VER 0
202 # define any_COMPILER_MSVC_VERSION 0
205 #define any_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
207 #if defined(__clang__)
208 # define any_COMPILER_CLANG_VERSION any_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
210 # define any_COMPILER_CLANG_VERSION 0
213 #if defined(__GNUC__) && !defined(__clang__)
214 # define any_COMPILER_GNUC_VERSION any_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
216 # define any_COMPILER_GNUC_VERSION 0
224 #define any_HAVE( feature ) ( any_HAVE_##feature )
227 # define any_HAS_CPP0X _HAS_CPP0X
229 # define any_HAS_CPP0X 0
232 #define any_CPP11_90 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1500)
233 #define any_CPP11_100 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1600)
234 #define any_CPP11_120 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1800)
235 #define any_CPP11_140 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1900)
237 #define any_CPP14_000 (any_CPP14_OR_GREATER)
238 #define any_CPP17_000 (any_CPP17_OR_GREATER)
242 #define any_HAVE_CONSTEXPR_11 any_CPP11_140
243 #define any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG \
245 #define any_HAVE_INITIALIZER_LIST any_CPP11_120
246 #define any_HAVE_NOEXCEPT any_CPP11_140
247 #define any_HAVE_NULLPTR any_CPP11_100
248 #define any_HAVE_TYPE_TRAITS any_CPP11_90
249 #define any_HAVE_STATIC_ASSERT any_CPP11_100
250 #define any_HAVE_ADD_CONST any_CPP11_90
251 #define any_HAVE_REMOVE_REFERENCE any_CPP11_90
253 #define any_HAVE_TR1_ADD_CONST (!! any_COMPILER_GNUC_VERSION )
254 #define any_HAVE_TR1_REMOVE_REFERENCE (!! any_COMPILER_GNUC_VERSION )
255 #define any_HAVE_TR1_TYPE_TRAITS (!! any_COMPILER_GNUC_VERSION )
259 #define any_HAVE_CONSTEXPR_14 any_CPP14_000
263 #define any_HAVE_NODISCARD any_CPP17_000
267 #if any_HAVE_CONSTEXPR_11
268 # define any_constexpr constexpr
270 # define any_constexpr
273 #if any_HAVE_CONSTEXPR_14
274 # define any_constexpr14 constexpr
276 # define any_constexpr14
279 #if any_HAVE_NOEXCEPT
280 # define any_noexcept noexcept
282 # define any_noexcept
286 # define any_nullptr nullptr
288 # define any_nullptr NULL
291 #if any_HAVE_NODISCARD
292 # define any_nodiscard [[nodiscard]]
294 # define any_nodiscard
299 #if any_CONFIG_NO_EXCEPTIONS
305 #if ! any_HAVE_NULLPTR
309 #if any_HAVE_INITIALIZER_LIST
310 # include <initializer_list>
313 #if any_HAVE_TYPE_TRAITS
314 # include <type_traits>
315 #elif any_HAVE_TR1_TYPE_TRAITS
316 # include <tr1/type_traits>
321 #if any_CPP11_OR_GREATER
323 #define any_REQUIRES_0(...) \
324 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
326 #define any_REQUIRES_T(...) \
327 , typename = typename std::enable_if< (__VA_ARGS__), nonstd::any_lite::detail::enabler >::type
329 #define any_REQUIRES_R(R, ...) \
330 typename std::enable_if<__VA_ARGS__, R>::type
332 #define any_REQUIRES_A(...) \
333 , typename std::enable_if<__VA_ARGS__, void*>::type = nullptr
347 #if any_HAVE_ADD_CONST
349 using std::add_const;
351 #elif any_HAVE_TR1_ADD_CONST
353 using std::tr1::add_const;
359 #endif // any_HAVE_ADD_CONST
361 #if any_HAVE_REMOVE_REFERENCE
363 using std::remove_reference;
365 #elif any_HAVE_TR1_REMOVE_REFERENCE
367 using std::tr1::remove_reference;
374 #endif // any_HAVE_REMOVE_REFERENCE
386 #if ! any_CONFIG_NO_EXCEPTIONS
388 class bad_any_cast :
public std::bad_cast
391 #if any_CPP11_OR_GREATER
394 virtual const char* what()
const throw()
397 return "any-lite: bad any_cast";
401 #endif // any_CONFIG_NO_EXCEPTIONS
411 : content( other.content ? other.content->clone() :
any_nullptr )
414 #if any_CPP11_OR_GREATER
423 class ValueType,
class T =
typename std::decay<ValueType>::type
424 any_REQUIRES_T( ! std::is_same<T, any>::value )
427 : content(
new holder<T>(
std::move( value ) ) )
431 class T,
class... Args
432 any_REQUIRES_T( std::is_constructible<T, Args&&...>::value )
435 : content( new holder<T>( T( std::forward<Args>(args)... ) ) )
439 class T,
class U,
class... Args
440 any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
443 : content( new holder<T>( T( il, std::forward<Args>(args)... ) ) )
448 template<
class ValueType >
449 any( ValueType
const & value )
450 : content( new holder<ValueType>( value ) )
453 #endif // any_CPP11_OR_GREATER
462 any( other ).swap( *
this );
466 #if any_CPP11_OR_GREATER
475 class ValueType,
class T =
typename std::decay<ValueType>::type
476 any_REQUIRES_T( ! std::is_same<T, any>::value )
484 template<
class T,
class... Args >
485 void emplace( Args && ... args )
487 any( T( std::forward<Args>(args)... ) ).swap( *
this );
491 class T,
class U,
class... Args
492 any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
494 void emplace( std::initializer_list<U> il, Args&&... args )
496 any( T( il, std::forward<Args>(args)... ) ).swap( *
this );
501 template<
class ValueType >
504 any( value ).swap( *
this );
508 #endif // any_CPP11_OR_GREATER
527 return has_value() ? content->type() :
typeid( void );
534 template<
class ValueType >
537 return &(
static_cast<holder<ValueType> *
>( content )->held );
540 template<
class ValueType >
543 return &(
static_cast<holder<ValueType> *
>( content )->held );
550 virtual ~placeholder()
554 virtual std::type_info
const &
type()
const = 0;
556 virtual placeholder * clone()
const = 0;
559 template<
typename ValueType >
560 class holder :
public placeholder
563 holder( ValueType
const & value )
567 #if any_CPP11_OR_GREATER
568 holder( ValueType && value )
569 : held( std::
move( value ) )
573 virtual std::type_info
const &
type()
const
575 return typeid( ValueType );
578 virtual placeholder * clone()
const
580 return new holder( held );
586 placeholder * content;
594 #if any_CPP11_OR_GREATER
596 template<
class T,
class ...Args >
597 inline any make_any( Args&& ...args )
602 template<
class T,
class U,
class ...Args >
603 inline any make_any( std::initializer_list<U> il, Args&& ...args )
608 #endif // any_CPP11_OR_GREATER
612 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
614 ,
typename =
typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value),
nonstd::any_lite::detail::enabler >::type
619 const ValueType * result = any_cast< typename std11::add_const< typename std11::remove_reference<ValueType>::type >::type >( &operand );
621 #if any_CONFIG_NO_EXCEPTIONS
626 throw bad_any_cast();
635 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
637 ,
typename =
typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value),
nonstd::any_lite::detail::enabler >::type
642 const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
644 #if any_CONFIG_NO_EXCEPTIONS
649 throw bad_any_cast();
656 #if any_CPP11_OR_GREATER
660 #if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
661 any_REQUIRES_T( std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value )
666 const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
668 #if any_CONFIG_NO_EXCEPTIONS
673 throw bad_any_cast();
680 #endif // any_CPP11_OR_GREATER
682 template<
class ValueType >
688 template<
class ValueType >
696 using namespace any_lite;
700 #endif // any_USES_STD_ANY
702 #endif // NONSTD_ANY_LITE_HPP