55#ifndef INCLUDE_KI_ANY_H_
56#define INCLUDE_KI_ANY_H_
58#include <initializer_list>
82 const char*
what() const noexcept
override {
return "bad ki::any_cast"; }
106 template <
typename T,
bool Safe = std::is_nothrow_move_constructible_v<T>,
107 bool Fits = ( sizeof( T ) <= sizeof( Storage ) )
108 && ( alignof( T ) <= alignof( Storage ) )>
109 using Use_Internal_Storage = std::
integral_constant<
bool, Safe && Fits>;
111 template <
typename T>
114 template <
typename T>
117 template <
typename T>
121 template <
typename T,
typename V = std::decay_t<T>>
125 template <
typename T,
typename... Args,
typename Mgr =
Manager<T>>
129 Mgr::do_create(
m_storage, std::forward<Args>( args )... );
134 template <
typename T,
typename U,
typename... Args,
typename Mgr =
Manager<T>>
135 void do_emplace( std::initializer_list<U> il, Args&&... args )
138 Mgr::do_create(
m_storage, il, std::forward<Args>( args )... );
142 template <
typename Res,
typename T,
typename... Args>
144 std::enable_if<std::is_copy_constructible_v<T> && std::is_constructible_v<
T, Args...>,
147 template <
typename T,
typename... Args>
150 template <
typename V,
typename... Args>
175 if( !other.has_value() )
188 template <
typename T,
typename V = decay_if_not_any<T>,
typename Mgr = Manager<V>,
189 std::enable_if_t<std::is_copy_constructible_v<V> && !is_in_place_type_v<V>,
bool> =
194 Mgr::do_create(
m_storage, std::forward<T>( value ) );
198 template <
typename T,
typename... Args,
typename V = std::decay_t<T>,
typename Mgr =
Manager<V>,
200 explicit any( std::in_place_type_t<T>, Args&&... args ) :
m_manager( &Mgr::m_manage_fn )
202 Mgr::do_create(
m_storage, std::forward<Args>( args )... );
206 template <
typename T,
typename U,
typename... Args,
typename V = std::decay_t<T>,
209 explicit any( std::in_place_type_t<T>, std::initializer_list<U> il, Args&&... args ) :
212 Mgr::do_create(
m_storage, il, std::forward<Args>( args )... );
228 if( !rhs.has_value() )
232 else if(
this != &rhs )
244 template <
typename T>
245 std::enable_if_t<std::is_copy_constructible_v<decay_if_not_any<T>>,
any&>
operator=(
T&& rhs )
247 *
this =
any( std::forward<T>( rhs ) );
252 template <
typename T,
typename... Args>
255 using V = std::decay_t<T>;
261 template <
typename T,
typename U,
typename... Args>
263 emplace( std::initializer_list<U> il, Args&&... args )
265 using V = std::decay_t<T>;
315 const std::type_info&
type() const noexcept
318 return typeid( void );
326 template <
typename T>
327 static constexpr bool is_valid_any_cast()
329 return std::is_reference_v<T> || std::is_copy_constructible_v<T>;
354 template <
typename T>
355 friend void* any_caster(
const any*
any );
359 template <
typename T>
364 template <
typename U>
368 ::new( addr )
T( std::forward<U>( value ) );
371 template <
typename... Args>
375 ::new( addr )
T( std::forward<Args>( args )... );
381 const void* addr = &storage.
m_buffer;
382 return static_cast<T*
>(
const_cast<void*
>( addr ) );
387 template <
typename T>
392 template <
typename U>
395 storage.
m_ptr =
new T( std::forward<U>( value ) );
397 template <
typename... Args>
400 storage.
m_ptr =
new T( std::forward<Args>( args )... );
405 return static_cast<T*
>( storage.
m_ptr );
417template <
typename T,
typename... Args>
418std::enable_if_t<std::is_constructible_v<any, std::in_place_type_t<T>, Args...>,
any>
421 return any( std::in_place_type<T>, std::forward<Args>( args )... );
425template <
typename T,
typename U,
typename... Args>
427 std::is_constructible_v<any, std::in_place_type_t<T>, std::initializer_list<U>&, Args...>,
429make_any( std::initializer_list<U> il, Args&&... args )
431 return any( std::in_place_type<T>, il, std::forward<Args>( args )... );
444template <
typename ValueType>
447 using U = std::remove_cvref_t<ValueType>;
449 static_assert( any::is_valid_any_cast<ValueType>(),
450 "Template argument must be a reference or CopyConstructible type" );
451 static_assert( std::is_constructible_v<ValueType, const U&>,
452 "Template argument must be constructible from a const value" );
457 return static_cast<ValueType
>( *p );
473template <
typename ValueType>
476 using U = std::remove_cvref_t<ValueType>;
478 static_assert( any::is_valid_any_cast<ValueType>(),
479 "Template argument must be a reference or CopyConstructible type" );
480 static_assert( std::is_constructible_v<ValueType, U&>,
481 "Template argument must be constructible from an lvalue" );
486 return static_cast<ValueType
>( *p );
491template <
typename ValueType>
494 using U = std::remove_cvref_t<ValueType>;
496 static_assert( any::is_valid_any_cast<ValueType>(),
497 "Template argument must be a reference or CopyConstructible type" );
498 static_assert( std::is_constructible_v<ValueType, U>,
499 "Template argument must be constructible from an rvalue" );
504 return static_cast<ValueType
>( std::move( *p ) );
513void* any_caster(
const any*
any )
517 using U = std::remove_cv_t<T>;
519 if constexpr( !std::is_same_v<std::decay_t<U>, U> )
525 else if constexpr( !std::is_copy_constructible_v<U> )
531 ||
any->
type().hash_code() ==
typeid(
T ).hash_code() )
551template <
typename ValueType>
554 static_assert( !std::is_void_v<ValueType> );
558 if constexpr( std::is_object_v<ValueType> )
561 return static_cast<ValueType*
>( any_caster<ValueType>(
any ) );
567template <
typename ValueType>
570 static_assert( !std::is_void_v<ValueType> );
572 if constexpr( std::is_object_v<ValueType> )
574 return static_cast<ValueType*
>( any_caster<ValueType>(
any ) );
583 auto ptr =
reinterpret_cast<const T*
>( &
any->m_storage.m_buffer );
606 auto ptr =
static_cast<const T*
>(
any->m_storage.m_ptr );
A type-safe container of any type.
constexpr any() noexcept
Default constructor, creates an empty object.
A type-safe container of any type.
typename any_constructible< bool, T, Args... >::type any_constructible_t
any(const any &other)
Copy constructor, copies the state of other.
bool has_value() const noexcept
Report whether there is a contained object or not.
any(std::in_place_type_t< T >, std::initializer_list< U > il, Args &&... args)
Construct with an object created from il and args as the contained object.
constexpr any() noexcept
Default constructor, creates an empty object.
void do_emplace(Args &&... args)
Emplace with an object created from args as the contained object.
void reset() noexcept
If not empty, destroys the contained object.
any(T &&value)
Construct with a copy of value as the contained object.
void swap(any &rhs) noexcept
Exchange state with another object.
typename any_constructible< V &, V, Args... >::type any_emplace_t
any_emplace_t< std::decay_t< T >, std::initializer_list< U > &, Args &&... > emplace(std::initializer_list< U > il, Args &&... args)
Emplace with an object created from il and args as the contained object.
any_emplace_t< std::decay_t< T >, Args... > emplace(Args &&... args)
Emplace with an object created from args as the contained object.
std::enable_if< std::is_copy_constructible_v< T > &&std::is_constructible_v< T, Args... >, Res > any_constructible
any & operator=(const any &rhs)
Copy the state of another object.
~any()
Destructor, calls reset().
any(any &&other) noexcept
Move constructor, transfer the state from other.
std::enable_if_t<!std::is_same_v< V, any >, V > decay_if_not_any
std::enable_if_t< std::is_copy_constructible_v< decay_if_not_any< T > >, any & > operator=(T &&rhs)
Store a copy of rhs as the contained object.
any & operator=(any &&rhs) noexcept
Move assignment operator.
void do_emplace(std::initializer_list< U > il, Args &&... args)
Emplace with an object created from il and args as the contained object.
any(std::in_place_type_t< T >, Args &&... args)
Construct with an object created from args as the contained object.
void(* m_manager)(Op, const any *, Arg *)
const std::type_info & type() const noexcept
The typeid of the contained object, or typeid(void) if empty.
std::conditional_t< Use_Internal_Storage< T >::value, Manager_Internal< T >, Manager_External< T > > Manager
Exception class thrown by a failed any_cast.
const char * what() const noexcept override
static bool empty(const wxTextEntryBase *aCtrl)
constexpr bool is_in_place_type_v
std::enable_if_t< std::is_constructible_v< any, std::in_place_type_t< T >, Args... >, any > make_any(Args &&... args)
Create a any holding a T constructed from args....
ValueType any_cast(const any &any)
Access the contained object.
static void do_create(Storage &storage, U &&value)
static void m_manage_fn(Op which, const any *any, Arg *arg)
static T * do_access(const Storage &storage)
static void do_create(Storage &storage, Args &&... args)
static void do_create(Storage &storage, Args &&... args)
static T * do_access(const Storage &storage)
static void m_manage_fn(Op which, const any *any, Arg *arg)
static void do_create(Storage &storage, U &&value)
const std::type_info * m_typeinfo
Storage & operator=(const Storage &)=delete
Storage(const Storage &)=delete
unsigned char m_buffer[sizeof(m_ptr)]