1// Boost.TypeErasure library
2//
3// Copyright 2011 Steven Watanabe
4//
5// Distributed under the Boost Software License Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// $Id$
10
11#ifndef BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED
12#define BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED
13
14#include <algorithm>
15#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
16# include <utility> // std::forward, std::move
17#endif
18#include <boost/config.hpp>
19#include <boost/utility/enable_if.hpp>
20#include <boost/utility/addressof.hpp>
21#include <boost/utility/declval.hpp>
22#include <boost/mpl/bool.hpp>
23#include <boost/mpl/or.hpp>
24#include <boost/mpl/pair.hpp>
25#include <boost/mpl/map.hpp>
26#include <boost/mpl/reverse_fold.hpp>
27#include <boost/type_traits/decay.hpp>
28#include <boost/type_traits/remove_reference.hpp>
29#include <boost/type_traits/remove_const.hpp>
30#include <boost/type_traits/is_same.hpp>
31#include <boost/type_traits/is_const.hpp>
32#include <boost/preprocessor/cat.hpp>
33#include <boost/preprocessor/iteration/iterate.hpp>
34#include <boost/preprocessor/repetition/enum_params.hpp>
35#include <boost/preprocessor/repetition/enum_binary_params.hpp>
36#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
37#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
38#include <boost/type_erasure/detail/access.hpp>
39#include <boost/type_erasure/detail/any_base.hpp>
40#include <boost/type_erasure/detail/normalize.hpp>
41#include <boost/type_erasure/detail/storage.hpp>
42#include <boost/type_erasure/detail/instantiate.hpp>
43#include <boost/type_erasure/config.hpp>
44#include <boost/type_erasure/binding.hpp>
45#include <boost/type_erasure/static_binding.hpp>
46#include <boost/type_erasure/concept_interface.hpp>
47#include <boost/type_erasure/call.hpp>
48#include <boost/type_erasure/relaxed.hpp>
49#include <boost/type_erasure/param.hpp>
50
51#ifdef BOOST_MSVC
52#pragma warning(push)
53#pragma warning(disable:4355)
54#pragma warning(disable:4521)
55#pragma warning(disable:4522) // multiple assignment operators specified
56#endif
57
58namespace boost {
59namespace type_erasure {
60
61#ifndef BOOST_TYPE_ERASURE_DOXYGEN
62
63template<class Sig>
64struct constructible;
65
66template<class T>
67struct destructible;
68
69template<class T, class U>
70struct assignable;
71
72#endif
73
74namespace detail {
75
76#if defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
77
78template<class Concept, class Base, class ID>
79struct choose_concept_interface
80{
81 typedef ::boost::type_erasure::concept_interface<Concept, Base, ID> type;
82};
83
84#else
85
86struct default_concept_interface
87{
88 template<class Concept, class Base, class ID>
89 using apply = ::boost::type_erasure::concept_interface<Concept, Base, ID>;
90};
91
92default_concept_interface boost_type_erasure_find_interface(...);
93
94template<class Concept, class Base, class ID>
95struct choose_concept_interface
96{
97 typedef decltype(boost_type_erasure_find_interface(::boost::declval<Concept>())) finder;
98 typedef typename finder::template apply<Concept, Base, ID> type;
99};
100
101#endif
102
103#ifndef BOOST_TYPE_ERASURE_USE_MP11
104
105template<class Derived, class Concept, class T>
106struct compute_bases
107{
108 typedef typename ::boost::mpl::reverse_fold<
109 typename ::boost::type_erasure::detail::collect_concepts<
110 Concept
111 >::type,
112 ::boost::type_erasure::any_base<Derived>,
113 ::boost::type_erasure::detail::choose_concept_interface<
114 ::boost::mpl::_2,
115 ::boost::mpl::_1,
116 T
117 >
118 >::type type;
119};
120
121#else
122
123template<class ID>
124struct compute_bases_f
125{
126 template<class Concept, class Base>
127 using apply = typename ::boost::type_erasure::detail::choose_concept_interface<Concept, Base, ID>::type;
128};
129
130template<class Derived, class Concept, class T>
131using compute_bases_t =
132 ::boost::mp11::mp_reverse_fold<
133 typename ::boost::type_erasure::detail::collect_concepts_t<
134 Concept
135 >,
136 ::boost::type_erasure::any_base<Derived>,
137 ::boost::type_erasure::detail::compute_bases_f<T>::template apply
138 >;
139
140template<class Derived, class Concept, class T>
141using compute_bases = ::boost::mpl::identity< ::boost::type_erasure::detail::compute_bases_t<Derived, Concept, T> >;
142
143#endif
144
145template<class T>
146T make(T*) { return T(); }
147
148// This dance is necessary to avoid errors calling
149// an ellipsis function with a non-trivially-copyable
150// argument.
151
152typedef char no;
153struct yes { no dummy[2]; };
154
155template<class Op>
156yes check_overload(const Op*);
157no check_overload(const void*);
158
159struct fallback {};
160
161#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
162
163template<class T>
164fallback make_fallback(T&&, boost::mpl::false_)
165{
166 return fallback();
167}
168
169template<class T>
170T&& make_fallback(T&& arg, boost::mpl::true_)
171{
172 return std::forward<T>(arg);
173}
174
175#else
176
177template<class T>
178fallback make_fallback(const T&, boost::mpl::false_)
179{
180 return fallback();
181}
182
183template<class T>
184const T& make_fallback(const T& arg, boost::mpl::true_)
185{
186 return arg;
187}
188
189#endif
190
191template<class T>
192struct is_any : ::boost::mpl::false_ {};
193
194template<class Concept, class T>
195struct is_any<any<Concept, T> > : ::boost::mpl::true_ {};
196
197#ifdef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
198
199template<class Any, class... U>
200struct has_constructor :
201 ::boost::mpl::bool_<
202 sizeof(
203 ::boost::type_erasure::detail::check_overload(
204 ::boost::declval<Any&>().
205 _boost_type_erasure_deduce_constructor(::boost::declval<U>()...)
206 )
207 ) == sizeof(::boost::type_erasure::detail::yes)
208 >
209{};
210
211template<class Any>
212using has_copy_constructor =
213 ::boost::type_erasure::is_subconcept<
214 ::boost::type_erasure::constructible<
215 typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type const&)
216 >,
217 typename ::boost::type_erasure::concept_of<Any>::type
218 >;
219
220template<class Any>
221using has_move_constructor =
222 ::boost::type_erasure::is_subconcept<
223 ::boost::type_erasure::constructible<
224 typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type &&)
225 >,
226 typename ::boost::type_erasure::concept_of<Any>::type
227 >;
228
229template<class Any>
230using has_mutable_copy_constructor =
231 ::boost::type_erasure::is_subconcept<
232 ::boost::type_erasure::constructible<
233 typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type &)
234 >,
235 typename ::boost::type_erasure::concept_of<Any>::type
236 >;
237
238struct empty {};
239
240template<class T>
241struct is_binding_arg : ::boost::mpl::false_ {};
242template<class T>
243struct is_binding_arg<binding<T> > : ::boost::mpl::true_ {};
244template<class T>
245struct is_binding_arg<binding<T>&&> : ::boost::mpl::true_ {};
246template<class T>
247struct is_binding_arg<binding<T>&> : ::boost::mpl::true_ {};
248template<class T>
249struct is_binding_arg<binding<T> const&> : ::boost::mpl::true_ {};
250
251template<class T>
252struct is_static_binding_arg : ::boost::mpl::false_ {};
253template<class T>
254struct is_static_binding_arg<static_binding<T> > : ::boost::mpl::true_ {};
255template<class T>
256struct is_static_binding_arg<static_binding<T>&&> : ::boost::mpl::true_ {};
257template<class T>
258struct is_static_binding_arg<static_binding<T>&> : ::boost::mpl::true_ {};
259template<class T>
260struct is_static_binding_arg<static_binding<T> const&> : ::boost::mpl::true_ {};
261
262template<class T>
263struct is_any_arg : ::boost::mpl::false_ {};
264template<class Concept, class T>
265struct is_any_arg<any<Concept, T> > : ::boost::mpl::true_ {};
266template<class Concept, class T>
267struct is_any_arg<any<Concept, T>&&> : ::boost::mpl::true_ {};
268template<class Concept, class T>
269struct is_any_arg<any<Concept, T>&> : ::boost::mpl::true_ {};
270template<class Concept, class T>
271struct is_any_arg<any<Concept, T> const&> : ::boost::mpl::true_ {};
272
273template<class T>
274struct safe_concept_of;
275template<class Concept, class T>
276struct safe_concept_of<any<Concept, T> > { typedef Concept type; };
277template<class Concept, class T>
278struct safe_concept_of<any<Concept, T>&&> { typedef Concept type; };
279template<class Concept, class T>
280struct safe_concept_of<any<Concept, T>&> { typedef Concept type; };
281template<class Concept, class T>
282struct safe_concept_of<any<Concept, T> const&> { typedef Concept type; };
283
284template<class T>
285struct safe_placeholder_of;
286template<class Concept, class T>
287struct safe_placeholder_of<any<Concept, T> > { typedef T type; };
288template<class Concept, class T>
289struct safe_placeholder_of<any<Concept, T>&&> { typedef T type; };
290template<class Concept, class T>
291struct safe_placeholder_of<any<Concept, T>&> { typedef T type; };
292template<class Concept, class T>
293struct safe_placeholder_of<any<Concept, T> const&> { typedef T type; };
294
295template<class T>
296using safe_placeholder_t = ::boost::remove_cv_t< ::boost::remove_reference_t<typename safe_placeholder_of<T>::type> >;
297
298}
299
300// Enables or deletes the copy/move constructors depending on the Concept.
301template<class Base, class Enable = void>
302struct any_constructor_control : Base
303{
304 using Base::Base;
305};
306
307template<class Base>
308struct any_constructor_control<
309 Base,
310 typename boost::enable_if_c<
311 !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
312 ::boost::type_erasure::detail::has_move_constructor<Base>::value &&
313 ::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
314 >::type
315> : Base
316{
317 using Base::Base;
318 any_constructor_control() = default;
319 any_constructor_control(any_constructor_control&) = default;
320 any_constructor_control(any_constructor_control&&) = default;
321 any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
322 any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
323 any_constructor_control& operator=(any_constructor_control &&) = default;
324};
325
326template<class Base>
327struct any_constructor_control<
328 Base,
329 typename boost::enable_if_c<
330 !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
331 !::boost::type_erasure::detail::has_move_constructor<Base>::value &&
332 ::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
333 >::type
334> : Base
335{
336 using Base::Base;
337 any_constructor_control() = default;
338 any_constructor_control(any_constructor_control&) = default;
339 any_constructor_control(any_constructor_control&&) = delete;
340 any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
341 any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
342 any_constructor_control& operator=(any_constructor_control &&) = default;
343};
344
345template<class Base>
346struct any_constructor_control<
347 Base,
348 typename boost::enable_if_c<
349 !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
350 ::boost::type_erasure::detail::has_move_constructor<Base>::value &&
351 !::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
352 >::type
353> : Base
354{
355 using Base::Base;
356 any_constructor_control() = default;
357 any_constructor_control(any_constructor_control const&) = delete;
358 any_constructor_control(any_constructor_control&&) = default;
359 any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
360 any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
361 any_constructor_control& operator=(any_constructor_control &&) = default;
362};
363
364template<class Base>
365struct any_constructor_control<
366 Base,
367 typename boost::enable_if_c<
368 !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
369 !::boost::type_erasure::detail::has_move_constructor<Base>::value &&
370 !::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
371 >::type
372> : Base
373{
374 using Base::Base;
375 any_constructor_control() = default;
376 any_constructor_control(any_constructor_control const&) = delete;
377 any_constructor_control(any_constructor_control&&) = delete;
378 any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
379 any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
380 any_constructor_control& operator=(any_constructor_control &&) = default;
381};
382
383template<class Concept, class T>
384struct any_constructor_impl :
385 ::boost::type_erasure::detail::compute_bases<
386 ::boost::type_erasure::any<Concept, T>,
387 Concept,
388 T
389 >::type
390{
391 typedef typename ::boost::type_erasure::detail::compute_bases<
392 ::boost::type_erasure::any<Concept, T>,
393 Concept,
394 T
395 >::type _boost_type_erasure_base;
396 // Internal constructors
397 typedef ::boost::type_erasure::binding<Concept> _boost_type_erasure_table_type;
398 any_constructor_impl(const ::boost::type_erasure::detail::storage& data_arg, const _boost_type_erasure_table_type& table_arg)
399 : _boost_type_erasure_table(table_arg),
400 _boost_type_erasure_data(data_arg)
401 {}
402 any_constructor_impl(::boost::type_erasure::detail::storage&& data_arg, const _boost_type_erasure_table_type& table_arg)
403 : _boost_type_erasure_table(table_arg),
404 _boost_type_erasure_data(data_arg)
405 {}
406 // default constructor
407 any_constructor_impl()
408 {
409 BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
410 _boost_type_erasure_data.data = 0;
411 }
412 // capturing constructor
413 template<class U,
414 typename ::boost::enable_if_c<
415 !::boost::type_erasure::detail::is_any_arg<U>::value &&
416 !::boost::type_erasure::detail::is_binding_arg<U>::value &&
417 !::boost::type_erasure::detail::is_static_binding_arg<U>::value
418 >::type* = nullptr
419 >
420 any_constructor_impl(U&& data_arg)
421 : _boost_type_erasure_table((
422 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, ::boost::decay_t<U>),
423 ::boost::type_erasure::make_binding<
424 ::boost::mpl::map1< ::boost::mpl::pair<T, ::boost::decay_t<U> > >
425 >()
426 )),
427 _boost_type_erasure_data(std::forward<U>(data_arg))
428 {}
429 template<class U, class Map,
430 typename ::boost::enable_if_c<
431 !::boost::type_erasure::detail::is_any_arg<U>::value &&
432 !::boost::type_erasure::detail::is_binding_arg<U>::value &&
433 !::boost::type_erasure::detail::is_static_binding_arg<U>::value
434 >::type* = nullptr
435 >
436 any_constructor_impl(U&& data_arg, const static_binding<Map>& b)
437 : _boost_type_erasure_table((
438 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
439 b
440 )),
441 _boost_type_erasure_data(std::forward<U>(data_arg))
442 {
443 BOOST_MPL_ASSERT((::boost::is_same<
444 typename ::boost::mpl::at<Map, T>::type, ::boost::decay_t<U> >));
445 }
446 // converting constructor
447 template<class U,
448 typename ::boost::enable_if_c<
449 ::boost::type_erasure::is_subconcept<
450 Concept, typename ::boost::type_erasure::detail::safe_concept_of<U>::type,
451 typename ::boost::mpl::if_c< ::boost::is_same<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >::value,
452 void,
453 ::boost::mpl::map1<
454 ::boost::mpl::pair<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >
455 >
456 >::type
457 >::value
458 >::type* = nullptr
459 >
460 any_constructor_impl(U&& other)
461 : _boost_type_erasure_table(
462 ::boost::type_erasure::detail::access::table(other),
463 typename ::boost::mpl::if_c< ::boost::is_same<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >::value,
464#ifndef BOOST_TYPE_ERASURE_USE_MP11
465 ::boost::type_erasure::detail::substitution_map< ::boost::mpl::map0<> >,
466#else
467 ::boost::type_erasure::detail::make_identity_placeholder_map<Concept>,
468#endif
469 ::boost::mpl::map1<
470 ::boost::mpl::pair<
471 T,
472 ::boost::type_erasure::detail::safe_placeholder_t<U>
473 >
474 >
475 >::type()
476 ),
477 _boost_type_erasure_data(::boost::type_erasure::call(
478 ::boost::type_erasure::detail::make(
479 false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
480 ), std::forward<U>(other))
481 )
482 {}
483 template<class U,
484 typename ::boost::enable_if_c<
485 ::boost::type_erasure::detail::is_any_arg<U>::value
486 >::type* = nullptr
487 >
488 any_constructor_impl(U&& other, const binding<Concept>& binding_arg)
489 : _boost_type_erasure_table(binding_arg),
490 _boost_type_erasure_data(::boost::type_erasure::call(
491 ::boost::type_erasure::detail::make(
492 false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
493 ), std::forward<U>(other))
494 )
495 {}
496 template<class U, class Map,
497 typename ::boost::enable_if_c<
498 ::boost::type_erasure::is_subconcept<
499 Concept, typename ::boost::type_erasure::detail::safe_concept_of<U>::type,
500 Map
501 >::value
502 >::type* = nullptr
503 >
504 any_constructor_impl(U&& other, const static_binding<Map>& binding_arg)
505 : _boost_type_erasure_table(::boost::type_erasure::detail::access::table(other), binding_arg),
506 _boost_type_erasure_data(::boost::type_erasure::call(
507 ::boost::type_erasure::detail::make(
508 false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
509 ), std::forward<U>(other))
510 )
511 {}
512 // copy and move constructors are a special case of the converting
513 // constructors, but must be defined separately to keep C++ happy.
514 any_constructor_impl(const any_constructor_impl& other)
515 : _boost_type_erasure_table(
516 ::boost::type_erasure::detail::access::table(other)
517 ),
518 _boost_type_erasure_data(::boost::type_erasure::call(
519 ::boost::type_erasure::detail::make(
520 false? other._boost_type_erasure_deduce_constructor(
521 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type const&>(other)) : 0
522 ), other)
523 )
524 {}
525 any_constructor_impl(any_constructor_impl& other)
526 : _boost_type_erasure_table(
527 ::boost::type_erasure::detail::access::table(other)
528 ),
529 _boost_type_erasure_data(::boost::type_erasure::call(
530 ::boost::type_erasure::detail::make(
531 false? other._boost_type_erasure_deduce_constructor(
532 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type &>(other)) : 0
533 ), other)
534 )
535 {}
536 any_constructor_impl(any_constructor_impl&& other)
537 : _boost_type_erasure_table(
538 ::boost::type_erasure::detail::access::table(other)
539 ),
540 _boost_type_erasure_data(::boost::type_erasure::call(
541 ::boost::type_erasure::detail::make(
542 false? other._boost_type_erasure_deduce_constructor(
543 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type &&>(other)) : 0
544 ), std::move(other))
545 )
546 {}
547
548 template<class R, class... A, class... U>
549 const _boost_type_erasure_table_type& _boost_type_erasure_extract_table(
550 ::boost::type_erasure::constructible<R(A...)>*,
551 U&&... u)
552 {
553 return *::boost::type_erasure::detail::extract_table(static_cast<void(*)(A...)>(0), u...);
554 }
555 // forwarding constructor
556 template<class... U,
557 typename ::boost::enable_if_c<
558 ::boost::type_erasure::detail::has_constructor<any_constructor_impl, U...>::value
559 >::type* = nullptr
560 >
561 explicit any_constructor_impl(U&&... u)
562 : _boost_type_erasure_table(
563 _boost_type_erasure_extract_table(
564 false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0,
565 std::forward<U>(u)...
566 )
567 ),
568 _boost_type_erasure_data(
569 ::boost::type_erasure::call(
570 ::boost::type_erasure::detail::make(
571 false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0
572 ),
573 std::forward<U>(u)...
574 )
575 )
576 {}
577 template<class... U,
578 typename ::boost::enable_if_c<
579 ::boost::type_erasure::detail::has_constructor<any_constructor_impl, U...>::value
580 >::type* = nullptr
581 >
582 explicit any_constructor_impl(const binding<Concept>& binding_arg, U&&... u)
583 : _boost_type_erasure_table(binding_arg),
584 _boost_type_erasure_data(
585 ::boost::type_erasure::call(
586 binding_arg,
587 ::boost::type_erasure::detail::make(
588 false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0
589 ),
590 std::forward<U>(u)...
591 )
592 )
593 {}
594
595 // The assignment operator and destructor must be defined here rather
596 // than in any to avoid implicitly deleting the move constructor.
597
598 any_constructor_impl& operator=(const any_constructor_impl& other)
599 {
600 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
601 static_cast<const typename _boost_type_erasure_base::_boost_type_erasure_derived_type&>(other));
602 return *this;
603 }
604
605 any_constructor_impl& operator=(any_constructor_impl& other)
606 {
607 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
608 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type&>(other));
609 return *this;
610 }
611
612 any_constructor_impl& operator=(any_constructor_impl&& other)
613 {
614 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
615 static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type&&>(other));
616 return *this;
617 }
618
619 ~any_constructor_impl()
620 {
621 _boost_type_erasure_table.template find<
622 ::boost::type_erasure::destructible<T>
623 >()(_boost_type_erasure_data);
624 }
625
626protected:
627 friend struct ::boost::type_erasure::detail::access;
628
629 _boost_type_erasure_table_type _boost_type_erasure_table;
630 ::boost::type_erasure::detail::storage _boost_type_erasure_data;
631};
632
633namespace detail {
634
635#endif
636
637template<class T>
638struct is_rvalue_for_any :
639 ::boost::mpl::not_<
640 ::boost::is_lvalue_reference<T>
641 >
642{};
643
644template<class C, class P>
645struct is_rvalue_for_any<any<C, P> > :
646 ::boost::mpl::not_<
647 ::boost::is_lvalue_reference<P>
648 >
649{};
650
651}
652
653/**
654 * The class template @ref any can store any object that
655 * models a specific \Concept. It dispatches all
656 * the functions defined by the \Concept to the contained type
657 * at runtime.
658 *
659 * \tparam Concept The \Concept that the stored type should model.
660 * \tparam T A @ref placeholder specifying which type this is.
661 *
662 * \see concept_of, placeholder_of, \any_cast, \is_empty, \binding_of, \typeid_of
663 */
664template<class Concept, class T = _self>
665class any :
666#ifdef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
667 public ::boost::type_erasure::any_constructor_control<
668 ::boost::type_erasure::any_constructor_impl<
669
670 Concept,
671 T
672 >
673 >
674#else
675 public ::boost::type_erasure::detail::compute_bases<
676 ::boost::type_erasure::any<Concept, T>,
677 Concept,
678 T
679 >::type
680#endif
681{
682 typedef ::boost::type_erasure::binding<Concept> table_type;
683public:
684 /** INTERNAL ONLY */
685 typedef Concept _boost_type_erasure_concept_type;
686
687#if defined(BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS)
688 using _boost_type_erasure_base = ::boost::type_erasure::any_constructor_control<
689 ::boost::type_erasure::any_constructor_impl<
690 Concept,
691 T
692 >
693 >;
694 using _boost_type_erasure_base::_boost_type_erasure_base;
695#else
696
697 /** INTERNAL ONLY */
698 any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg)
699 : table(table_arg),
700 data(data_arg)
701 {}
702#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
703 /** INTERNAL ONLY */
704 any(::boost::type_erasure::detail::storage&& data_arg, const table_type& table_arg)
705 : table(table_arg),
706 data(data_arg)
707 {}
708#endif
709 /**
710 * Constructs an empty @ref any.
711 *
712 * Except as otherwise noted, all operations on an
713 * empty @ref any result in a @ref bad_function_call exception.
714 * The copy-constructor of an empty @ref any creates another
715 * null @ref any. The destructor of an empty @ref any is a no-op.
716 * Comparison operators treat all empty @ref any "anys" as equal.
717 * \typeid_of applied to an empty @ref any returns @c typeid(void).
718 *
719 * An @ref any which does not include @ref relaxed in its
720 * \Concept can never be null.
721 *
722 * \pre @ref relaxed must be in @c Concept.
723 *
724 * \throws Nothing.
725 *
726 * @see \is_empty
727 */
728 any()
729 {
730 BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
731 data.data = 0;
732 }
733
734#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
735
736 template<class U>
737 any(const U& data_arg)
738 : table((
739 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
740 ::boost::type_erasure::make_binding<
741 ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
742 >()
743 )),
744 data(data_arg)
745 {}
746 template<class U, class Map>
747 any(const U& data_arg, const static_binding<Map>& binding_arg)
748 : table((
749 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
750 binding_arg
751 )),
752 data(data_arg)
753 {
754 BOOST_MPL_ASSERT((::boost::is_same<
755 typename ::boost::mpl::at<Map, T>::type, U>));
756 }
757
758#else
759
760 /**
761 * Constructs an @ref any to hold a copy of @c data.
762 * The @c Concept will be instantiated with the
763 * placeholder @c T bound to U.
764 *
765 * \param data The object to store in the @ref any.
766 *
767 * \pre @c U is a model of @c Concept.
768 * \pre @c U must be \CopyConstructible.
769 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
770 *
771 * \throws std::bad_alloc or whatever that the copy
772 * constructor of @c U throws.
773 *
774 * \note This constructor never matches if the argument is
775 * an @ref any, @ref binding, or @ref static_binding.
776 */
777 template<class U>
778 any(U&& data_arg)
779 : table((
780 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type),
781 ::boost::type_erasure::make_binding<
782 ::boost::mpl::map1< ::boost::mpl::pair<T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type> >
783 >()
784 )),
785 data(std::forward<U>(data_arg))
786 {}
787 /**
788 * Constructs an @ref any to hold a copy of @c data
789 * with explicitly specified placeholder bindings.
790 *
791 * \param data The object to store in the @ref any.
792 * \param binding Specifies the types that
793 * all the placeholders should bind to.
794 *
795 * \pre @c U is a model of @c Concept.
796 * \pre @c U must be \CopyConstructible.
797 * \pre @c Map is an MPL map with an entry for every
798 * non-deduced placeholder referred to by @c Concept.
799 * \pre @c @c T must map to @c U in @c Map.
800 *
801 * \throws std::bad_alloc or whatever that the copy
802 * constructor of @c U throws.
803 *
804 * \note This constructor never matches if the argument is an @ref any.
805 */
806 template<class U, class Map>
807 any(U&& data_arg, const static_binding<Map>& binding_arg)
808 : table((
809 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
810 binding_arg
811 )),
812 data(std::forward<U>(data_arg))
813 {
814 BOOST_MPL_ASSERT((::boost::is_same<
815 typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
816 }
817
818#endif
819
820 // Handle array/function-to-pointer decay
821 /** INTERNAL ONLY */
822 template<class U>
823 any(U* data_arg)
824 : table((
825 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U*),
826 ::boost::type_erasure::make_binding<
827 ::boost::mpl::map1< ::boost::mpl::pair<T, U*> >
828 >()
829 )),
830 data(data_arg)
831 {}
832 /** INTERNAL ONLY */
833 template<class U, class Map>
834 any(U* data_arg, const static_binding<Map>& binding_arg)
835 : table((
836 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
837 binding_arg
838 )),
839 data(data_arg)
840 {
841 BOOST_MPL_ASSERT((::boost::is_same<
842 typename ::boost::mpl::at<Map, T>::type, U*>));
843 }
844 /**
845 * Copies an @ref any.
846 *
847 * \param other The object to make a copy of.
848 *
849 * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>".
850 * (This is included in @ref copy_constructible "copy_constructible<T>")
851 *
852 * \throws std::bad_alloc or whatever that the copy
853 * constructor of the contained type throws.
854 */
855 any(const any& other)
856 : table(other.table),
857 data(::boost::type_erasure::call(constructible<T(const T&)>(), other))
858 {}
859 /**
860 * Upcasts from an @ref any with stricter requirements to
861 * an @ref any with weaker requirements.
862 *
863 * \param other The object to make a copy of.
864 *
865 * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>".
866 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
867 * \pre After substituting @c T for @c Tag2, the requirements of
868 * @c Concept2 must be a superset of the requirements of
869 * @c Concept.
870 *
871 * \throws std::bad_alloc or whatever that the copy
872 * constructor of the contained type throws.
873 */
874 template<class Concept2, class Tag2>
875 any(const any<Concept2, Tag2>& other)
876 : table(
877 ::boost::type_erasure::detail::access::table(other),
878 ::boost::mpl::map1<
879 ::boost::mpl::pair<
880 T,
881 typename ::boost::remove_const<
882 typename ::boost::remove_reference<Tag2>::type
883 >::type
884 >
885 >()
886 ),
887 data(::boost::type_erasure::call(
888 constructible<
889 typename ::boost::remove_const<
890 typename boost::remove_reference<Tag2>::type
891 >::type(const typename boost::remove_reference<Tag2>::type&)
892 >(), other)
893 )
894 {}
895 /**
896 * Constructs an @ref any from another @ref any.
897 *
898 * \param other The object to make a copy of.
899 * \param binding Specifies the mapping between the placeholders
900 * used by the two concepts.
901 *
902 * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>".
903 * \pre @c Map must be an MPL map with keys for all the non-deduced
904 * placeholders used by @c Concept and values for the corresponding
905 * placeholders in @c Concept2.
906 * \pre After substituting placeholders according to @c Map, the
907 * requirements of @c Concept2 must be a superset of the
908 * requirements of @c Concept.
909 *
910 * \throws std::bad_alloc or whatever that the copy
911 * constructor of the contained type throws.
912 */
913 template<class Concept2, class Tag2, class Map>
914 any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
915 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
916 data(::boost::type_erasure::call(
917 constructible<
918 typename ::boost::remove_const<
919 typename boost::remove_reference<Tag2>::type
920 >::type(const typename boost::remove_reference<Tag2>::type&)
921 >(), other)
922 )
923 {}
924 /**
925 * Constructs an @ref any from another @ref any.
926 *
927 * \param other The object to make a copy of.
928 * \param binding Specifies the bindings of placeholders to actual types.
929 *
930 * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>".
931 * \pre The type stored in @c other must match the type expected by
932 * @c binding.
933 *
934 * \post binding_of(*this) == @c binding
935 *
936 * \throws std::bad_alloc or whatever that the copy
937 * constructor of the contained type throws.
938 *
939 * \warning This constructor is potentially dangerous, as it cannot
940 * check at compile time whether the arguments match.
941 */
942 template<class Concept2, class Tag2>
943 any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
944 : table(binding_arg),
945 data(::boost::type_erasure::call(
946 constructible<
947 typename ::boost::remove_const<
948 typename boost::remove_reference<Tag2>::type
949 >::type(const typename boost::remove_reference<Tag2>::type&)
950 >(), other)
951 )
952 {}
953
954#ifdef BOOST_TYPE_ERASURE_DOXYGEN
955
956 /**
957 * Calls a constructor of the contained type. The bindings
958 * will be deduced from the arguments.
959 *
960 * \param arg The arguments to be passed to the underlying constructor.
961 *
962 * \pre @c Concept must contain an instance of @ref constructible which
963 * can be called with these arguments.
964 * \pre At least one of the arguments must by an @ref any with the
965 * same @c Concept as this.
966 * \pre The bindings of all the arguments that are @ref any's, must
967 * be the same.
968 *
969 * \throws std::bad_alloc or whatever that the
970 * constructor of the contained type throws.
971 *
972 * \note This constructor is never chosen if any other constructor
973 * can be called instead.
974 */
975 template<class... U>
976 explicit any(U&&... arg);
977
978 /**
979 * Calls a constructor of the contained type.
980 *
981 * \param binding Specifies the bindings of placeholders to actual types.
982 * \param arg The arguments to be passed to the underlying constructor.
983 *
984 * \pre @c Concept must contain a matching instance of @ref constructible.
985 * \pre The contained type of every argument that is an @ref any, must
986 * be the same as that specified by @c binding.
987 *
988 * \post binding_of(*this) == @c binding
989 *
990 * \throws std::bad_alloc or whatever that the
991 * constructor of the contained type throws.
992 */
993 template<class... U>
994 explicit any(const binding<Concept>& binding_arg, U&&... arg)
995 : table(binding_arg),
996 data(
997 ::boost::type_erasure::detail::make(
998 false? this->_boost_type_erasure_deduce_constructor(arg...) : 0
999 )(arg...)
1000 )
1001 {}
1002
1003#else
1004#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1005 any(any&& other)
1006 : table(::boost::type_erasure::detail::access::table(other)),
1007 data(::boost::type_erasure::call(
1008 ::boost::type_erasure::detail::make(
1009 false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0
1010 ), std::move(other))
1011 )
1012 {}
1013 any(any& other)
1014 : table(::boost::type_erasure::detail::access::table(other)),
1015 data(::boost::type_erasure::call(
1016 ::boost::type_erasure::detail::make(
1017 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1018 ), other)
1019 )
1020 {}
1021 template<class Concept2, class Tag2>
1022 any(any<Concept2, Tag2>& other)
1023 : table(
1024 ::boost::type_erasure::detail::access::table(other),
1025 ::boost::mpl::map1<
1026 ::boost::mpl::pair<
1027 T,
1028 typename ::boost::remove_const<
1029 typename ::boost::remove_reference<Tag2>::type
1030 >::type
1031 >
1032 >()
1033 ),
1034 data(::boost::type_erasure::call(
1035 ::boost::type_erasure::detail::make(
1036 false? other._boost_type_erasure_deduce_constructor(other) : 0
1037 ), other)
1038 )
1039 {}
1040 template<class Concept2, class Tag2>
1041 any(any<Concept2, Tag2>&& other)
1042 : table(
1043 ::boost::type_erasure::detail::access::table(other),
1044 ::boost::mpl::map1<
1045 ::boost::mpl::pair<
1046 T,
1047 typename ::boost::remove_const<
1048 typename ::boost::remove_reference<Tag2>::type
1049 >::type
1050 >
1051 >()
1052 ),
1053 data(::boost::type_erasure::call(
1054 ::boost::type_erasure::detail::make(
1055 false? other._boost_type_erasure_deduce_constructor(std::move(other)) : 0
1056 ), std::move(other))
1057 )
1058 {}
1059#endif
1060 // construction from a reference
1061 any(const any<Concept, T&>& other)
1062 : table(::boost::type_erasure::detail::access::table(other)),
1063 data(::boost::type_erasure::call(
1064 ::boost::type_erasure::detail::make(
1065 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1066 ), other)
1067 )
1068 {}
1069 any(any<Concept, T&>& other)
1070 : table(::boost::type_erasure::detail::access::table(other)),
1071 data(::boost::type_erasure::call(
1072 ::boost::type_erasure::detail::make(
1073 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1074 ), other)
1075 )
1076 {}
1077#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1078 any(any<Concept, T&>&& other)
1079 : table(::boost::type_erasure::detail::access::table(other)),
1080 data(::boost::type_erasure::call(
1081 ::boost::type_erasure::detail::make(
1082 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1083 ), other)
1084 )
1085 {}
1086#endif
1087 any(const any<Concept, const T&>& other)
1088 : table(::boost::type_erasure::detail::access::table(other)),
1089 data(::boost::type_erasure::call(
1090 ::boost::type_erasure::detail::make(
1091 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1092 ), other)
1093 )
1094 {}
1095 any(any<Concept, const T&>& other)
1096 : table(::boost::type_erasure::detail::access::table(other)),
1097 data(::boost::type_erasure::call(
1098 ::boost::type_erasure::detail::make(
1099 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1100 ), other)
1101 )
1102 {}
1103#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1104 any(any<Concept, const T&>&& other)
1105 : table(::boost::type_erasure::detail::access::table(other)),
1106 data(::boost::type_erasure::call(
1107 ::boost::type_erasure::detail::make(
1108 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1109 ), other)
1110 )
1111 {}
1112#endif
1113
1114 // disambiguating overloads
1115 template<class U, class Map>
1116 any(U* data_arg, static_binding<Map>& binding_arg)
1117 : table((
1118 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1119 binding_arg
1120 )),
1121 data(data_arg)
1122 {
1123 BOOST_MPL_ASSERT((::boost::is_same<
1124 typename ::boost::mpl::at<Map, T>::type, U*>));
1125 }
1126#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
1127 template<class U, class Map>
1128 any(U& data_arg, static_binding<Map>& binding_arg)
1129 : table((
1130 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1131 binding_arg
1132 )),
1133 data(data_arg)
1134 {
1135 BOOST_MPL_ASSERT((::boost::is_same<
1136 typename ::boost::mpl::at<Map, T>::type, U>));
1137 }
1138 template<class U, class Map>
1139 any(const U& data_arg, static_binding<Map>& binding_arg)
1140 : table((
1141 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1142 binding_arg
1143 )),
1144 data(data_arg)
1145 {
1146 BOOST_MPL_ASSERT((::boost::is_same<
1147 typename ::boost::mpl::at<Map, T>::type, U>));
1148 }
1149 template<class U, class Map>
1150 any(U& data_arg, const static_binding<Map>& binding_arg)
1151 : table((
1152 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1153 binding_arg
1154 )),
1155 data(data_arg)
1156 {
1157 BOOST_MPL_ASSERT((::boost::is_same<
1158 typename ::boost::mpl::at<Map, T>::type, U>));
1159 }
1160#endif
1161#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1162 template<class U, class Map>
1163 any(U* data_arg, static_binding<Map>&& binding_arg)
1164 : table((
1165 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1166 binding_arg
1167 )),
1168 data(data_arg)
1169 {
1170 BOOST_MPL_ASSERT((::boost::is_same<
1171 typename ::boost::mpl::at<Map, T>::type, U*>));
1172 }
1173 template<class U, class Map>
1174 any(U&& data_arg, static_binding<Map>& binding_arg)
1175 : table((
1176 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1177 binding_arg
1178 )),
1179 data(data_arg)
1180 {
1181 BOOST_MPL_ASSERT((::boost::is_same<
1182 typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
1183 }
1184 template<class U, class Map>
1185 any(U&& data_arg, static_binding<Map>&& binding_arg)
1186 : table((
1187 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1188 binding_arg
1189 )),
1190 data(data_arg)
1191 {
1192 BOOST_MPL_ASSERT((::boost::is_same<
1193 typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
1194 }
1195#endif
1196 template<class Concept2, class Tag2, class Map>
1197 any(any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
1198 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1199 data(::boost::type_erasure::call(
1200 constructible<
1201 typename ::boost::remove_const<
1202 typename boost::remove_reference<Tag2>::type
1203 >::type(const typename boost::remove_reference<Tag2>::type&)
1204 >(), other)
1205 )
1206 {}
1207 template<class Concept2, class Tag2, class Map>
1208 any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
1209 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1210 data(::boost::type_erasure::call(
1211 constructible<
1212 typename ::boost::remove_const<
1213 typename boost::remove_reference<Tag2>::type
1214 >::type(const typename boost::remove_reference<Tag2>::type&)
1215 >(), other)
1216 )
1217 {}
1218 template<class Concept2, class Tag2, class Map>
1219 any(const any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
1220 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1221 data(::boost::type_erasure::call(
1222 constructible<
1223 typename ::boost::remove_const<
1224 typename boost::remove_reference<Tag2>::type
1225 >::type(const typename boost::remove_reference<Tag2>::type&)
1226 >(), other)
1227 )
1228 {}
1229 template<class Concept2, class Tag2>
1230 any(any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
1231 : table(binding_arg),
1232 data(::boost::type_erasure::call(
1233 constructible<
1234 typename ::boost::remove_const<
1235 typename boost::remove_reference<Tag2>::type
1236 >::type(const typename boost::remove_reference<Tag2>::type&)
1237 >(), other)
1238 )
1239 {}
1240 template<class Concept2, class Tag2>
1241 any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
1242 : table(binding_arg),
1243 data(::boost::type_erasure::call(
1244 constructible<
1245 typename ::boost::remove_const<
1246 typename boost::remove_reference<Tag2>::type
1247 >::type(const typename boost::remove_reference<Tag2>::type&)
1248 >(), other)
1249 )
1250 {}
1251 template<class Concept2, class Tag2>
1252 any(const any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
1253 : table(binding_arg),
1254 data(::boost::type_erasure::call(
1255 constructible<
1256 typename ::boost::remove_const<
1257 typename boost::remove_reference<Tag2>::type
1258 >::type(const typename boost::remove_reference<Tag2>::type&)
1259 >(), other)
1260 )
1261 {}
1262
1263#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1264 template<class Concept2, class Tag2, class Map>
1265 any(any<Concept2, Tag2>& other, static_binding<Map>&& binding_arg)
1266 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1267 data(::boost::type_erasure::call(
1268 constructible<
1269 typename ::boost::remove_const<
1270 typename boost::remove_reference<Tag2>::type
1271 >::type(const typename boost::remove_reference<Tag2>::type&)
1272 >(), other)
1273 )
1274 {}
1275 template<class Concept2, class Tag2, class Map>
1276 any(const any<Concept2, Tag2>& other, static_binding<Map>&& binding_arg)
1277 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1278 data(::boost::type_erasure::call(
1279 constructible<
1280 typename ::boost::remove_const<
1281 typename boost::remove_reference<Tag2>::type
1282 >::type(const typename boost::remove_reference<Tag2>::type&)
1283 >(), other)
1284 )
1285 {}
1286 template<class Concept2, class Tag2, class Map>
1287 any(any<Concept2, Tag2>&& other, static_binding<Map>&& binding_arg)
1288 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1289 data(::boost::type_erasure::call(
1290 constructible<
1291 typename ::boost::remove_const<
1292 typename boost::remove_reference<Tag2>::type
1293 >::type(const typename boost::remove_reference<Tag2>::type&)
1294 >(), std::move(other))
1295 )
1296 {}
1297 template<class Concept2, class Tag2, class Map>
1298 any(any<Concept2, Tag2>&& other, static_binding<Map>& binding_arg)
1299 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1300 data(::boost::type_erasure::call(
1301 constructible<
1302 typename ::boost::remove_const<
1303 typename boost::remove_reference<Tag2>::type
1304 >::type(const typename boost::remove_reference<Tag2>::type&)
1305 >(), std::move(other))
1306 )
1307 {}
1308 template<class Concept2, class Tag2, class Map>
1309 any(any<Concept2, Tag2>&& other, const static_binding<Map>& binding_arg)
1310 : table(::boost::type_erasure::detail::access::table(other), binding_arg),
1311 data(::boost::type_erasure::call(
1312 constructible<
1313 typename ::boost::remove_const<
1314 typename boost::remove_reference<Tag2>::type
1315 >::type(const typename boost::remove_reference<Tag2>::type&)
1316 >(), std::move(other))
1317 )
1318 {}
1319 template<class Concept2, class Tag2>
1320 any(any<Concept2, Tag2>& other, binding<Concept>&& binding_arg)
1321 : table(binding_arg),
1322 data(::boost::type_erasure::call(
1323 constructible<
1324 typename ::boost::remove_const<
1325 typename boost::remove_reference<Tag2>::type
1326 >::type(const typename boost::remove_reference<Tag2>::type&)
1327 >(), other)
1328 )
1329 {}
1330 template<class Concept2, class Tag2>
1331 any(const any<Concept2, Tag2>& other, binding<Concept>&& binding_arg)
1332 : table(binding_arg),
1333 data(::boost::type_erasure::call(
1334 constructible<
1335 typename ::boost::remove_const<
1336 typename boost::remove_reference<Tag2>::type
1337 >::type(const typename boost::remove_reference<Tag2>::type&)
1338 >(), other)
1339 )
1340 {}
1341 template<class Concept2, class Tag2>
1342 any(any<Concept2, Tag2>&& other, binding<Concept>&& binding_arg)
1343 : table(binding_arg),
1344 data(::boost::type_erasure::call(
1345 constructible<
1346 typename ::boost::remove_const<
1347 typename boost::remove_reference<Tag2>::type
1348 >::type(const typename boost::remove_reference<Tag2>::type&)
1349 >(), std::move(other))
1350 )
1351 {}
1352 template<class Concept2, class Tag2>
1353 any(any<Concept2, Tag2>&& other, binding<Concept>& binding_arg)
1354 : table(binding_arg),
1355 data(::boost::type_erasure::call(
1356 constructible<
1357 typename ::boost::remove_const<
1358 typename boost::remove_reference<Tag2>::type
1359 >::type(const typename boost::remove_reference<Tag2>::type&)
1360 >(), std::move(other))
1361 )
1362 {}
1363 template<class Concept2, class Tag2>
1364 any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg)
1365 : table(binding_arg),
1366 data(::boost::type_erasure::call(
1367 constructible<
1368 typename ::boost::remove_const<
1369 typename boost::remove_reference<Tag2>::type
1370 >::type(const typename boost::remove_reference<Tag2>::type&)
1371 >(), std::move(other))
1372 )
1373 {}
1374#endif
1375
1376 // One argument is a special case. The argument must be an any
1377 // and the constructor must be explicit.
1378 template<class Tag2>
1379 explicit any(const any<Concept, Tag2>& other)
1380 : table(::boost::type_erasure::detail::access::table(other)),
1381 data(::boost::type_erasure::call(
1382 ::boost::type_erasure::detail::make(
1383 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1384 ), other)
1385 )
1386 {}
1387 template<class Tag2>
1388 explicit any(any<Concept, Tag2>& other)
1389 : table(::boost::type_erasure::detail::access::table(other)),
1390 data(::boost::type_erasure::call(
1391 ::boost::type_erasure::detail::make(
1392 false? this->_boost_type_erasure_deduce_constructor(other) : 0
1393 ), other)
1394 )
1395 {}
1396
1397#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1398 template<class Tag2>
1399 explicit any(any<Concept, Tag2>&& other)
1400 : table(::boost::type_erasure::detail::access::table(other)),
1401 data(::boost::type_erasure::call(
1402 ::boost::type_erasure::detail::make(
1403 false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0
1404 ), std::move(other))
1405 )
1406 {}
1407#endif
1408
1409 explicit any(const binding<Concept>& binding_arg)
1410 : table(binding_arg),
1411 data(
1412 ::boost::type_erasure::call(
1413 binding_arg,
1414 ::boost::type_erasure::constructible<T()>()
1415 )
1416 )
1417 {}
1418 explicit any(binding<Concept>& binding_arg)
1419 : table(binding_arg),
1420 data(
1421 ::boost::type_erasure::call(
1422 binding_arg,
1423 ::boost::type_erasure::constructible<T()>()
1424 )
1425 )
1426 {}
1427
1428#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1429
1430 explicit any(binding<Concept>&& binding_arg)
1431 : table(binding_arg),
1432 data(
1433 ::boost::type_erasure::call(
1434 binding_arg,
1435 ::boost::type_erasure::constructible<T()>()
1436 )
1437 )
1438 {}
1439
1440#endif
1441
1442#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
1443
1444 template<class R, class... A, class... U>
1445 const table_type& _boost_type_erasure_extract_table(
1446 ::boost::type_erasure::constructible<R(A...)>*,
1447 U&&... u)
1448 {
1449 return *::boost::type_erasure::detail::extract_table(static_cast<void(*)(A...)>(0), u...);
1450 }
1451
1452 template<class U0, class U1, class... U>
1453 any(U0&& u0, U1&& u1, U&&... u)
1454 : table(
1455 _boost_type_erasure_extract_table(
1456 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0,
1457 std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...
1458 )
1459 ),
1460 data(
1461 ::boost::type_erasure::call(
1462 ::boost::type_erasure::detail::make(
1463 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0
1464 ),
1465 std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...
1466 )
1467 )
1468 {}
1469
1470 template<class U0, class... U>
1471 any(const binding<Concept>& binding_arg, U0&& u0, U&&... u)
1472 : table(binding_arg),
1473 data(
1474 ::boost::type_erasure::call(
1475 binding_arg,
1476 ::boost::type_erasure::detail::make(
1477 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
1478 ),
1479 std::forward<U0>(u0), std::forward<U>(u)...
1480 )
1481 )
1482 {}
1483
1484 // disambiguating overloads
1485 template<class U0, class... U>
1486 any(binding<Concept>& binding_arg, U0&& u0, U&&... u)
1487 : table(binding_arg),
1488 data(
1489 ::boost::type_erasure::call(
1490 binding_arg,
1491 ::boost::type_erasure::detail::make(
1492 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
1493 ),
1494 std::forward<U0>(u0), std::forward<U>(u)...
1495 )
1496 )
1497 {}
1498 template<class U0, class... U>
1499 any(binding<Concept>&& binding_arg, U0&& u0, U&&... u)
1500 : table(binding_arg),
1501 data(
1502 ::boost::type_erasure::call(
1503 binding_arg,
1504 ::boost::type_erasure::detail::make(
1505 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
1506 ),
1507 std::forward<U0>(u0), std::forward<U>(u)...
1508 )
1509 )
1510 {}
1511
1512#else
1513
1514#include <boost/type_erasure/detail/construct.hpp>
1515
1516#endif
1517
1518#endif
1519
1520 /** INTERNAL ONLY */
1521 any& operator=(const any& other)
1522 {
1523 _boost_type_erasure_resolve_assign(other);
1524 return *this;
1525 }
1526 /** INTERNAL ONLY */
1527 any& operator=(any& other)
1528 {
1529 _boost_type_erasure_resolve_assign(other);
1530 return *this;
1531 }
1532
1533#endif // BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
1534
1535#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
1536 template<class U>
1537 any& operator=(U& other)
1538 {
1539 _boost_type_erasure_resolve_assign(other);
1540 return *this;
1541 }
1542 template<class U>
1543 any& operator=(const U& other)
1544 {
1545 _boost_type_erasure_resolve_assign(other);
1546 return *this;
1547 }
1548#else
1549#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
1550 /** INTERNAL ONLY */
1551 any& operator=(any&& other)
1552 {
1553 _boost_type_erasure_resolve_assign(std::move(other));
1554 return *this;
1555 }
1556#endif
1557 /**
1558 * Assigns to an @ref any.
1559 *
1560 * If an appropriate overload of @ref assignable is not available
1561 * and @ref relaxed is in @c Concept, falls back on
1562 * constructing from @c other.
1563 *
1564 * \note If @c U is an @ref any, then this can decide dynamically
1565 * whether to use construction based on the type stored in other.
1566 *
1567 * \throws Whatever the assignment operator of the contained
1568 * type throws. When falling back on construction,
1569 * throws @c std::bad_alloc or whatever the move (or copy)
1570 * constructor of the contained type throws. In
1571 * this case move assignment provides the strong exception
1572 * guarantee. When calling a (move) assignment operator
1573 * of the contained type, the exception guarantee is
1574 * whatever the contained type provides.
1575 */
1576 template<class U>
1577 any& operator=(U&& other)
1578 {
1579 _boost_type_erasure_resolve_assign(std::forward<U>(other));
1580 return *this;
1581 }
1582#endif
1583
1584#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
1585 /**
1586 * \pre @c Concept includes @ref destructible "destructible<T>".
1587 */
1588 ~any()
1589 {
1590 ::boost::type_erasure::detail::access::table(*this).template find<
1591 ::boost::type_erasure::destructible<T>
1592 >()(::boost::type_erasure::detail::access::data(*this));
1593 }
1594#endif
1595
1596#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
1597 /** INTERNAL ONLY */
1598 operator param<Concept, T&>() &
1599 {
1600 return param<Concept, T&>(
1601 boost::type_erasure::detail::access::data(*this),
1602 boost::type_erasure::detail::access::table(*this));
1603 }
1604 /** INTERNAL ONLY */
1605 operator param<Concept, T&&>() && {
1606 return param<Concept, T&&>(
1607 boost::type_erasure::detail::access::data(*this),
1608 boost::type_erasure::detail::access::table(*this));
1609 }
1610#endif
1611private:
1612#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
1613 /** INTERNAL ONLY */
1614 void _boost_type_erasure_swap(any& other)
1615 {
1616 ::std::swap(data, other.data);
1617 ::std::swap(table, other.table);
1618 }
1619#else
1620 void _boost_type_erasure_swap(any& other)
1621 {
1622 ::std::swap(this->_boost_type_erasure_data, other._boost_type_erasure_data);
1623 ::std::swap(this->_boost_type_erasure_table, other._boost_type_erasure_table);
1624 }
1625#endif
1626#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1627 /** INTERNAL ONLY */
1628 template<class Other>
1629 void _boost_type_erasure_resolve_assign(Other&& other)
1630 {
1631 _boost_type_erasure_assign_impl(
1632 std::forward<Other>(other),
1633 false? this->_boost_type_erasure_deduce_assign(
1634 ::boost::type_erasure::detail::make_fallback(
1635 std::forward<Other>(other),
1636 ::boost::mpl::bool_<
1637 sizeof(
1638 ::boost::type_erasure::detail::check_overload(
1639 ::boost::declval<any&>().
1640 _boost_type_erasure_deduce_assign(std::forward<Other>(other))
1641 )
1642 ) == sizeof(::boost::type_erasure::detail::yes)
1643 >()
1644 )
1645 ) : 0,
1646 ::boost::type_erasure::is_relaxed<Concept>()
1647 );
1648 }
1649 /** INTERNAL ONLY */
1650 template<class Other, class U>
1651 void _boost_type_erasure_assign_impl(
1652 Other&& other,
1653 const assignable<T, U>*,
1654 ::boost::mpl::false_)
1655 {
1656 ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
1657 }
1658 /** INTERNAL ONLY */
1659 template<class Other, class U>
1660 void _boost_type_erasure_assign_impl(
1661 Other&& other,
1662 const assignable<T, U>*,
1663 ::boost::mpl::true_)
1664 {
1665 ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
1666 }
1667 /** INTERNAL ONLY */
1668 template<class Other>
1669 void _boost_type_erasure_assign_impl(
1670 Other&& other,
1671 const void*,
1672 ::boost::mpl::true_)
1673 {
1674 any temp(std::forward<Other>(other));
1675 _boost_type_erasure_swap(other&: temp);
1676 }
1677#else
1678 /** INTERNAL ONLY */
1679 template<class Other>
1680 void _boost_type_erasure_resolve_assign(Other& other)
1681 {
1682 _boost_type_erasure_assign_impl(
1683 other,
1684 false? this->_boost_type_erasure_deduce_assign(
1685 ::boost::type_erasure::detail::make_fallback(
1686 other,
1687 ::boost::mpl::bool_<
1688 sizeof(
1689 ::boost::type_erasure::detail::check_overload(
1690 ::boost::declval<any&>().
1691 _boost_type_erasure_deduce_assign(other)
1692 )
1693 ) == sizeof(::boost::type_erasure::detail::yes)
1694 >()
1695 )
1696 ) : 0,
1697 ::boost::type_erasure::is_relaxed<Concept>()
1698 );
1699 }
1700 /** INTERNAL ONLY */
1701 template<class Other, class U>
1702 void _boost_type_erasure_assign_impl(
1703 Other& other,
1704 const assignable<T, U>*,
1705 ::boost::mpl::false_)
1706 {
1707 ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1708 }
1709 /** INTERNAL ONLY */
1710 template<class Other, class U>
1711 void _boost_type_erasure_assign_impl(
1712 Other& other,
1713 const assignable<T, U>*,
1714 ::boost::mpl::true_)
1715 {
1716 ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1717 }
1718 /** INTERNAL ONLY */
1719 template<class Other>
1720 void _boost_type_erasure_assign_impl(
1721 Other& other,
1722 const void*,
1723 ::boost::mpl::true_)
1724 {
1725 any temp(other);
1726 _boost_type_erasure_swap(temp);
1727 }
1728#endif
1729 /** INTERNAL ONLY */
1730 template<class Concept2, class Tag2>
1731 void _boost_type_erasure_resolve_assign(const any<Concept2, Tag2>& other)
1732 {
1733 _boost_type_erasure_resolve_assign_any(other);
1734 }
1735 /** INTERNAL ONLY */
1736 template<class Concept2, class Tag2>
1737 void _boost_type_erasure_resolve_assign(any<Concept2, Tag2>& other)
1738 {
1739 _boost_type_erasure_resolve_assign_any(other);
1740 }
1741#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1742 /** INTERNAL ONLY */
1743 template<class Concept2, class Tag2>
1744 void _boost_type_erasure_resolve_assign(any<Concept2, Tag2>&& other)
1745 {
1746 _boost_type_erasure_resolve_assign_any(std::move(other));
1747 }
1748 /** INTERNAL ONLY */
1749 template<class Other>
1750 void _boost_type_erasure_resolve_assign_any(Other&& other)
1751 {
1752 _boost_type_erasure_assign_impl(
1753 std::forward<Other>(other),
1754 false? this->_boost_type_erasure_deduce_assign(
1755 ::boost::type_erasure::detail::make_fallback(
1756 std::forward<Other>(other),
1757 ::boost::mpl::bool_<
1758 sizeof(
1759 ::boost::type_erasure::detail::check_overload(
1760 ::boost::declval<any&>().
1761 _boost_type_erasure_deduce_assign(std::forward<Other>(other))
1762 )
1763 ) == sizeof(::boost::type_erasure::detail::yes)
1764 >()
1765 )
1766 ) : 0,
1767 false? this->_boost_type_erasure_deduce_constructor(
1768 ::boost::type_erasure::detail::make_fallback(
1769 std::forward<Other>(other),
1770 ::boost::mpl::bool_<
1771 sizeof(
1772 ::boost::type_erasure::detail::check_overload(
1773 ::boost::declval<any&>().
1774 _boost_type_erasure_deduce_constructor(std::forward<Other>(other))
1775 )
1776 ) == sizeof(::boost::type_erasure::detail::yes)
1777 >()
1778 )
1779 ) : 0,
1780 ::boost::type_erasure::is_relaxed<Concept>()
1781 );
1782 }
1783 /** INTERNAL ONLY */
1784 template<class Other, class U>
1785 void _boost_type_erasure_assign_impl(
1786 Other&& other,
1787 const assignable<T, U>*,
1788 const void*,
1789 ::boost::mpl::false_)
1790 {
1791 ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
1792 }
1793 /** INTERNAL ONLY */
1794 template<class Other, class U>
1795 void _boost_type_erasure_assign_impl(
1796 Other&& other,
1797 const assignable<T, U>*,
1798 const void*,
1799 ::boost::mpl::true_)
1800 {
1801 ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
1802 }
1803 /** INTERNAL ONLY */
1804 template<class Other, class Sig>
1805 void _boost_type_erasure_assign_impl(
1806 Other&& other,
1807 const void*,
1808 const constructible<Sig>*,
1809 ::boost::mpl::true_)
1810 {
1811 any temp(std::forward<Other>(other));
1812 _boost_type_erasure_swap(other&: temp);
1813 }
1814 /** INTERNAL ONLY */
1815 template<class Other, class U, class Sig>
1816 void _boost_type_erasure_assign_impl(
1817 Other&& other,
1818 const assignable<T, U>*,
1819 const constructible<Sig>*,
1820 ::boost::mpl::true_)
1821 {
1822 if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) // const reference to other is enough!
1823 {
1824 ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, std::forward<Other>(other));
1825 }
1826 else
1827 {
1828 any temp(std::forward<Other>(other));
1829 _boost_type_erasure_swap(other&: temp);
1830 }
1831 }
1832#else
1833 /** INTERNAL ONLY */
1834 template<class Other>
1835 void _boost_type_erasure_resolve_assign_any(Other& other)
1836 {
1837 _boost_type_erasure_assign_impl(
1838 other,
1839 false? this->_boost_type_erasure_deduce_assign(
1840 ::boost::type_erasure::detail::make_fallback(
1841 other,
1842 ::boost::mpl::bool_<
1843 sizeof(
1844 ::boost::type_erasure::detail::check_overload(
1845 ::boost::declval<any&>().
1846 _boost_type_erasure_deduce_assign(other)
1847 )
1848 ) == sizeof(::boost::type_erasure::detail::yes)
1849 >()
1850 )
1851 ) : 0,
1852 false? this->_boost_type_erasure_deduce_constructor(
1853 ::boost::type_erasure::detail::make_fallback(
1854 other,
1855 ::boost::mpl::bool_<
1856 sizeof(
1857 ::boost::type_erasure::detail::check_overload(
1858 ::boost::declval<any&>().
1859 _boost_type_erasure_deduce_constructor(other)
1860 )
1861 ) == sizeof(::boost::type_erasure::detail::yes)
1862 >()
1863 )
1864 ) : 0,
1865 ::boost::type_erasure::is_relaxed<Concept>()
1866 );
1867 }
1868 /** INTERNAL ONLY */
1869 template<class Other, class U>
1870 void _boost_type_erasure_assign_impl(
1871 Other& other,
1872 const assignable<T, U>*,
1873 const void*,
1874 ::boost::mpl::false_)
1875 {
1876 ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1877 }
1878 /** INTERNAL ONLY */
1879 template<class Other, class U>
1880 void _boost_type_erasure_assign_impl(
1881 Other& other,
1882 const assignable<T, U>*,
1883 const void*,
1884 ::boost::mpl::true_)
1885 {
1886 ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1887 }
1888 /** INTERNAL ONLY */
1889 template<class Other, class Sig>
1890 void _boost_type_erasure_assign_impl(
1891 Other& other,
1892 const void*,
1893 const constructible<Sig>*,
1894 ::boost::mpl::true_)
1895 {
1896 any temp(other);
1897 _boost_type_erasure_swap(temp);
1898 }
1899 /** INTERNAL ONLY */
1900 template<class Other, class U, class Sig>
1901 void _boost_type_erasure_assign_impl(
1902 Other& other,
1903 const assignable<T, U>*,
1904 const constructible<Sig>*,
1905 ::boost::mpl::true_)
1906 {
1907 if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other))
1908 {
1909 ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
1910 }
1911 else
1912 {
1913 any temp(other);
1914 _boost_type_erasure_swap(temp);
1915 }
1916 }
1917#endif
1918 friend struct ::boost::type_erasure::detail::access;
1919#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
1920 // The table has to be initialized first for exception
1921 // safety in some constructors.
1922 table_type table;
1923 ::boost::type_erasure::detail::storage data;
1924#else
1925 template<class Concept2, class T2>
1926 friend struct ::boost::type_erasure::any_constructor_impl;
1927#endif
1928};
1929
1930template<class Concept, class T>
1931class any<Concept, T&> :
1932 public ::boost::type_erasure::detail::compute_bases<
1933 ::boost::type_erasure::any<Concept, T&>,
1934 Concept,
1935 T
1936 >::type
1937{
1938 typedef ::boost::type_erasure::binding<Concept> table_type;
1939public:
1940 /** INTERNAL ONLY */
1941 typedef Concept _boost_type_erasure_concept_type;
1942 /** INTERNAL ONLY */
1943 any(const ::boost::type_erasure::detail::storage& data_arg,
1944 const table_type& table_arg)
1945 : data(data_arg),
1946 table(table_arg)
1947 {}
1948 /**
1949 * Constructs an @ref any from a reference.
1950 *
1951 * \param arg The object to bind the reference to.
1952 *
1953 * \pre @c U is a model of @c Concept.
1954 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1955 *
1956 * \throws Nothing.
1957 */
1958 template<class U>
1959 any(U& arg
1960#ifndef BOOST_TYPE_ERASURE_DOXYGEN
1961 , typename ::boost::disable_if<
1962 ::boost::mpl::or_<
1963 ::boost::is_const<U>,
1964 ::boost::type_erasure::detail::is_any<U>
1965 >
1966 >::type* = 0
1967#endif
1968 )
1969 : table((
1970 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
1971 ::boost::type_erasure::make_binding<
1972 ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
1973 >()
1974 ))
1975 {
1976 data.data = ::boost::addressof(arg);
1977 }
1978 /**
1979 * Constructs an @ref any from a reference.
1980 *
1981 * \param arg The object to bind the reference to.
1982 * \param binding Specifies the actual types that
1983 * all the placeholders should bind to.
1984 *
1985 * \pre @c U is a model of @c Concept.
1986 * \pre @c Map is an MPL map with an entry for every
1987 * non-deduced placeholder referred to by @c Concept.
1988 *
1989 * \throws Nothing.
1990 */
1991 template<class U, class Map>
1992 any(U& arg, const static_binding<Map>& binding_arg)
1993 : table((
1994 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1995 binding_arg
1996 ))
1997 {
1998 BOOST_MPL_ASSERT((::boost::is_same<
1999 typename ::boost::mpl::at<Map, T>::type, U>));
2000 data.data = ::boost::addressof(arg);
2001 }
2002 /**
2003 * Constructs an @ref any from another reference.
2004 *
2005 * \param other The reference to copy.
2006 *
2007 * \throws Nothing.
2008 */
2009 any(const any& other)
2010 : data(other.data),
2011 table(other.table)
2012 {}
2013#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2014 any(any& other)
2015 : data(other.data),
2016 table(other.table)
2017 {}
2018#endif
2019 /**
2020 * Constructs an @ref any from another @ref any.
2021 *
2022 * \param other The object to bind the reference to.
2023 *
2024 * \throws Nothing.
2025 */
2026 any(any<Concept, T>& other)
2027 : data(::boost::type_erasure::detail::access::data(other)),
2028 table(::boost::type_erasure::detail::access::table(other))
2029 {}
2030 /**
2031 * Constructs an @ref any from another reference.
2032 *
2033 * \param other The reference to copy.
2034 *
2035 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2036 * \pre After substituting @c T for @c Tag2, the requirements of
2037 * @c Concept2 must be a superset of the requirements of
2038 * @c Concept.
2039 *
2040 * \throws std::bad_alloc
2041 */
2042 template<class Concept2, class Tag2>
2043 any(const any<Concept2, Tag2&>& other
2044#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2045 , typename ::boost::disable_if<
2046 ::boost::mpl::or_<
2047 ::boost::is_same<Concept, Concept2>,
2048 ::boost::is_const<Tag2>
2049 >
2050 >::type* = 0
2051#endif
2052 )
2053 : data(::boost::type_erasure::detail::access::data(other)),
2054 table(
2055 ::boost::type_erasure::detail::access::table(other),
2056 ::boost::mpl::map1<
2057 ::boost::mpl::pair<
2058 T,
2059 Tag2
2060 >
2061 >())
2062 {}
2063 /**
2064 * Constructs an @ref any from another @ref any.
2065 *
2066 * \param other The object to bind the reference to.
2067 *
2068 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2069 * \pre After substituting @c T for @c Tag2, the requirements of
2070 * @c Concept2 must be a superset of the requirements of
2071 * @c Concept.
2072 *
2073 * \throws std::bad_alloc
2074 */
2075 template<class Concept2, class Tag2>
2076 any(any<Concept2, Tag2>& other
2077#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2078 , typename ::boost::disable_if<
2079 ::boost::mpl::or_<
2080 ::boost::is_same<Concept, Concept2>,
2081 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2082 >
2083 >::type* = 0
2084#endif
2085 )
2086 : data(::boost::type_erasure::detail::access::data(other)),
2087 table(
2088 ::boost::type_erasure::detail::access::table(other),
2089 ::boost::mpl::map1<
2090 ::boost::mpl::pair<
2091 T,
2092 typename ::boost::remove_reference<Tag2>::type
2093 >
2094 >())
2095 {}
2096 /**
2097 * Constructs an @ref any from another reference.
2098 *
2099 * \param other The reference to copy.
2100 * \param binding Specifies the mapping between the two concepts.
2101 *
2102 * \pre @c Map must be an MPL map with keys for all the non-deduced
2103 * placeholders used by @c Concept and values for the corresponding
2104 * placeholders in @c Concept2.
2105 * \pre After substituting placeholders according to @c Map, the
2106 * requirements of @c Concept2 must be a superset of the
2107 * requirements of @c Concept.
2108 *
2109 * \throws std::bad_alloc
2110 */
2111 template<class Concept2, class Tag2, class Map>
2112 any(const any<Concept2, Tag2&>& other, const static_binding<Map>& binding_arg
2113#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2114 , typename ::boost::disable_if< ::boost::is_const<Tag2> >::type* = 0
2115#endif
2116 )
2117 : data(::boost::type_erasure::detail::access::data(other)),
2118 table(::boost::type_erasure::detail::access::table(other), binding_arg)
2119 {}
2120 /**
2121 * Constructs an @ref any from another @ref any.
2122 *
2123 * \param other The object to bind the reference to.
2124 * \param binding Specifies the mapping between the two concepts.
2125 *
2126 * \pre @c Map must be an MPL map with keys for all the non-deduced
2127 * placeholders used by @c Concept and values for the corresponding
2128 * placeholders in @c Concept2.
2129 * \pre After substituting placeholders according to @c Map, the
2130 * requirements of @c Concept2 must be a superset of the
2131 * requirements of @c Concept.
2132 *
2133 * \throws std::bad_alloc
2134 */
2135 template<class Concept2, class Tag2, class Map>
2136 any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg
2137#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2138 , typename ::boost::disable_if<
2139 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2140 >::type* = 0
2141#endif
2142 )
2143 : data(::boost::type_erasure::detail::access::data(other)),
2144 table(::boost::type_erasure::detail::access::table(other), binding_arg)
2145 {}
2146 /**
2147 * Constructs an @ref any from another reference.
2148 *
2149 * \param other The reference to copy.
2150 * \param binding Specifies the bindings of placeholders to actual types.
2151 *
2152 * \pre The type stored in @c other must match the type expected by
2153 * @c binding.
2154 *
2155 * \post binding_of(*this) == @c binding
2156 *
2157 * \throws Nothing.
2158 */
2159 template<class Concept2, class Tag2>
2160 any(const any<Concept2, Tag2&>& other, const binding<Concept>& binding_arg
2161#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2162 , typename ::boost::disable_if<
2163 ::boost::is_const<Tag2>
2164 >::type* = 0
2165#endif
2166 )
2167 : data(::boost::type_erasure::detail::access::data(other)),
2168 table(binding_arg)
2169 {}
2170 /**
2171 * Constructs an @ref any from another @ref any.
2172 *
2173 * \param other The object to bind the reference to.
2174 * \param binding Specifies the bindings of placeholders to actual types.
2175 *
2176 * \pre The type stored in @c other must match the type expected by
2177 * @c binding.
2178 *
2179 * \post binding_of(*this) == @c binding
2180 *
2181 * \throws Nothing.
2182 */
2183 template<class Concept2, class Tag2>
2184 any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg
2185#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2186 , typename ::boost::disable_if<
2187 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2188 >::type* = 0
2189#endif
2190 )
2191 : data(::boost::type_erasure::detail::access::data(other)),
2192 table(binding_arg)
2193 {}
2194
2195 /** INTERNAL ONLY */
2196 any& operator=(const any& other)
2197 {
2198 _boost_type_erasure_resolve_assign(other);
2199 return *this;
2200 }
2201
2202 /** INTERNAL ONLY */
2203 any& operator=(any& other)
2204 {
2205 _boost_type_erasure_resolve_assign(other);
2206 return *this;
2207 }
2208
2209#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2210 /** INTERNAL ONLY */
2211 any& operator=(any&& other)
2212 {
2213 _boost_type_erasure_resolve_assign(std::move(other));
2214 return *this;
2215 }
2216 /**
2217 * Assigns to an @ref any.
2218 *
2219 * If an appropriate overload of @ref assignable is not available
2220 * and @ref relaxed is in @c Concept, falls back on
2221 * constructing from @c other.
2222 *
2223 * \throws Whatever the assignment operator of the contained
2224 * type throws. When falling back on construction,
2225 * can only throw @c std::bad_alloc if @c U is an @ref any
2226 * that uses a different @c Concept. In this case assignment
2227 * provides the strong exception guarantee. When
2228 * calling the assignment operator of the contained type,
2229 * the exception guarantee is whatever the contained type provides.
2230 */
2231 template<class U>
2232 any& operator=(U&& other)
2233 {
2234 _boost_type_erasure_resolve_assign(std::forward<U>(other));
2235 return *this;
2236 }
2237#else
2238 template<class U>
2239 any& operator=(U& other)
2240 {
2241 _boost_type_erasure_resolve_assign(other);
2242 return *this;
2243 }
2244
2245 template<class U>
2246 any& operator=(const U& other)
2247 {
2248 _boost_type_erasure_resolve_assign(other);
2249 return *this;
2250 }
2251#endif
2252
2253#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
2254 /** INTERNAL ONLY */
2255 operator param<Concept, T&>() const { return param<Concept, T&>(data, table); }
2256#endif
2257private:
2258
2259 /** INTERNAL ONLY */
2260 void _boost_type_erasure_swap(any& other)
2261 {
2262 ::std::swap(a&: data, b&: other.data);
2263 ::std::swap(table, other.table);
2264 }
2265#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2266 /** INTERNAL ONLY */
2267 template<class Other>
2268 void _boost_type_erasure_resolve_assign(Other&& other)
2269 {
2270 _boost_type_erasure_assign_impl(
2271 std::forward<Other>(other),
2272 false? this->_boost_type_erasure_deduce_assign(
2273 ::boost::type_erasure::detail::make_fallback(
2274 std::forward<Other>(other),
2275 ::boost::mpl::bool_<
2276 sizeof(
2277 ::boost::type_erasure::detail::check_overload(
2278 ::boost::declval<any&>().
2279 _boost_type_erasure_deduce_assign(std::forward<Other>(other))
2280 )
2281 ) == sizeof(::boost::type_erasure::detail::yes)
2282 >()
2283 )
2284 ) : 0,
2285 ::boost::mpl::and_<
2286 ::boost::type_erasure::is_relaxed<Concept>,
2287 ::boost::is_convertible<Other, any>
2288#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
2289 , ::boost::mpl::not_<
2290 ::boost::type_erasure::detail::is_rvalue_for_any<Other>
2291 >
2292#endif
2293 >()
2294 );
2295 }
2296 /** INTERNAL ONLY */
2297 template<class Other, class U>
2298 void _boost_type_erasure_assign_impl(
2299 Other&& other,
2300 const assignable<T, U>*,
2301 ::boost::mpl::false_)
2302 {
2303 ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
2304 }
2305 /** INTERNAL ONLY */
2306 template<class Other, class U>
2307 void _boost_type_erasure_assign_impl(
2308 Other&& other,
2309 const assignable<T, U>*,
2310 ::boost::mpl::true_)
2311 {
2312 if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) {
2313 ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, std::forward<Other>(other));
2314 } else {
2315 any temp(std::forward<Other>(other));
2316 _boost_type_erasure_swap(other&: temp);
2317 }
2318 }
2319 /** INTERNAL ONLY */
2320 template<class Other>
2321 void _boost_type_erasure_assign_impl(
2322 Other&& other,
2323 const void*,
2324 ::boost::mpl::true_)
2325 {
2326 any temp(std::forward<Other>(other));
2327 _boost_type_erasure_swap(other&: temp);
2328 }
2329#else
2330 /** INTERNAL ONLY */
2331 template<class Other>
2332 void _boost_type_erasure_resolve_assign(Other& other)
2333 {
2334 _boost_type_erasure_assign_impl(
2335 other,
2336 false? this->_boost_type_erasure_deduce_assign(
2337 ::boost::type_erasure::detail::make_fallback(
2338 other,
2339 ::boost::mpl::bool_<
2340 sizeof(
2341 ::boost::type_erasure::detail::check_overload(
2342 ::boost::declval<any&>().
2343 _boost_type_erasure_deduce_assign(other)
2344 )
2345 ) == sizeof(::boost::type_erasure::detail::yes)
2346 >()
2347 )
2348 ) : 0,
2349 ::boost::mpl::and_<
2350 ::boost::type_erasure::is_relaxed<Concept>,
2351 ::boost::is_convertible<Other&, any>
2352 >()
2353 );
2354 }
2355 /** INTERNAL ONLY */
2356 template<class Other, class U>
2357 void _boost_type_erasure_assign_impl(
2358 Other& other,
2359 const assignable<T, U>*,
2360 ::boost::mpl::false_)
2361 {
2362 ::boost::type_erasure::call(assignable<T, U>(), *this, other);
2363 }
2364 /** INTERNAL ONLY */
2365 template<class Other, class U>
2366 void _boost_type_erasure_assign_impl(
2367 Other& other,
2368 const assignable<T, U>*,
2369 ::boost::mpl::true_)
2370 {
2371 if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) {
2372 ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
2373 } else {
2374 any temp(other);
2375 _boost_type_erasure_swap(temp);
2376 }
2377 }
2378 /** INTERNAL ONLY */
2379 template<class Other>
2380 void _boost_type_erasure_assign_impl(
2381 Other& other,
2382 const void*,
2383 ::boost::mpl::true_)
2384 {
2385 any temp(other);
2386 _boost_type_erasure_swap(temp);
2387 }
2388#endif
2389
2390 friend struct ::boost::type_erasure::detail::access;
2391 ::boost::type_erasure::detail::storage data;
2392 table_type table;
2393};
2394
2395#ifdef BOOST_MSVC
2396#pragma warning(pop)
2397#endif
2398
2399template<class Concept, class T>
2400class any<Concept, const T&> :
2401 public ::boost::type_erasure::detail::compute_bases<
2402 ::boost::type_erasure::any<Concept, const T&>,
2403 Concept,
2404 T
2405 >::type
2406{
2407 typedef ::boost::type_erasure::binding<Concept> table_type;
2408public:
2409 /** INTERNAL ONLY */
2410 typedef Concept _boost_type_erasure_concept_type;
2411 /** INTERNAL ONLY */
2412 any(const ::boost::type_erasure::detail::storage& data_arg,
2413 const table_type& table_arg)
2414 : data(data_arg),
2415 table(table_arg)
2416 {}
2417 /**
2418 * Constructs an @ref any from a reference.
2419 *
2420 * \param arg The object to bind the reference to.
2421 *
2422 * \pre @c U is a model of @c Concept.
2423 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2424 *
2425 * \throws Nothing.
2426 */
2427 template<class U>
2428 any(const U& arg)
2429 : table((
2430 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
2431 ::boost::type_erasure::make_binding<
2432 ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
2433 >()
2434 ))
2435 {
2436 data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
2437 }
2438 /**
2439 * Constructs an @ref any from a reference.
2440 *
2441 * \param arg The object to bind the reference to.
2442 * \param binding Specifies the actual types that
2443 * all the placeholders should bind to.
2444 *
2445 * \pre @c U is a model of @c Concept.
2446 * \pre @c Map is an MPL map with an entry for every
2447 * non-deduced placeholder referred to by @c Concept.
2448 *
2449 * \throws Nothing.
2450 */
2451 template<class U, class Map>
2452 any(const U& arg, const static_binding<Map>& binding_arg)
2453 : table((
2454 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
2455 binding_arg
2456 ))
2457 {
2458 BOOST_MPL_ASSERT((::boost::is_same<
2459 typename ::boost::mpl::at<Map, T>::type, U>));
2460 data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
2461 }
2462 /**
2463 * Constructs an @ref any from another @ref any.
2464 *
2465 * \param other The reference to copy.
2466 *
2467 * \throws Nothing.
2468 */
2469 any(const any& other)
2470 : data(other.data),
2471 table(other.table)
2472 {}
2473 /**
2474 * Constructs an @ref any from another @ref any.
2475 *
2476 * \param other The reference to copy.
2477 *
2478 * \throws Nothing.
2479 */
2480 any(const any<Concept, T&>& other)
2481 : data(::boost::type_erasure::detail::access::data(other)),
2482 table(::boost::type_erasure::detail::access::table(other))
2483 {}
2484 /**
2485 * Constructs an @ref any from another @ref any.
2486 *
2487 * \param other The object to bind the reference to.
2488 *
2489 * \throws Nothing.
2490 */
2491 any(const any<Concept, T>& other)
2492 : data(::boost::type_erasure::detail::access::data(other)),
2493 table(::boost::type_erasure::detail::access::table(other))
2494 {}
2495#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2496 /**
2497 * Constructs an @ref any from another @ref any.
2498 *
2499 * \param other The object to bind the reference to.
2500 *
2501 * \throws Nothing.
2502 */
2503 any(const any<Concept, T&&>& other)
2504 : data(::boost::type_erasure::detail::access::data(other)),
2505 table(::boost::type_erasure::detail::access::table(other))
2506 {}
2507#endif
2508 /**
2509 * Constructs an @ref any from another @ref any.
2510 *
2511 * \param other The object to bind the reference to.
2512 *
2513 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2514 * \pre After substituting @c T for @c Tag2, the requirements of
2515 * @c Concept2 must be a superset of the requirements of
2516 * @c Concept.
2517 *
2518 * \throws std::bad_alloc
2519 */
2520 template<class Concept2, class Tag2>
2521 any(const any<Concept2, Tag2>& other
2522#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2523 , typename ::boost::disable_if< ::boost::is_same<Concept, Concept2> >::type* = 0
2524#endif
2525 )
2526 : data(::boost::type_erasure::detail::access::data(other)),
2527 table(
2528 ::boost::type_erasure::detail::access::table(other),
2529 ::boost::mpl::map1<
2530 ::boost::mpl::pair<
2531 T,
2532 typename ::boost::remove_const<
2533 typename ::boost::remove_reference<Tag2>::type
2534 >::type
2535 >
2536 >())
2537 {}
2538 /**
2539 * Constructs an @ref any from another @ref any.
2540 *
2541 * \param other The object to bind the reference to.
2542 * \param binding Specifies the mapping between the two concepts.
2543 *
2544 * \pre @c Map must be an MPL map with keys for all the non-deduced
2545 * placeholders used by @c Concept and values for the corresponding
2546 * placeholders in @c Concept2.
2547 * \pre After substituting placeholders according to @c Map, the
2548 * requirements of @c Concept2 must be a superset of the
2549 * requirements of @c Concept.
2550 *
2551 * \throws std::bad_alloc
2552 */
2553 template<class Concept2, class Tag2, class Map>
2554 any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
2555 : data(::boost::type_erasure::detail::access::data(other)),
2556 table(::boost::type_erasure::detail::access::table(other), binding_arg)
2557 {}
2558 /**
2559 * Constructs an @ref any from another @ref any.
2560 *
2561 * \param other The object to bind the reference to.
2562 * \param binding Specifies the bindings of placeholders to actual types.
2563 *
2564 * \pre The type stored in @c other must match the type expected by
2565 * @c binding.
2566 *
2567 * \post binding_of(*this) == @c binding
2568 *
2569 * \throws Nothing.
2570 */
2571 template<class Concept2, class Tag2>
2572 any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
2573 : data(::boost::type_erasure::detail::access::data(other)),
2574 table(binding_arg)
2575 {}
2576
2577
2578 /**
2579 * Assigns to an @ref any.
2580 *
2581 * \pre @ref relaxed is in @c Concept.
2582 *
2583 * \throws Nothing.
2584 */
2585 any& operator=(const any& other)
2586 {
2587 BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
2588 any temp(other);
2589 _boost_type_erasure_swap(other&: temp);
2590 return *this;
2591 }
2592 /**
2593 * Assigns to an @ref any.
2594 *
2595 * \pre @ref relaxed is in @c Concept.
2596 *
2597 * \throws std::bad_alloc. Provides the strong exception guarantee.
2598 */
2599 template<class U>
2600 any& operator=(const U& other)
2601 {
2602 BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
2603 any temp(other);
2604 _boost_type_erasure_swap(other&: temp);
2605 return *this;
2606 }
2607
2608#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
2609 /** INTERNAL ONLY */
2610 operator param<Concept, const T&>() const { return param<Concept, const T&>(data, table); }
2611#endif
2612private:
2613 /** INTERNAL ONLY */
2614 void _boost_type_erasure_swap(any& other)
2615 {
2616 ::std::swap(a&: data, b&: other.data);
2617 ::std::swap(table, other.table);
2618 }
2619 friend struct ::boost::type_erasure::detail::access;
2620 ::boost::type_erasure::detail::storage data;
2621 table_type table;
2622};
2623
2624#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2625
2626template<class Concept, class T>
2627class any<Concept, T&&> :
2628 public ::boost::type_erasure::detail::compute_bases<
2629 ::boost::type_erasure::any<Concept, T&&>,
2630 Concept,
2631 T
2632 >::type
2633{
2634 typedef ::boost::type_erasure::binding<Concept> table_type;
2635public:
2636 /** INTERNAL ONLY */
2637 typedef Concept _boost_type_erasure_concept_type;
2638 /** INTERNAL ONLY */
2639 any(const ::boost::type_erasure::detail::storage& data_arg,
2640 const table_type& table_arg)
2641 : data(data_arg),
2642 table(table_arg)
2643 {}
2644 /**
2645 * Constructs an @ref any from a reference.
2646 *
2647 * \param arg The object to bind the reference to.
2648 *
2649 * \pre @c U is a model of @c Concept.
2650 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2651 *
2652 * \throws Nothing.
2653 */
2654 template<class U>
2655 any(U&& arg
2656#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2657 , typename ::boost::disable_if<
2658 ::boost::mpl::or_<
2659 ::boost::is_reference<U>,
2660 ::boost::is_const<U>,
2661 ::boost::type_erasure::detail::is_any<U>
2662 >
2663 >::type* = 0
2664#endif
2665 )
2666 : table((
2667 BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
2668 ::boost::type_erasure::make_binding<
2669 ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
2670 >()
2671 ))
2672 {
2673 data.data = ::boost::addressof(arg);
2674 }
2675 /**
2676 * Constructs an @ref any from a reference.
2677 *
2678 * \param arg The object to bind the reference to.
2679 * \param binding Specifies the actual types that
2680 * all the placeholders should bind to.
2681 *
2682 * \pre @c U is a model of @c Concept.
2683 * \pre @c Map is an MPL map with an entry for every
2684 * non-deduced placeholder referred to by @c Concept.
2685 *
2686 * \throws Nothing.
2687 */
2688 template<class U, class Map>
2689 any(U&& arg, const static_binding<Map>& binding_arg)
2690 : table((
2691 BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
2692 binding_arg
2693 ))
2694 {
2695 BOOST_MPL_ASSERT((::boost::is_same<
2696 typename ::boost::mpl::at<Map, T>::type, U>));
2697 data.data = ::boost::addressof(arg);
2698 }
2699 /**
2700 * Constructs an @ref any from another rvalue reference.
2701 *
2702 * \param other The reference to copy.
2703 *
2704 * \throws Nothing.
2705 */
2706#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2707 any(any&& other)
2708 : data(other.data),
2709 table(std::move(other.table))
2710 {}
2711 any(const any& other)
2712 : data(other.data),
2713 table(other.table)
2714 {}
2715#endif
2716 /**
2717 * Constructs an @ref any from another @ref any.
2718 *
2719 * \param other The object to bind the reference to.
2720 *
2721 * \throws Nothing.
2722 */
2723 any(any<Concept, T>&& other)
2724 : data(::boost::type_erasure::detail::access::data(other)),
2725 table(std::move(::boost::type_erasure::detail::access::table(other)))
2726 {}
2727 /**
2728 * Constructs an @ref any from another rvalue reference.
2729 *
2730 * \param other The reference to copy.
2731 *
2732 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2733 * \pre After substituting @c T for @c Tag2, the requirements of
2734 * @c Concept2 must be a superset of the requirements of
2735 * @c Concept.
2736 *
2737 * \throws std::bad_alloc
2738 */
2739 template<class Concept2, class Tag2>
2740 any(any<Concept2, Tag2&&>&& other
2741#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2742 , typename ::boost::disable_if<
2743 ::boost::mpl::or_<
2744 ::boost::is_reference<Tag2>,
2745 ::boost::is_same<Concept, Concept2>,
2746 ::boost::is_const<Tag2>
2747 >
2748 >::type* = 0
2749#endif
2750 )
2751 : data(::boost::type_erasure::detail::access::data(other)),
2752 table(
2753 std::move(::boost::type_erasure::detail::access::table(other)),
2754 ::boost::mpl::map1<
2755 ::boost::mpl::pair<
2756 T,
2757 Tag2
2758 >
2759 >())
2760 {}
2761 /**
2762 * Constructs an @ref any from another @ref any.
2763 *
2764 * \param other The object to bind the reference to.
2765 *
2766 * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
2767 * \pre After substituting @c T for @c Tag2, the requirements of
2768 * @c Concept2 must be a superset of the requirements of
2769 * @c Concept.
2770 *
2771 * \throws std::bad_alloc
2772 */
2773 template<class Concept2, class Tag2>
2774 any(any<Concept2, Tag2>&& other
2775#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2776 , typename ::boost::disable_if<
2777 ::boost::mpl::or_<
2778 ::boost::is_same<Concept, Concept2>,
2779 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2780 >
2781 >::type* = 0
2782#endif
2783 )
2784 : data(::boost::type_erasure::detail::access::data(other)),
2785 table(
2786 std::move(::boost::type_erasure::detail::access::table(other)),
2787 ::boost::mpl::map1<
2788 ::boost::mpl::pair<
2789 T,
2790 typename ::boost::remove_reference<Tag2>::type
2791 >
2792 >())
2793 {}
2794 /**
2795 * Constructs an @ref any from another reference.
2796 *
2797 * \param other The reference to copy.
2798 * \param binding Specifies the mapping between the two concepts.
2799 *
2800 * \pre @c Map must be an MPL map with keys for all the non-deduced
2801 * placeholders used by @c Concept and values for the corresponding
2802 * placeholders in @c Concept2.
2803 * \pre After substituting placeholders according to @c Map, the
2804 * requirements of @c Concept2 must be a superset of the
2805 * requirements of @c Concept.
2806 *
2807 * \throws std::bad_alloc
2808 */
2809 template<class Concept2, class Tag2, class Map>
2810 any(const any<Concept2, Tag2&&>& other, const static_binding<Map>& binding_arg
2811#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2812 , typename ::boost::disable_if< ::boost::is_const<Tag2> >::type* = 0
2813#endif
2814 )
2815 : data(::boost::type_erasure::detail::access::data(other)),
2816 table(std::move(::boost::type_erasure::detail::access::table(other)), binding_arg)
2817 {}
2818 /**
2819 * Constructs an @ref any from another @ref any.
2820 *
2821 * \param other The object to bind the reference to.
2822 * \param binding Specifies the mapping between the two concepts.
2823 *
2824 * \pre @c Map must be an MPL map with keys for all the non-deduced
2825 * placeholders used by @c Concept and values for the corresponding
2826 * placeholders in @c Concept2.
2827 * \pre After substituting placeholders according to @c Map, the
2828 * requirements of @c Concept2 must be a superset of the
2829 * requirements of @c Concept.
2830 *
2831 * \throws std::bad_alloc
2832 */
2833 template<class Concept2, class Tag2, class Map>
2834 any(any<Concept2, Tag2>&& other, const static_binding<Map>& binding_arg
2835#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2836 , typename ::boost::disable_if<
2837 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2838 >::type* = 0
2839#endif
2840 )
2841 : data(::boost::type_erasure::detail::access::data(other)),
2842 table(::boost::type_erasure::detail::access::table(other), binding_arg)
2843 {}
2844 /**
2845 * Constructs an @ref any from another rvalue reference.
2846 *
2847 * \param other The reference to copy.
2848 * \param binding Specifies the bindings of placeholders to actual types.
2849 *
2850 * \pre The type stored in @c other must match the type expected by
2851 * @c binding.
2852 *
2853 * \post binding_of(*this) == @c binding
2854 *
2855 * \throws Nothing.
2856 */
2857 template<class Concept2, class Tag2>
2858 any(const any<Concept2, Tag2&&>& other, const binding<Concept>& binding_arg
2859#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2860 , typename ::boost::disable_if<
2861 ::boost::is_const<Tag2>
2862 >::type* = 0
2863#endif
2864 )
2865 : data(::boost::type_erasure::detail::access::data(other)),
2866 table(binding_arg)
2867 {}
2868 /**
2869 * Constructs an @ref any from another @ref any.
2870 *
2871 * \param other The object to bind the reference to.
2872 * \param binding Specifies the bindings of placeholders to actual types.
2873 *
2874 * \pre The type stored in @c other must match the type expected by
2875 * @c binding.
2876 *
2877 * \post binding_of(*this) == @c binding
2878 *
2879 * \throws Nothing.
2880 */
2881 template<class Concept2, class Tag2>
2882 any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg
2883#ifndef BOOST_TYPE_ERASURE_DOXYGEN
2884 , typename ::boost::disable_if<
2885 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2886 >::type* = 0
2887#endif
2888 )
2889 : data(::boost::type_erasure::detail::access::data(other)),
2890 table(binding_arg)
2891 {}
2892
2893 /** INTERNAL ONLY */
2894 any& operator=(const any& other)
2895 {
2896 _boost_type_erasure_resolve_assign(other);
2897 return *this;
2898 }
2899
2900 /**
2901 * Assigns to an @ref any.
2902 *
2903 * If an appropriate overload of @ref assignable is not available
2904 * and @ref relaxed is in @c Concept, falls back on
2905 * constructing from @c other.
2906 *
2907 * \throws Whatever the assignment operator of the contained
2908 * type throws. When falling back on construction,
2909 * can only throw @c std::bad_alloc if @c U is an @ref any
2910 * that uses a different @c Concept. In this case assignment
2911 * provides the strong exception guarantee. When
2912 * calling the assignment operator of the contained type,
2913 * the exception guarantee is whatever the contained type provides.
2914 */
2915 template<class U>
2916 any& operator=(U&& other)
2917 {
2918 _boost_type_erasure_resolve_assign(std::forward<U>(other));
2919 return *this;
2920 }
2921
2922#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
2923 /** INTERNAL ONLY */
2924 operator param<Concept, T&&>() const { return param<Concept, T&&>(data, table); }
2925#endif
2926private:
2927
2928 /** INTERNAL ONLY */
2929 void _boost_type_erasure_swap(any& other)
2930 {
2931 ::std::swap(a&: data, b&: other.data);
2932 ::std::swap(table, other.table);
2933 }
2934 /** INTERNAL ONLY */
2935 template<class Other>
2936 void _boost_type_erasure_resolve_assign(Other&& other)
2937 {
2938 _boost_type_erasure_assign_impl(
2939 std::forward<Other>(other),
2940 false? this->_boost_type_erasure_deduce_assign(
2941 ::boost::type_erasure::detail::make_fallback(
2942 std::forward<Other>(other),
2943 ::boost::mpl::bool_<
2944 sizeof(
2945 ::boost::type_erasure::detail::check_overload(
2946 ::boost::declval<any&>().
2947 _boost_type_erasure_deduce_assign(std::forward<Other>(other))
2948 )
2949 ) == sizeof(::boost::type_erasure::detail::yes)
2950 >()
2951 )
2952 ) : 0,
2953 ::boost::mpl::and_<
2954 ::boost::type_erasure::is_relaxed<Concept>,
2955 ::boost::is_convertible<Other, any>
2956 >()
2957 );
2958 }
2959 /** INTERNAL ONLY */
2960 template<class Other, class U>
2961 void _boost_type_erasure_assign_impl(
2962 Other&& other,
2963 const assignable<T, U>*,
2964 ::boost::mpl::false_)
2965 {
2966 ::boost::type_erasure::call(
2967 assignable<T, U>(),
2968 // lose rvalueness of this
2969 ::boost::type_erasure::param<Concept, T&>(data, table),
2970 std::forward<Other>(other));
2971 }
2972 /** INTERNAL ONLY */
2973 template<class Other, class U>
2974 void _boost_type_erasure_assign_impl(
2975 Other&& other,
2976 const assignable<T, U>*,
2977 ::boost::mpl::true_)
2978 {
2979 if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) {
2980 ::boost::type_erasure::unchecked_call(
2981 assignable<T, U>(),
2982 // lose rvalueness of this
2983 ::boost::type_erasure::param<Concept, T&>(data, table),
2984 std::forward<Other>(other));
2985 } else {
2986 any temp(std::forward<Other>(other));
2987 _boost_type_erasure_swap(other&: temp);
2988 }
2989 }
2990 /** INTERNAL ONLY */
2991 template<class Other>
2992 void _boost_type_erasure_assign_impl(
2993 Other&& other,
2994 const void*,
2995 ::boost::mpl::true_)
2996 {
2997 any temp(std::forward<Other>(other));
2998 _boost_type_erasure_swap(other&: temp);
2999 }
3000
3001 friend struct ::boost::type_erasure::detail::access;
3002 ::boost::type_erasure::detail::storage data;
3003 table_type table;
3004};
3005
3006#endif
3007
3008#ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
3009template<class Concept, class T>
3010using any_ref = any<Concept, T&>;
3011template<class Concept, class T>
3012using any_cref = any<Concept, const T&>;
3013#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
3014template<class Concept, class T>
3015using any_rvref = any<Concept, T&&>;
3016#endif
3017#endif
3018
3019}
3020}
3021
3022#endif
3023

source code of boost/libs/type_erasure/include/boost/type_erasure/any.hpp