9#ifndef ADOBE_ANY_REGULAR_HPP
10#define ADOBE_ANY_REGULAR_HPP
19#include <boost/concept_check.hpp>
20#include <boost/mpl/bool.hpp>
21#include <boost/mpl/if.hpp>
22#include <boost/noncopyable.hpp>
23#include <boost/operators.hpp>
32#include <adobe/implementation/swap.hpp>
34#if defined(ADOBE_STD_SERIALIZATION)
82namespace implementation {
84enum { vtable_version = 2 };
88struct any_regular_interface_t;
91 typedef any_regular_interface_t interface_type;
93 std::uintptr_t version;
94 void (*destruct)(
const interface_type&);
95 const std::type_info& (*type_info)(
const interface_type&);
96 interface_type* (*clone)(
const interface_type&,
void*);
97 interface_type* (*move_clone)(interface_type&,
void*);
98 void (*assign)(interface_type&,
const interface_type&);
99 bool (*equals)(
const interface_type&,
const interface_type&);
100 void (*exchange)(interface_type&, interface_type&);
101 void (*serialize)(
const interface_type&, std::ostream&);
106static_assert(
sizeof(vtable_t) == 9 *
sizeof(
void*));
111 const vtable_t* vtable_m;
115static_assert(
sizeof(pad_vtable_t) ==
sizeof(double));
119struct any_regular_interface_t {
120 typedef any_regular_interface_t interface_type;
122 any_regular_interface_t(
const vtable_t& x) { object_m.vtable_m = &x; }
124 pad_vtable_t object_m;
126 void destruct()
const {
return object_m.vtable_m->destruct(*
this); }
127 const std::type_info& type_info()
const {
return object_m.vtable_m->type_info(*
this); }
128 interface_type* clone(
void* x)
const {
return object_m.vtable_m->clone(*
this, x); }
129 interface_type* move_clone(
void* x) {
return object_m.vtable_m->move_clone(*
this, x); }
130 void assign(
const interface_type& x) { object_m.vtable_m->assign(*
this, x); }
131 bool equals(
const interface_type& x)
const {
return object_m.vtable_m->equals(*
this, x); }
132 void exchange(interface_type& x) { object_m.vtable_m->exchange(*
this, x); }
133 void serialize(std::ostream& s)
const { object_m.vtable_m->serialize(*
this, s); }
139struct any_regular_model_local : any_regular_interface_t, boost::noncopyable {
140 typedef any_regular_interface_t interface_type;
144 static const vtable_t vtable_s;
146 any_regular_model_local() : interface_type(vtable_s), object_m() {}
148 explicit any_regular_model_local(T x) : interface_type(vtable_s), object_m(std::move(x)) {}
150 static const any_regular_model_local& self(
const interface_type& x) {
151 return static_cast<const any_regular_model_local&
>(x);
154 static any_regular_model_local& self(interface_type& x) {
155 return static_cast<any_regular_model_local&
>(x);
158 static const std::type_info& type_info(
const interface_type&) {
return typeid(T); }
160 static void destruct(
const interface_type& x) { self(x).~any_regular_model_local(); }
162 static interface_type* clone(
const interface_type& x,
void* storage) {
163 return ::new (storage) any_regular_model_local(self(x).object_m);
166 static interface_type* move_clone(interface_type& x,
void* storage) {
167 return ::new (storage) any_regular_model_local(std::move(self(x).object_m));
170 static void assign(interface_type& x,
const interface_type& y) {
171 self(x).object_m = self(y).object_m;
174 static bool equals(
const interface_type& x,
const interface_type& y) {
175 return self(x).object_m == self(y).object_m;
178 static void exchange(interface_type& x, interface_type& y) {
179 swap(self(x).object_m, self(y).object_m);
182 static void serialize(
const interface_type& x, std::ostream& s) { s << format(self(x).get()); }
184 const T& get()
const {
return object_m; }
185 T& get() {
return object_m; }
188static_assert(
sizeof(any_regular_model_local<double>) == 16);
191const vtable_t any_regular_model_local<T>::vtable_s = {
193 &any_regular_model_local::destruct,
194 &any_regular_model_local::type_info,
195 &any_regular_model_local::clone,
196 &any_regular_model_local::move_clone,
197 &any_regular_model_local::assign,
198 &any_regular_model_local::equals,
199 &any_regular_model_local::exchange,
200 &any_regular_model_local::serialize,
204struct any_regular_model_remote : any_regular_interface_t, boost::noncopyable {
205 BOOST_CLASS_REQUIRE(T, adobe, RegularConcept);
207 typedef any_regular_interface_t interface_type;
210 typedef capture_allocator<object_t> allocator_type;
212 struct object_t : boost::noncopyable {
213 aligned_storage<allocator_type> alloc_m;
217 static object_t* new_move(T& x) {
219 object_t* result = a.allocate(1);
225 object_t* object_ptr_m;
227 static const vtable_t vtable_s;
229 explicit any_regular_model_remote(T x) : interface_type(vtable_s), object_ptr_m(new_move(x)) {}
231 any_regular_model_remote(any_regular_model_remote&& x) noexcept
232 : interface_type(vtable_s), object_ptr_m(x.object_ptr_m) {
236 ~any_regular_model_remote() {
238 allocator_type a = object_ptr_m->alloc_m.get();
239 destroy(&object_ptr_m->alloc_m);
240 destroy(&object_ptr_m->data_m);
241 a.deallocate(object_ptr_m, 1);
245 static const any_regular_model_remote& self(
const interface_type& x) {
246 return static_cast<const any_regular_model_remote&
>(x);
249 static any_regular_model_remote& self(interface_type& x) {
250 return static_cast<any_regular_model_remote&
>(x);
253 static const std::type_info& type_info(
const interface_type&) {
return typeid(T); }
255 static void destruct(
const interface_type& x) {
return self(x).~any_regular_model_remote(); }
257 static interface_type* clone(
const interface_type& x,
void* storage) {
258 return ::new (storage) any_regular_model_remote(self(x).get());
261 static interface_type* move_clone(interface_type& x,
void* storage) {
262 return ::new (storage) any_regular_model_remote(std::move(self(x)));
265 static void assign(interface_type& x,
const interface_type& y) {
266 self(x).get() = self(y).get();
269 static bool equals(
const interface_type& x,
const interface_type& y) {
270 return self(x).get() == self(y).get();
273 static void exchange(interface_type& x, interface_type& y) {
274 return swap(self(x).object_ptr_m, self(y).object_ptr_m);
277 static void serialize(
const interface_type& x, std::ostream& s) { s << format(self(x).get()); }
279 const T& get()
const {
return object_ptr_m->data_m; }
280 T& get() {
return object_ptr_m->data_m; }
283static_assert(
sizeof(any_regular_model_remote<double>) <= 16);
286const vtable_t any_regular_model_remote<T>::vtable_s = {
288 &any_regular_model_remote::destruct,
289 &any_regular_model_remote::type_info,
290 &any_regular_model_remote::clone,
291 &any_regular_model_remote::move_clone,
292 &any_regular_model_remote::assign,
293 &any_regular_model_remote::equals,
294 &any_regular_model_remote::exchange,
295 &any_regular_model_remote::serialize,
356class any_regular_t : boost::equality_comparable<any_regular_t, any_regular_t> {
357 typedef implementation::any_regular_interface_t interface_type;
358 typedef double storage_t[2];
360#ifndef ADOBE_NO_DOCUMENTATION
362 template <
typename T>
367 typedef promote_type& reference_type;
368 typedef const promote_type& const_reference_type;
370 typedef implementation::any_regular_model_local<promote_type> regular_model_local_type;
371 typedef implementation::any_regular_model_remote<promote_type> regular_model_remote_type;
373 typedef boost::mpl::bool_<(
sizeof(regular_model_local_type) <=
sizeof(storage_t)) &&
374 std::is_nothrow_move_constructible<promote_type>::value>
377 typedef typename boost::mpl::if_<use_local_type, regular_model_local_type,
378 regular_model_remote_type>
::type model_type;
381 typename boost::mpl::if_c<std::is_same<promote_type, T>::value, reference_type, T>
::type
384 typedef typename boost::mpl::if_c<std::is_same<promote_type, T>::value,
385 const_reference_type, T>
::type const_result_type;
388 template <
typename T>
390 template <
typename T>
391 friend struct helper;
410 x.object().move_clone(storage());
426 template <
typename T>
428 ::new (storage())
typename traits<T>::model_type(std::move(x));
444 template <
typename T>
452 template <
typename T>
453 typename traits<T>::const_result_type
cast()
const {
454 return helper<T>::cast(*
this);
466 template <
typename T>
467 typename traits<T>::result_type
cast() {
468 return helper<T>::cast(*
this);
484 template <
typename T>
487 ::new (storage())
typename traits<T>::model_type(std::move(x));
493 x.object().move_clone(storage());
515 template <
typename T>
526#if defined(ADOBE_STD_SERIALIZATION)
534 struct explicit_const_any_regular_t {
535 explicit_const_any_regular_t(
const any_regular_t& x) : p_m(x) {}
540 friend std::ostream&
operator<<(std::ostream& out,
const explicit_const_any_regular_t& value) {
541 value.p_m.object().serialize(out);
551 any_regular_t(interface_type&& x)
noexcept { x.move_clone(storage()); }
553 interface_type&
object() {
return *
static_cast<interface_type*
>(storage()); }
554 const interface_type&
object()
const {
return *
static_cast<const interface_type*
>(storage()); }
556 void* storage() {
return &data_m; }
557 const void* storage()
const {
return &data_m; }
561#ifndef ADOBE_NO_DOCUMENTATION
563#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
566 template <
typename,
typename>
570 template <
typename T>
572 return helper<T>::ptr_cast(*
this);
578#ifndef ADOBE_NO_DOCUMENTATION
587 any_regular_t::interface_type& a(x.object());
588 any_regular_t::interface_type& b(y.object());
590 if (a.type_info() == b.type_info()) {
600 b.move_clone(x.storage());
604 tmp.object().move_clone(y.storage());
611#ifndef ADOBE_NO_DOCUMENTATION
614struct any_regular_t::helper {
618 return &
reinterpret_cast<typename traits<T>::model_type&
>(r.object()).get();
621 static inline typename traits<T>::const_result_type
cast(
const any_regular_t& r) {
622 typedef typename traits<T>::promote_type promote_type;
624 if (r.
type_info() !=
typeid(promote_type))
626 return static_cast<typename traits<T>::const_result_type
>(
627 reinterpret_cast<const typename traits<T>::model_type&
>(r.object()).get());
631 typedef typename traits<T>::promote_type promote_type;
633 if (r.type_info() !=
typeid(promote_type))
634 throw bad_cast(r.type_info(),
typeid(promote_type));
635 return static_cast<typename traits<T>::result_type
>(
636 reinterpret_cast<typename traits<T>::model_type&
>(r.object()).get());
642 if (r.type_info() ==
typeid(promote_type))
643 r.cast<promote_type>() =
static_cast<promote_type
>(x);
690 typedef typename boost::remove_const<typename boost::remove_reference<R>::type>
::type
693 static_assert(boost::is_reference<R>::value);
696 static_assert(std::is_same<typename promote<result_type>::type, result_type>::value);
698 return x.
cast<result_type>();
707 typedef typename boost::remove_reference<R>::type result_type;
709 static_assert(boost::is_reference<R>::value);
712 static_assert(std::is_same<typename promote<result_type>::type, result_type>::value);
714 return x.
cast<result_type>();
723 typedef typename boost::remove_pointer<R>::type result_type;
725 static_assert(boost::is_pointer<R>::value);
728 static_assert(std::is_same<typename promote<result_type>::type, result_type>::value);
730 return x->ptr_cast<result_type>();
740 typename boost::remove_const<typename boost::remove_pointer<R>::type>
::type result_type;
742 static_assert(boost::is_pointer<R>::value);
745 static_assert(std::is_same<typename promote<result_type>::type, result_type>::value);
747 if (x->
type_info() !=
typeid(result_type))
749 return &x->
cast<result_type>();
An exception class thrown during ASL failures to cast.
A runtime polymorphic type similar to boost::any which can hold any type which models Regular.
any_regular_t & assign(T x)
traits< T >::result_type cast()
traits< T >::const_result_type cast() const
any_regular_t(const any_regular_t &x)
friend void swap(any_regular_t &x, any_regular_t &y)
const std::type_info & type_info() const
bool empty(const any_regular_t &x)
any_regular_t(any_regular_t &&x) noexcept
friend bool operator==(const any_regular_t &x, const any_regular_t &y)
any_regular_t & operator=(any_regular_t x)
any_regular_t & assign(any_regular_t x)
void swap(any_regular_t &x, any_regular_t &y)
bool operator==(const any_regular_t &x, const any_regular_t &y)
void print(const any_regular_t &x)
T * construct_at(T *p, Args &&... args)
std::ostream & operator<<(std::ostream &s, const extents_t &x)
R operator()(any_regular_t &x) const
R operator()(any_regular_t *x) const
R operator()(const any_regular_t &x) const
R operator()(const any_regular_t *x) const
static any_regular_t * ptr_cast(any_regular_t &r)
static const any_regular_t & cast(const any_regular_t &r)
static any_regular_t & cast(any_regular_t &r)
An empty regular- and less-than-comparable- type.