13#include <bond/core/config.h>
17#include <bond/core/config.h>
19#include <boost/assert.hpp>
20#include <boost/static_assert.hpp>
21#include <boost/utility/enable_if.hpp>
32template <
template <
typename>
class TypeId, std::size_t Size>
35 BOOST_STATIC_ASSERT(Size >=
sizeof(
void*));
44 emplace_uninitialized(other);
50 emplace_uninitialized(value);
58 any& operator=(
const any& other)
64 any& operator=(
const T& value)
69 bool empty() const BOND_NOEXCEPT
74 explicit operator bool() const BOND_NOEXCEPT
80 T* cast() BOND_NOEXCEPT
82 return TypeId<T>::value == _id ? functions::template table<T>::unsafe_cast(*
this) : nullptr;
86 const T* cast() const BOND_NOEXCEPT
88 return TypeId<T>::value == _id ? functions::template table<T>::unsafe_cast(*
this) : nullptr;
93 return _id == other._id && (empty() || _functions.compare(*
this, other));
96 bool operator!=(
const any& other)
const
98 return !(*
this == other);
102 using storage =
typename std::aligned_storage<Size>::type;
106 void (*destroy)(any& x);
108 void (*assign)(any& x,
const any& other);
110 void (*emplace_uninitialized)(any& x,
const any& other);
112 bool (*compare)(
const any& x,
const any& y);
115 template <
typename T,
bool IsSmall>
118 template <
typename T>
121 static T* unsafe_cast(any& x) BOND_NOEXCEPT
123 BOOST_ASSERT(TypeId<T>::value == x._id);
124 return static_cast<T*
>(x.data());
127 static const T* unsafe_cast(
const any& x) BOND_NOEXCEPT
129 BOOST_ASSERT(TypeId<T>::value == x._id);
130 return static_cast<const T*
>(x.data());
133 static void emplace_uninitialized(any& x,
const T& value)
135 new (x.data()) T{ value };
138 static void destroy(any& x)
140 unsafe_cast(x)->~T();
144 template <
typename T>
145 struct impl<T, false>
147 static T*& unsafe_cast(any& x) BOND_NOEXCEPT
149 BOOST_ASSERT(TypeId<T>::value == x._id);
150 return *
static_cast<T**
>(x.data());
153 static const T* unsafe_cast(
const any& x) BOND_NOEXCEPT
155 BOOST_ASSERT(TypeId<T>::value == x._id);
156 return *
static_cast<const T* const*
>(x.data());
159 static void emplace_uninitialized(any& x,
const T& value)
161 *
static_cast<T**
>(x.data()) =
new T{ value };
164 static void destroy(any& x)
166 T*& ptr = unsafe_cast(x);
172 template <
typename T>
173 struct table : impl<T, (sizeof(T) <= sizeof(storage))>
175 BOOST_STATIC_ASSERT(TypeId<T>::value != 0);
177 using base = impl<T, (sizeof(T) <= sizeof(storage))>;
179 template <typename U = T, typename boost::enable_if<std::is_copy_assignable<U> >::type* = nullptr>
180 static void assign(any& x, const T& value)
182 *base::unsafe_cast(x) = value;
185 template <typename U = T, typename boost::disable_if<std::is_copy_assignable<U> >::type* = nullptr>
186 static void assign(any& x, const T& value)
190 emplace_uninitialized(x, value);
193 static void emplace_uninitialized(any& x, const T& value)
195 base::emplace_uninitialized(x, value);
196 x._id = TypeId<T>::value;
199 static functions make() BOND_NOEXCEPT
204 [](any& x, const any& other) { assign(x, *base::unsafe_cast(other)); },
205 [](any& x, const any& other) { emplace_uninitialized(x, *base::unsafe_cast(other)); },
206 [](const any& x, const any& y) { return *base::unsafe_cast(x) == *base::unsafe_cast(y); }
213 const void* data() const BOND_NOEXCEPT
218 void* data() BOND_NOEXCEPT
224 template <typename T>
225 void emplace_uninitialized(const T& value)
227 functions::template table<T>::emplace_uninitialized(*this, value);
228 _functions = functions::template table<T>::make();
232 void emplace_uninitialized(const any& other)
236 other._functions.emplace_uninitialized(*this, other);
237 _functions = other._functions;
245 template <typename T>
246 any& assign(const T& value)
248 if (!try_assign_same(value))
252 emplace_uninitialized(value);
258 template <typename T>
259 bool try_assign_same(const T& value)
261 if (_id == TypeId<T>::value)
263 functions::template table<T>::assign(*this, value);
270 bool try_assign_same(const any& other)
272 if (_id == other._id)
276 _functions.assign(*this, other);
289 _functions.destroy(*this);
296 functions _functions;
301template <typename T, template <typename> class TypeId, std::size_t Size>
302inline T* any_cast(any<TypeId, Size>* x) BOND_NOEXCEPT
305 return x->template cast<T>();
308template <typename T, template <typename> class TypeId, std::size_t Size>
309inline const T* any_cast(const any<TypeId, Size>* x) BOND_NOEXCEPT
312 return x->template cast<T>();
namespace bond
Definition: apply.h:17
boost::enable_if< is_signed_int_or_enum< SignedT >, bool >::type operator==(const Variant &variant, SignedT value)
Compares variant for equality against the provided signed integer or enum value.
Definition: metadata.h:24