13#include <boost/mpl/bool.hpp>
14#include <boost/mpl/if.hpp>
15#include <boost/mpl/or.hpp>
16#include <boost/utility/enable_if.hpp>
18#include <adobe/implementation/swap.hpp>
43#if !defined(ADOBE_NO_DOCUMENTATION)
45template <
typename T,
typename U>
47 : boost::mpl::or_<std::is_base_of<T, U>, std::is_base_of<U, T>, std::is_same<T, U>> {};
65 virtual const void*
cast()
const = 0;
66 virtual const std::type_info&
type_info()
const = 0;
79#if !defined(ADOBE_NO_DOCUMENTATION)
83namespace implementation {
87template <
typename ConcreteType,
typename Interface>
88struct poly_state_remote : Interface {
89 typedef ConcreteType value_type;
90 typedef Interface interface_type;
92 const value_type& get()
const {
return *value_ptr_m; }
93 value_type& get() {
return *value_ptr_m; }
95 poly_state_remote(poly_state_remote&& x) : value_ptr_m(x.value_ptr_m) {
96 x.value_ptr_m =
nullptr;
99 explicit poly_state_remote(value_type x) : value_ptr_m(::new value_type(std::move(x))) {}
101 ~poly_state_remote() {
delete value_ptr_m; }
104 void assign(
const poly_copyable_interface& x) {
105 *value_ptr_m = *
static_cast<const poly_state_remote&
>(x).value_ptr_m;
108 const std::type_info& type_info()
const {
return typeid(value_type); }
109 const void* cast()
const {
return value_ptr_m; }
110 void* cast() {
return value_ptr_m; }
113 void exchange(poly_copyable_interface& x) {
114 return std::swap(value_ptr_m,
static_cast<poly_state_remote&
>(x).value_ptr_m);
118 friend bool operator==(
const poly_state_remote& x,
const poly_state_remote& y) {
119 return *x.value_ptr_m == *y.value_ptr_m;
122 value_type* value_ptr_m;
127template <
typename ConcreteType,
typename Interface>
128struct poly_state_local : Interface {
129 typedef ConcreteType value_type;
130 typedef Interface interface_type;
132 const value_type& get()
const {
return value_m; }
133 value_type& get() {
return value_m; }
135 poly_state_local(poly_state_local&& x) noexcept : value_m(std::move(x.value_m)) {}
137 explicit poly_state_local(value_type x) : value_m(std::move(x)) {}
140 void assign(
const poly_copyable_interface& x) {
141 value_m =
static_cast<const poly_state_local&
>(x).value_m;
144 const std::type_info& type_info()
const {
return typeid(value_type); }
145 const void* cast()
const {
return &value_m; }
146 void* cast() {
return &value_m; }
149 void exchange(poly_copyable_interface& x) {
150 return std::swap(value_m,
static_cast<poly_state_local&
>(x).value_m);
154 friend bool operator==(
const poly_state_local& x,
const poly_state_local& y) {
155 return x.value_m == y.value_m;
164typedef double storage_t[2];
166template <
typename T,
int N = sizeof(storage_t)>
169 value =
sizeof(T) <= N && (std::is_nothrow_constructible<typename T::value_type>::value ||
170 std::is_same<std::string, typename T::value_type>::value)
177struct poly_instance : F {
178 typedef typename F::value_type value_type;
179 typedef typename F::interface_type interface_type;
181 poly_instance(
const value_type& x) : F(x) {}
182 poly_instance(poly_instance&& x) : F(std::move(x)) {}
184 poly_copyable_interface* clone(
void* storage)
const {
185 return ::new (storage) poly_instance(this->get());
188 poly_copyable_interface* move_clone(
void* storage) {
189 return ::new (storage) poly_instance(std::move(*
this));
197 typedef bool (T::*E)(
const T&)
const;
198 typedef char (&no_type)[1];
199 typedef char (&yes_type)[2];
202 typedef yes_type type;
205 static typename sfinae<&U::equals>::type test(
int);
207 static no_type test(...);
210 enum { value =
sizeof(test<T>(1)) ==
sizeof(yes_type) };
233template <
typename ConcreteType,
typename Interface>
236 implementation::is_small<implementation::poly_state_local<ConcreteType, Interface>>,
237 implementation::poly_state_local<ConcreteType, Interface>,
238 implementation::poly_state_remote<ConcreteType, Interface>> {};
254template <
typename I,
template <
typename>
class Instance>
257 template <
typename T,
template <
typename>
class U>
264 template <
typename T>
265 explicit poly_base(T x,
typename boost::disable_if<std::is_base_of<poly_base, T>>
::type* = 0) {
266 ::new (
storage()) implementation::poly_instance<Instance<T>>(std::move(x));
270 template <
typename J,
template <
typename>
class K>
273 if (std::is_base_of<J, I>::value)
310 template <
typename J,
template <
typename>
class K>
312 return dynamic_cast<const I*
>(
316 template <
typename J>
318 return dynamic_cast<const J*
>(
324 template <
typename T>
331 template <
typename T>
338 template <
typename T>
346 template <
typename T>
358 template <
typename J,
template <
typename>
class K>
359 typename boost::enable_if<is_base_derived_or_same<I, J>>
::type
361 if (std::is_base_of<J, I>::value)
362 dynamic_cast<I&
>(
static_cast<J&
>(*x.interface_ptr()));
383template <
class J,
template <
typename>
class K>
384inline typename boost::enable_if<implementation::has_equals<J>,
bool>
::type
410 template <
typename T>
417 static_cast<F&
>(*this) = std::move(
static_cast<F&
>(x));
440template <
typename T,
typename U>
442 typedef typename boost::remove_reference<T>::type target_type;
443 typedef typename target_type::interface_type target_interface_type;
444 if (!x.template is_dynamic_convertible_to<target_interface_type>())
446 return reinterpret_cast<T
>(x);
458template <
typename T,
typename U>
460 typedef typename boost::remove_reference<T>::type target_type;
461 typedef typename target_type::interface_type target_interface_type;
462 if (!x.template is_dynamic_convertible_to<target_interface_type>())
464 return reinterpret_cast<T
>(x);
484template <
typename T,
typename U>
486 typedef typename std::remove_pointer<T>::type target_type;
487 typedef typename target_type::interface_type target_interface_type;
488 return x->template is_dynamic_convertible_to<target_interface_type>() ?
reinterpret_cast<T
>(x)
502template <
typename T,
typename U>
504 typedef typename std::remove_pointer<T>::type target_type;
505 typedef typename target_type::interface_type target_interface_type;
506 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