18#include <boost/mpl/bool.hpp>
19#include <boost/mpl/if.hpp>
20#include <boost/mpl/or.hpp>
21#include <boost/utility/enable_if.hpp>
23#include <adobe/implementation/swap.hpp>
46#if !defined(ADOBE_NO_DOCUMENTATION)
48template <
typename T,
typename U>
50 : boost::mpl::or_<std::is_base_of<T, U>, std::is_base_of<U, T>, std::is_same<T, U>> {};
68 virtual const void*
cast()
const = 0;
69 virtual const std::type_info&
type_info()
const = 0;
82#if !defined(ADOBE_NO_DOCUMENTATION)
86namespace implementation {
90template <
typename ConcreteType,
typename Interface>
91struct poly_state_remote : Interface {
92 typedef ConcreteType value_type;
93 typedef Interface interface_type;
95 const value_type& get()
const {
return *value_ptr_m; }
96 value_type& get() {
return *value_ptr_m; }
98 poly_state_remote(poly_state_remote&& x) : value_ptr_m(x.value_ptr_m) {
99 x.value_ptr_m =
nullptr;
102 explicit poly_state_remote(value_type x) : value_ptr_m(::new value_type(std::move(x))) {}
104 ~poly_state_remote() {
delete value_ptr_m; }
107 void assign(
const poly_copyable_interface& x) {
108 *value_ptr_m = *
static_cast<const poly_state_remote&
>(x).value_ptr_m;
111 const std::type_info& type_info()
const {
return typeid(value_type); }
112 const void* cast()
const {
return value_ptr_m; }
113 void* cast() {
return value_ptr_m; }
116 void exchange(poly_copyable_interface& x) {
117 return std::swap(value_ptr_m,
static_cast<poly_state_remote&
>(x).value_ptr_m);
121 friend bool operator==(
const poly_state_remote& x,
const poly_state_remote& y) {
122 return *x.value_ptr_m == *y.value_ptr_m;
125 value_type* value_ptr_m;
130template <
typename ConcreteType,
typename Interface>
131struct poly_state_local : Interface {
132 typedef ConcreteType value_type;
133 typedef Interface interface_type;
135 const value_type& get()
const {
return value_m; }
136 value_type& get() {
return value_m; }
138 poly_state_local(poly_state_local&& x) noexcept : value_m(std::move(x.value_m)) {}
140 explicit poly_state_local(value_type x) : value_m(std::move(x)) {}
143 void assign(
const poly_copyable_interface& x) {
144 value_m =
static_cast<const poly_state_local&
>(x).value_m;
147 const std::type_info& type_info()
const {
return typeid(value_type); }
148 const void* cast()
const {
return &value_m; }
149 void* cast() {
return &value_m; }
152 void exchange(poly_copyable_interface& x) {
153 return std::swap(value_m,
static_cast<poly_state_local&
>(x).value_m);
157 friend bool operator==(
const poly_state_local& x,
const poly_state_local& y) {
158 return x.value_m == y.value_m;
167typedef double storage_t[2];
169template <
typename T,
int N = sizeof(storage_t)>
172 value =
sizeof(T) <= N && (std::is_nothrow_constructible<typename T::value_type>::value ||
173 std::is_same<std::string, typename T::value_type>::value)
180struct poly_instance : F {
181 typedef typename F::value_type value_type;
182 typedef typename F::interface_type interface_type;
184 poly_instance(
const value_type& x) : F(x) {}
185 poly_instance(poly_instance&& x) : F(std::move(x)) {}
187 poly_copyable_interface* clone(
void* storage)
const {
188 return ::new (storage) poly_instance(this->get());
191 poly_copyable_interface* move_clone(
void* storage) {
192 return ::new (storage) poly_instance(std::move(*
this));
200 typedef bool (T::*E)(
const T&)
const;
201 typedef char (&no_type)[1];
202 typedef char (&yes_type)[2];
205 typedef yes_type type;
208 static typename sfinae<&U::equals>::type test(
int);
210 static no_type test(...);
213 enum { value =
sizeof(test<T>(1)) ==
sizeof(yes_type) };
236template <
typename ConcreteType,
typename Interface>
239 implementation::is_small<implementation::poly_state_local<ConcreteType, Interface>>,
240 implementation::poly_state_local<ConcreteType, Interface>,
241 implementation::poly_state_remote<ConcreteType, Interface>> {};
257template <
typename I,
template <
typename>
class Instance>
260 template <
typename T,
template <
typename>
class U>
267 template <
typename T>
268 explicit poly_base(T x,
typename boost::disable_if<std::is_base_of<poly_base, T>>
::type* = 0) {
269 ::new (
storage()) implementation::poly_instance<Instance<T>>(std::move(x));
273 template <
typename J,
template <
typename>
class K>
276 if (std::is_base_of<J, I>::value)
313 template <
typename J,
template <
typename>
class K>
315 return dynamic_cast<const I*
>(
319 template <
typename J>
321 return dynamic_cast<const J*
>(
327 template <
typename T>
334 template <
typename T>
341 template <
typename T>
349 template <
typename T>
361 template <
typename J,
template <
typename>
class K>
362 typename boost::enable_if<is_base_derived_or_same<I, J>>
::type
364 if (std::is_base_of<J, I>::value)
365 dynamic_cast<I&
>(
static_cast<J&
>(*x.interface_ptr()));
386template <
class J,
template <
typename>
class K>
387inline typename boost::enable_if<implementation::has_equals<J>,
bool>
::type
413 template <
typename T>
420 static_cast<F&
>(*this) = std::move(
static_cast<F&
>(x));
443template <
typename T,
typename U>
445 typedef typename std::remove_reference<T>::type target_type;
446 typedef typename target_type::interface_type target_interface_type;
447 if (!x.template is_dynamic_convertible_to<target_interface_type>())
449 return reinterpret_cast<T
>(x);
461template <
typename T,
typename U>
463 typedef typename std::remove_reference<T>::type target_type;
464 typedef typename target_type::interface_type target_interface_type;
465 if (!x.template is_dynamic_convertible_to<target_interface_type>())
467 return reinterpret_cast<T
>(x);
487template <
typename T,
typename U>
489 typedef typename std::remove_pointer<T>::type target_type;
490 typedef typename target_type::interface_type target_interface_type;
491 return x->template is_dynamic_convertible_to<target_interface_type>() ?
reinterpret_cast<T
>(x)
505template <
typename T,
typename U>
507 typedef typename std::remove_pointer<T>::type target_type;
508 typedef typename target_type::interface_type target_interface_type;
509 return x->template is_dynamic_convertible_to<target_interface_type>() ?
reinterpret_cast<T
>(x)
An exception class thrown during ASL failures to cast.
poly<foo> will be a runtime polymorphic value type wrapper modelling a concept represented by foo
poly(const poly &)=default
bool operator==(const any_regular_t &x, const any_regular_t &y)
bool operator!=(const forest< T > &x, const forest< T > &y)
void swap(adobe::extents_t::slice_t &x, adobe::extents_t::slice_t &y) BOOST_NOEXCEPT
Authors of poly concept representatives must derive their instance class from this....
Authors of a Concept representative F, intended as a template parameter to poly, will inherit from po...
bool is_dynamic_convertible_to() const
poly_base(const poly_base &x)
poly_base(const poly_base< J, K > &x, typename boost::enable_if< is_base_derived_or_same< I, J > >::type *=0)
poly_base(T x, typename boost::disable_if< std::is_base_of< poly_base, T > >::type *=0)
const interface_type * operator->() const
const std::type_info & type_info() const
const void * storage() const
boost::enable_if< is_base_derived_or_same< I, J > >::type assign(const poly_base< J, K > &x)
poly_base & operator=(poly_base x)
implementation::storage_t data_m
interface_type * operator->()
poly_base & assign(const T &x)
const interface_type & interface_ref() const
interface_type & interface_ref()
static bool is_dynamic_convertible_from(const poly_base< J, K > &x)
friend void swap(poly_base &x, poly_base &y)
Abstract interface providing signatures needed to implement "handle" objects modeling a Value (Copyab...
virtual poly_copyable_interface * clone(void *) const =0
virtual const void * cast() const =0
virtual void assign(const poly_copyable_interface &x)=0
virtual void exchange(poly_copyable_interface &x)=0
virtual ~poly_copyable_interface()
virtual poly_copyable_interface * move_clone(void *)=0
virtual const std::type_info & type_info() const =0