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 #include <boost/config.hpp>
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/utility/addressof.hpp>
18 #include <boost/utility/declval.hpp>
19 #include <boost/mpl/bool.hpp>
20 #include <boost/mpl/or.hpp>
21 #include <boost/mpl/pair.hpp>
22 #include <boost/mpl/map.hpp>
23 #include <boost/mpl/fold.hpp>
24 #include <boost/type_traits/remove_reference.hpp>
25 #include <boost/type_traits/remove_const.hpp>
26 #include <boost/type_traits/is_same.hpp>
27 #include <boost/type_traits/is_const.hpp>
28 #include <boost/preprocessor/cat.hpp>
29 #include <boost/preprocessor/iteration/iterate.hpp>
30 #include <boost/preprocessor/repetition/enum_params.hpp>
31 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
32 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
33 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
34 #include <boost/type_erasure/detail/access.hpp>
35 #include <boost/type_erasure/detail/any_base.hpp>
36 #include <boost/type_erasure/detail/normalize.hpp>
37 #include <boost/type_erasure/detail/storage.hpp>
38 #include <boost/type_erasure/detail/instantiate.hpp>
39 #include <boost/type_erasure/config.hpp>
40 #include <boost/type_erasure/binding.hpp>
41 #include <boost/type_erasure/static_binding.hpp>
42 #include <boost/type_erasure/concept_interface.hpp>
43 #include <boost/type_erasure/call.hpp>
44 #include <boost/type_erasure/relaxed.hpp>
45 #include <boost/type_erasure/param.hpp>
46 
47 namespace boost {
48 namespace type_erasure {
49 
50 template<class Sig>
51 struct constructible;
52 
53 template<class T>
54 struct destructible;
55 
56 template<class T, class U>
57 struct assignable;
58 
59 namespace detail {
60 
61 template<class Derived, class Concept, class T>
62 struct compute_bases
63 {
64     typedef typename ::boost::mpl::fold<
65         typename ::boost::type_erasure::detail::collect_concepts<
66             Concept
67         >::type,
68         ::boost::type_erasure::any_base<Derived>,
69         ::boost::type_erasure::concept_interface<
70             ::boost::mpl::_2,
71             ::boost::mpl::_1,
72             T
73         >
74     >::type type;
75 };
76 
77 template<class T>
make(T *)78 T make(T*) { return T(); }
79 
80 // This dance is necessary to avoid errors calling
81 // an ellipsis function with a non-trivially-copyable
82 // argument.
83 
84 typedef char no;
85 struct yes { no dummy[2]; };
86 
87 template<class Op>
88 yes check_overload(const Op*);
89 no check_overload(const void*);
90 
91 struct fallback {};
92 
93 template<class T>
make_fallback(const T &,boost::mpl::false_)94 fallback make_fallback(const T&, boost::mpl::false_)
95 {
96     return fallback();
97 }
98 
99 template<class T>
make_fallback(const T & arg,boost::mpl::true_)100 const T& make_fallback(const T& arg, boost::mpl::true_)
101 {
102     return arg;
103 }
104 
105 template<class T>
106 struct is_any : ::boost::mpl::false_ {};
107 
108 template<class Concept, class T>
109 struct is_any<any<Concept, T> > : ::boost::mpl::true_ {};
110 
111 }
112 
113 #ifdef BOOST_MSVC
114 #pragma warning(push)
115 #pragma warning(disable:4355)
116 #pragma warning(disable:4521)
117 #endif
118 
119 /**
120  * The class template @ref any can store any object that
121  * models a specific \Concept.  It dispatches all
122  * the functions defined by the \Concept to the contained type
123  * at runtime.
124  *
125  * \tparam Concept The \Concept that the stored type should model.
126  * \tparam T A @ref placeholder specifying which type this is.
127  *
128  * \see concept_of, placeholder_of, \any_cast, \is_empty, \binding_of, \typeid_of
129  */
130 template<class Concept, class T = _self>
131 class any :
132     public ::boost::type_erasure::detail::compute_bases<
133         ::boost::type_erasure::any<Concept, T>,
134         Concept,
135         T
136     >::type
137 {
138     typedef ::boost::type_erasure::binding<Concept> table_type;
139 public:
140     /** INTERNAL ONLY */
141     typedef Concept _boost_type_erasure_concept_type;
142     /** INTERNAL ONLY */
any(const::boost::type_erasure::detail::storage & data_arg,const table_type & table_arg)143     any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg)
144       : table(table_arg),
145         data(data_arg)
146     {}
147 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
148     /** INTERNAL ONLY */
any(::boost::type_erasure::detail::storage && data_arg,const table_type & table_arg)149     any(::boost::type_erasure::detail::storage&& data_arg, const table_type& table_arg)
150       : table(table_arg),
151         data(data_arg)
152     {}
153 #endif
154     /**
155      * Constructs an empty @ref any.
156      *
157      * Except as otherwise noted, all operations on an
158      * empty @ref any result in a @ref bad_function_call exception.
159      * The copy-constructor of an empty @ref any creates another
160      * null @ref any.  The destructor of an empty @ref any is a no-op.
161      * Comparison operators treat all empty @ref any "anys" as equal.
162      * \typeid_of applied to an empty @ref any returns @c typeid(void).
163      *
164      * An @ref any which does not include @ref relaxed in its
165      * \Concept can never be null.
166      *
167      * \pre @ref relaxed must be in @c Concept.
168      *
169      * \throws Nothing.
170      *
171      * @see \is_empty
172      */
any()173     any()
174     {
175         BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
176         data.data = 0;
177     }
178 
179 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
180 
181     template<class U>
any(const U & data_arg)182     any(const U& data_arg)
183       : table((
184             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
185             ::boost::type_erasure::make_binding<
186                 ::boost::mpl::map< ::boost::mpl::pair<T, U> >
187             >()
188         )),
189         data(data_arg)
190     {}
191     template<class U, class Map>
any(const U & data_arg,const static_binding<Map> & binding_arg)192     any(const U& data_arg, const static_binding<Map>& binding_arg)
193       : table((
194             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
195             binding_arg
196         )),
197         data(data_arg)
198     {
199         BOOST_MPL_ASSERT((::boost::is_same<
200             typename ::boost::mpl::at<Map, T>::type, U>));
201     }
202 
203 #else
204 
205     /**
206      * Constructs an @ref any to hold a copy of @c data.
207      * The @c Concept will be instantiated with the
208      * placeholder @c T bound to U.
209      *
210      * \param data The object to store in the @ref any.
211      *
212      * \pre @c U is a model of @c Concept.
213      * \pre @c U must be \CopyConstructible.
214      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
215      *
216      * \throws std::bad_alloc or whatever that the copy
217      *         constructor of @c U throws.
218      *
219      * \note This constructor never matches if the argument is
220      *       an @ref any, @ref binding, or @ref static_binding.
221      */
222     template<class U>
any(U && data_arg)223     any(U&& data_arg)
224       : table((
225             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type),
226             ::boost::type_erasure::make_binding<
227                 ::boost::mpl::map< ::boost::mpl::pair<T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type> >
228             >()
229         )),
230         data(std::forward<U>(data_arg))
231     {}
232     /**
233      * Constructs an @ref any to hold a copy of @c data
234      * with explicitly specified placeholder bindings.
235      *
236      * \param data The object to store in the @ref any.
237      * \param binding Specifies the types that
238      *        all the placeholders should bind to.
239      *
240      * \pre @c U is a model of @c Concept.
241      * \pre @c U must be \CopyConstructible.
242      * \pre @c Map is an MPL map with an entry for every
243      *         non-deduced placeholder referred to by @c Concept.
244      * \pre @c @c T must map to @c U in @c Map.
245      *
246      * \throws std::bad_alloc or whatever that the copy
247      *         constructor of @c U throws.
248      *
249      * \note This constructor never matches if the argument is an @ref any.
250      */
251     template<class U, class Map>
any(U && data_arg,const static_binding<Map> & binding_arg)252     any(U&& data_arg, const static_binding<Map>& binding_arg)
253       : table((
254             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
255             binding_arg
256         )),
257         data(std::forward<U>(data_arg))
258     {
259         BOOST_MPL_ASSERT((::boost::is_same<
260             typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
261     }
262 
263 #endif
264 
265     // Handle array/function-to-pointer decay
266     /** INTERNAL ONLY */
267     template<class U>
any(U * data_arg)268     any(U* data_arg)
269       : table((
270             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U*),
271             ::boost::type_erasure::make_binding<
272                 ::boost::mpl::map< ::boost::mpl::pair<T, U*> >
273             >()
274         )),
275         data(data_arg)
276     {}
277     /** INTERNAL ONLY */
278     template<class U, class Map>
any(U * data_arg,const static_binding<Map> & binding_arg)279     any(U* data_arg, const static_binding<Map>& binding_arg)
280       : table((
281             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
282             binding_arg
283         )),
284         data(data_arg)
285     {
286         BOOST_MPL_ASSERT((::boost::is_same<
287             typename ::boost::mpl::at<Map, T>::type, U*>));
288     }
289     /**
290      * Copies an @ref any.
291      *
292      * \param other The object to make a copy of.
293      *
294      * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>".
295      *     (This is included in @ref copy_constructible "copy_constructible<T>")
296      *
297      * \throws std::bad_alloc or whatever that the copy
298      *         constructor of the contained type throws.
299      */
any(const any & other)300     any(const any& other)
301       : table(other.table),
302         data(::boost::type_erasure::call(constructible<T(const T&)>(), other))
303     {}
304     /**
305      * Upcasts from an @ref any with stricter requirements to
306      * an @ref any with weaker requirements.
307      *
308      * \param other The object to make a copy of.
309      *
310      * \pre @c Concept must contain @ref constructible<T(const T&)>.
311      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
312      * \pre After substituting @c T for @c Tag2, the requirements of
313      *      @c Concept2 must be a superset of the requirements of
314      *      @c Concept.
315      *
316      * \throws std::bad_alloc or whatever that the copy
317      *         constructor of the contained type throws.
318      */
319     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other)320     any(const any<Concept2, Tag2>& other)
321       : table(
322             ::boost::type_erasure::detail::access::table(other),
323             ::boost::mpl::map<
324                 ::boost::mpl::pair<
325                     T,
326                     typename ::boost::remove_const<
327                         typename ::boost::remove_reference<Tag2>::type
328                     >::type
329                 >
330             >()
331         ),
332         data(::boost::type_erasure::call(
333             constructible<
334                 typename ::boost::remove_const<
335                     typename boost::remove_reference<Tag2>::type
336                 >::type(const typename boost::remove_reference<Tag2>::type&)
337             >(), other)
338         )
339     {}
340     /**
341      * Constructs an @ref any from another @ref any.
342      *
343      * \param other The object to make a copy of.
344      * \param binding Specifies the mapping between the placeholders
345      *        used by the two concepts.
346      *
347      * \pre @c Concept must contain @ref constructible<T(const T&)>.
348      * \pre @c Map must be an MPL map with keys for all the non-deduced
349      *      placeholders used by @c Concept and values for the corresponding
350      *      placeholders in @c Concept2.
351      * \pre After substituting placeholders according to @c Map, the
352      *      requirements of @c Concept2 must be a superset of the
353      *      requirements of @c Concept.
354      *
355      * \throws std::bad_alloc or whatever that the copy
356      *         constructor of the contained type throws.
357      */
358     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2> & other,const static_binding<Map> & binding_arg)359     any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
360       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
361         data(::boost::type_erasure::call(
362             constructible<
363                 typename ::boost::remove_const<
364                     typename boost::remove_reference<Tag2>::type
365                 >::type(const typename boost::remove_reference<Tag2>::type&)
366             >(), other)
367         )
368     {}
369     /**
370      * Constructs an @ref any from another @ref any.
371      *
372      * \param other The object to make a copy of.
373      * \param binding Specifies the bindings of placeholders to actual types.
374      *
375      * \pre @c Concept must contain @ref constructible<T(const T&)>.
376      * \pre The type stored in @c other must match the type expected by
377      *      @c binding.
378      *
379      * \post binding_of(*this) == @c binding
380      *
381      * \throws std::bad_alloc or whatever that the copy
382      *         constructor of the contained type throws.
383      *
384      * \warning This constructor is potentially dangerous, as it cannot
385      *          check at compile time whether the arguments match.
386      */
387     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other,const binding<Concept> & binding_arg)388     any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
389       : table(binding_arg),
390         data(::boost::type_erasure::call(
391             constructible<
392                 typename ::boost::remove_const<
393                     typename boost::remove_reference<Tag2>::type
394                 >::type(const typename boost::remove_reference<Tag2>::type&)
395             >(), other)
396         )
397     {}
398 
399 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
400 
401     /**
402      * Calls a constructor of the contained type.  The bindings
403      * will be deduced from the arguments.
404      *
405      * \param arg The arguments to be passed to the underlying constructor.
406      *
407      * \pre @c Concept must contain an instance of @ref constructible which
408      *      can be called with these arguments.
409      * \pre At least one of the arguments must by an @ref any with the
410      *      same @c Concept as this.
411      * \pre The bindings of all the arguments that are @ref any's, must
412      *      be the same.
413      *
414      * \throws std::bad_alloc or whatever that the
415      *         constructor of the contained type throws.
416      *
417      * \note This constructor is never chosen if any other constructor
418      *       can be called instead.
419      */
420     template<class... U>
421     explicit any(U&&... arg);
422 
423     /**
424      * Calls a constructor of the contained type.
425      *
426      * \param binding Specifies the bindings of placeholders to actual types.
427      * \param arg The arguments to be passed to the underlying constructor.
428      *
429      * \pre @c Concept must contain a matching instance of @ref constructible.
430      * \pre The contained type of every argument that is an @ref any, must
431      *      be the same as that specified by @c binding.
432      *
433      * \post binding_of(*this) == @c binding
434      *
435      * \throws std::bad_alloc or whatever that the
436      *         constructor of the contained type throws.
437      */
438     template<class... U>
any(const binding<Concept> & binding_arg,U &&...arg)439     explicit any(const binding<Concept>& binding_arg, U&&... arg)
440       : table(binding_arg),
441         data(
442             ::boost::type_erasure::detail::make(
443                 false? this->_boost_type_erasure_deduce_constructor(arg...) : 0
444             )(arg...)
445         )
446     {}
447 
448 #else
449 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
any(any && other)450     any(any&& other)
451       : table(::boost::type_erasure::detail::access::table(other)),
452         data(::boost::type_erasure::call(
453             ::boost::type_erasure::detail::make(
454                 false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0
455             ), std::move(other))
456         )
457     {}
any(any & other)458     any(any& other)
459       : table(::boost::type_erasure::detail::access::table(other)),
460         data(::boost::type_erasure::call(
461             ::boost::type_erasure::detail::make(
462                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
463             ), other)
464         )
465     {}
466     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other)467     any(any<Concept2, Tag2>& other)
468       : table(
469             ::boost::type_erasure::detail::access::table(other),
470             ::boost::mpl::map<
471                 ::boost::mpl::pair<
472                     T,
473                     typename ::boost::remove_const<
474                         typename ::boost::remove_reference<Tag2>::type
475                     >::type
476                 >
477             >()
478         ),
479         data(::boost::type_erasure::call(
480             ::boost::type_erasure::detail::make(
481                 false? other._boost_type_erasure_deduce_constructor(other) : 0
482             ), other)
483         )
484     {}
485     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other)486     any(any<Concept2, Tag2>&& other)
487       : table(
488             ::boost::type_erasure::detail::access::table(other),
489             ::boost::mpl::map<
490                 ::boost::mpl::pair<
491                     T,
492                     typename ::boost::remove_const<
493                         typename ::boost::remove_reference<Tag2>::type
494                     >::type
495                 >
496             >()
497         ),
498         data(::boost::type_erasure::call(
499             ::boost::type_erasure::detail::make(
500                 false? other._boost_type_erasure_deduce_constructor(std::move(other)) : 0
501             ), std::move(other))
502         )
503     {}
504 #endif
505     // construction from a reference
any(const any<Concept,T &> & other)506     any(const any<Concept, T&>& other)
507       : table(::boost::type_erasure::detail::access::table(other)),
508         data(::boost::type_erasure::call(
509             ::boost::type_erasure::detail::make(
510                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
511             ), other)
512         )
513     {}
any(any<Concept,T &> & other)514     any(any<Concept, T&>& other)
515       : table(::boost::type_erasure::detail::access::table(other)),
516         data(::boost::type_erasure::call(
517             ::boost::type_erasure::detail::make(
518                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
519             ), other)
520         )
521     {}
522 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
any(any<Concept,T &> && other)523     any(any<Concept, T&>&& other)
524       : table(::boost::type_erasure::detail::access::table(other)),
525         data(::boost::type_erasure::call(
526             ::boost::type_erasure::detail::make(
527                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
528             ), other)
529         )
530     {}
531 #endif
any(const any<Concept,const T &> & other)532     any(const any<Concept, const T&>& other)
533       : table(::boost::type_erasure::detail::access::table(other)),
534         data(::boost::type_erasure::call(
535             ::boost::type_erasure::detail::make(
536                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
537             ), other)
538         )
539     {}
any(any<Concept,const T &> & other)540     any(any<Concept, const T&>& other)
541       : table(::boost::type_erasure::detail::access::table(other)),
542         data(::boost::type_erasure::call(
543             ::boost::type_erasure::detail::make(
544                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
545             ), other)
546         )
547     {}
548 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
any(any<Concept,const T &> && other)549     any(any<Concept, const T&>&& other)
550       : table(::boost::type_erasure::detail::access::table(other)),
551         data(::boost::type_erasure::call(
552             ::boost::type_erasure::detail::make(
553                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
554             ), other)
555         )
556     {}
557 #endif
558 
559     // disambiguating overloads
560     template<class U, class Map>
any(U * data_arg,static_binding<Map> & binding_arg)561     any(U* data_arg, static_binding<Map>& binding_arg)
562       : table((
563             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
564             binding_arg
565         )),
566         data(data_arg)
567     {
568         BOOST_MPL_ASSERT((::boost::is_same<
569             typename ::boost::mpl::at<Map, T>::type, U*>));
570     }
571 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
572     template<class U, class Map>
any(U & data_arg,static_binding<Map> & binding_arg)573     any(U& data_arg, static_binding<Map>& binding_arg)
574       : table((
575             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
576             binding_arg
577         )),
578         data(data_arg)
579     {
580         BOOST_MPL_ASSERT((::boost::is_same<
581             typename ::boost::mpl::at<Map, T>::type, U>));
582     }
583     template<class U, class Map>
any(const U & data_arg,static_binding<Map> & binding_arg)584     any(const U& data_arg, static_binding<Map>& binding_arg)
585       : table((
586             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
587             binding_arg
588         )),
589         data(data_arg)
590     {
591         BOOST_MPL_ASSERT((::boost::is_same<
592             typename ::boost::mpl::at<Map, T>::type, U>));
593     }
594     template<class U, class Map>
any(U & data_arg,const static_binding<Map> & binding_arg)595     any(U& data_arg, const static_binding<Map>& binding_arg)
596       : table((
597             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
598             binding_arg
599         )),
600         data(data_arg)
601     {
602         BOOST_MPL_ASSERT((::boost::is_same<
603             typename ::boost::mpl::at<Map, T>::type, U>));
604     }
605 #endif
606 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
607     template<class U, class Map>
any(U * data_arg,static_binding<Map> && binding_arg)608     any(U* data_arg, static_binding<Map>&& binding_arg)
609       : table((
610             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
611             binding_arg
612         )),
613         data(data_arg)
614     {
615         BOOST_MPL_ASSERT((::boost::is_same<
616             typename ::boost::mpl::at<Map, T>::type, U*>));
617     }
618     template<class U, class Map>
any(U && data_arg,static_binding<Map> & binding_arg)619     any(U&& data_arg, static_binding<Map>& binding_arg)
620       : table((
621             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
622             binding_arg
623         )),
624         data(data_arg)
625     {
626         BOOST_MPL_ASSERT((::boost::is_same<
627             typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
628     }
629     template<class U, class Map>
any(U && data_arg,static_binding<Map> && binding_arg)630     any(U&& data_arg, static_binding<Map>&& binding_arg)
631       : table((
632             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
633             binding_arg
634         )),
635         data(data_arg)
636     {
637         BOOST_MPL_ASSERT((::boost::is_same<
638             typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>));
639     }
640 #endif
641     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> & other,static_binding<Map> & binding_arg)642     any(any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
643       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
644         data(::boost::type_erasure::call(
645             constructible<
646                 typename ::boost::remove_const<
647                     typename boost::remove_reference<Tag2>::type
648                 >::type(const typename boost::remove_reference<Tag2>::type&)
649             >(), other)
650         )
651     {}
652     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> & other,const static_binding<Map> & binding_arg)653     any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
654       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
655         data(::boost::type_erasure::call(
656             constructible<
657                 typename ::boost::remove_const<
658                     typename boost::remove_reference<Tag2>::type
659                 >::type(const typename boost::remove_reference<Tag2>::type&)
660             >(), other)
661         )
662     {}
663     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2> & other,static_binding<Map> & binding_arg)664     any(const any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
665       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
666         data(::boost::type_erasure::call(
667             constructible<
668                 typename ::boost::remove_const<
669                     typename boost::remove_reference<Tag2>::type
670                 >::type(const typename boost::remove_reference<Tag2>::type&)
671             >(), other)
672         )
673     {}
674     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other,binding<Concept> & binding_arg)675     any(any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
676       : table(binding_arg),
677         data(::boost::type_erasure::call(
678             constructible<
679                 typename ::boost::remove_const<
680                     typename boost::remove_reference<Tag2>::type
681                 >::type(const typename boost::remove_reference<Tag2>::type&)
682             >(), other)
683         )
684     {}
685     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other,const binding<Concept> & binding_arg)686     any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
687       : table(binding_arg),
688         data(::boost::type_erasure::call(
689             constructible<
690                 typename ::boost::remove_const<
691                     typename boost::remove_reference<Tag2>::type
692                 >::type(const typename boost::remove_reference<Tag2>::type&)
693             >(), other)
694         )
695     {}
696     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other,binding<Concept> & binding_arg)697     any(const any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
698       : table(binding_arg),
699         data(::boost::type_erasure::call(
700             constructible<
701                 typename ::boost::remove_const<
702                     typename boost::remove_reference<Tag2>::type
703                 >::type(const typename boost::remove_reference<Tag2>::type&)
704             >(), other)
705         )
706     {}
707 
708 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
709     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> & other,static_binding<Map> && binding_arg)710     any(any<Concept2, Tag2>& other, static_binding<Map>&& binding_arg)
711       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
712         data(::boost::type_erasure::call(
713             constructible<
714                 typename ::boost::remove_const<
715                     typename boost::remove_reference<Tag2>::type
716                 >::type(const typename boost::remove_reference<Tag2>::type&)
717             >(), other)
718         )
719     {}
720     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2> & other,static_binding<Map> && binding_arg)721     any(const any<Concept2, Tag2>& other, static_binding<Map>&& binding_arg)
722       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
723         data(::boost::type_erasure::call(
724             constructible<
725                 typename ::boost::remove_const<
726                     typename boost::remove_reference<Tag2>::type
727                 >::type(const typename boost::remove_reference<Tag2>::type&)
728             >(), other)
729         )
730     {}
731     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> && other,static_binding<Map> && binding_arg)732     any(any<Concept2, Tag2>&& other, static_binding<Map>&& binding_arg)
733       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
734         data(::boost::type_erasure::call(
735             constructible<
736                 typename ::boost::remove_const<
737                     typename boost::remove_reference<Tag2>::type
738                 >::type(const typename boost::remove_reference<Tag2>::type&)
739             >(), std::move(other))
740         )
741     {}
742     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> && other,static_binding<Map> & binding_arg)743     any(any<Concept2, Tag2>&& other, static_binding<Map>& binding_arg)
744       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
745         data(::boost::type_erasure::call(
746             constructible<
747                 typename ::boost::remove_const<
748                     typename boost::remove_reference<Tag2>::type
749                 >::type(const typename boost::remove_reference<Tag2>::type&)
750             >(), std::move(other))
751         )
752     {}
753     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> && other,const static_binding<Map> & binding_arg)754     any(any<Concept2, Tag2>&& other, const static_binding<Map>& binding_arg)
755       : table(::boost::type_erasure::detail::access::table(other), binding_arg),
756         data(::boost::type_erasure::call(
757             constructible<
758                 typename ::boost::remove_const<
759                     typename boost::remove_reference<Tag2>::type
760                 >::type(const typename boost::remove_reference<Tag2>::type&)
761             >(), std::move(other))
762         )
763     {}
764     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other,binding<Concept> && binding_arg)765     any(any<Concept2, Tag2>& other, binding<Concept>&& binding_arg)
766       : table(binding_arg),
767         data(::boost::type_erasure::call(
768             constructible<
769                 typename ::boost::remove_const<
770                     typename boost::remove_reference<Tag2>::type
771                 >::type(const typename boost::remove_reference<Tag2>::type&)
772             >(), other)
773         )
774     {}
775     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other,binding<Concept> && binding_arg)776     any(const any<Concept2, Tag2>& other, binding<Concept>&& binding_arg)
777       : table(binding_arg),
778         data(::boost::type_erasure::call(
779             constructible<
780                 typename ::boost::remove_const<
781                     typename boost::remove_reference<Tag2>::type
782                 >::type(const typename boost::remove_reference<Tag2>::type&)
783             >(), other)
784         )
785     {}
786     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other,binding<Concept> && binding_arg)787     any(any<Concept2, Tag2>&& other, binding<Concept>&& binding_arg)
788       : table(binding_arg),
789         data(::boost::type_erasure::call(
790             constructible<
791                 typename ::boost::remove_const<
792                     typename boost::remove_reference<Tag2>::type
793                 >::type(const typename boost::remove_reference<Tag2>::type&)
794             >(), std::move(other))
795         )
796     {}
797     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other,binding<Concept> & binding_arg)798     any(any<Concept2, Tag2>&& other, binding<Concept>& binding_arg)
799       : table(binding_arg),
800         data(::boost::type_erasure::call(
801             constructible<
802                 typename ::boost::remove_const<
803                     typename boost::remove_reference<Tag2>::type
804                 >::type(const typename boost::remove_reference<Tag2>::type&)
805             >(), std::move(other))
806         )
807     {}
808     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other,const binding<Concept> & binding_arg)809     any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg)
810       : table(binding_arg),
811         data(::boost::type_erasure::call(
812             constructible<
813                 typename ::boost::remove_const<
814                     typename boost::remove_reference<Tag2>::type
815                 >::type(const typename boost::remove_reference<Tag2>::type&)
816             >(), std::move(other))
817         )
818     {}
819 #endif
820 
821     // One argument is a special case.  The argument must be an any
822     // and the constructor must be explicit.
823     template<class Tag2>
any(const any<Concept,Tag2> & other)824     explicit any(const any<Concept, Tag2>& other)
825       : table(::boost::type_erasure::detail::access::table(other)),
826         data(::boost::type_erasure::call(
827             ::boost::type_erasure::detail::make(
828                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
829             ), other)
830         )
831     {}
832     template<class Tag2>
any(any<Concept,Tag2> & other)833     explicit any(any<Concept, Tag2>& other)
834       : table(::boost::type_erasure::detail::access::table(other)),
835         data(::boost::type_erasure::call(
836             ::boost::type_erasure::detail::make(
837                 false? this->_boost_type_erasure_deduce_constructor(other) : 0
838             ), other)
839         )
840     {}
841 
842 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
843     template<class Tag2>
any(any<Concept,Tag2> && other)844     explicit any(any<Concept, Tag2>&& other)
845       : table(::boost::type_erasure::detail::access::table(other)),
846         data(::boost::type_erasure::call(
847             ::boost::type_erasure::detail::make(
848                 false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0
849             ), std::move(other))
850         )
851     {}
852 #endif
853 
any(const binding<Concept> & binding_arg)854     explicit any(const binding<Concept>& binding_arg)
855       : table(binding_arg),
856         data(
857             ::boost::type_erasure::call(
858                 binding_arg,
859                 ::boost::type_erasure::constructible<T()>()
860             )
861         )
862     {}
any(binding<Concept> & binding_arg)863     explicit any(binding<Concept>& binding_arg)
864       : table(binding_arg),
865         data(
866             ::boost::type_erasure::call(
867                 binding_arg,
868                 ::boost::type_erasure::constructible<T()>()
869             )
870         )
871     {}
872 
873 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
874 
any(binding<Concept> && binding_arg)875     explicit any(binding<Concept>&& binding_arg)
876       : table(binding_arg),
877         data(
878             ::boost::type_erasure::call(
879                 binding_arg,
880                 ::boost::type_erasure::constructible<T()>()
881             )
882         )
883     {}
884 
885 #endif
886 
887 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
888 
889     template<class R, class... A, class... U>
_boost_type_erasure_extract_table(::boost::type_erasure::constructible<R (A...)> *,U &&...u)890     const table_type& _boost_type_erasure_extract_table(
891         ::boost::type_erasure::constructible<R(A...)>*,
892         U&&... u)
893     {
894         return *::boost::type_erasure::detail::extract_table(static_cast<void(*)(A...)>(0), u...);
895     }
896 
897     template<class U0, class U1, class... U>
any(U0 && u0,U1 && u1,U &&...u)898     any(U0&& u0, U1&& u1, U&&... u)
899       : table(
900             _boost_type_erasure_extract_table(
901                 false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0,
902                 std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...
903             )
904         ),
905         data(
906             ::boost::type_erasure::call(
907                 ::boost::type_erasure::detail::make(
908                     false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0
909                 ),
910                 std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...
911             )
912         )
913     {}
914 
915     template<class U0, class... U>
any(const binding<Concept> & binding_arg,U0 && u0,U &&...u)916     any(const binding<Concept>& binding_arg, U0&& u0, U&&... u)
917       : table(binding_arg),
918         data(
919             ::boost::type_erasure::call(
920                 binding_arg,
921                 ::boost::type_erasure::detail::make(
922                     false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
923                 ),
924                 std::forward<U0>(u0), std::forward<U>(u)...
925             )
926         )
927     {}
928 
929     // disambiguate
930     template<class U0, class... U>
any(binding<Concept> & binding_arg,U0 && u0,U &&...u)931     any(binding<Concept>& binding_arg, U0&& u0, U&&... u)
932       : table(binding_arg),
933         data(
934             ::boost::type_erasure::call(
935                 binding_arg,
936                 ::boost::type_erasure::detail::make(
937                     false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
938                 ),
939                 std::forward<U0>(u0), std::forward<U>(u)...
940             )
941         )
942     {}
943     template<class U0, class... U>
any(binding<Concept> && binding_arg,U0 && u0,U &&...u)944     any(binding<Concept>&& binding_arg, U0&& u0, U&&... u)
945       : table(binding_arg),
946         data(
947             ::boost::type_erasure::call(
948                 binding_arg,
949                 ::boost::type_erasure::detail::make(
950                     false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U>(u)...) : 0
951                 ),
952                 std::forward<U0>(u0), std::forward<U>(u)...
953             )
954         )
955     {}
956 
957 #else
958 
959 #include <boost/type_erasure/detail/construct.hpp>
960 
961 #endif
962 
963 #endif
964 
965     /**
966      * Assigns to an @ref any.
967      *
968      * If an appropriate overload of @ref assignable is not available
969      * and @ref relaxed is in @c Concept, falls back on
970      * constructing from @c other.
971      *
972      * \throws Whatever the assignment operator of the contained
973      *         type throws.  When falling back on construction,
974      *         throws @c std::bad_alloc or whatever the copy
975      *         constructor of the contained type throws.  In
976      *         this case assignment provides the strong exception
977      *         guarantee.  When calling the assignment operator
978      *         of the contained type, the exception guarantee is
979      *         whatever the contained type provides.
980      */
operator =(const any & other)981     any& operator=(const any& other)
982     {
983         _boost_type_erasure_resolve_assign(other);
984         return *this;
985     }
986     /**
987      * Assigns to an @ref any.
988      *
989      * If an appropriate overload of @ref assignable is not available
990      * and @ref relaxed is in @c Concept, falls back on
991      * constructing from @c other.
992      *
993      * \throws Whatever the assignment operator of the contained
994      *         type throws.  When falling back on construction,
995      *         throws @c std::bad_alloc or whatever the copy
996      *         constructor of the contained type throws.  In
997      *         this case assignment provides the strong exception
998      *         guarantee.  When calling an assignment operator
999      *         of the contained type, the exception guarantee is
1000      *         whatever the contained type provides.
1001      */
1002     template<class U>
operator =(const U & other)1003     any& operator=(const U& other)
1004     {
1005         _boost_type_erasure_resolve_assign(other);
1006         return *this;
1007     }
1008     /**
1009      * \pre @c Concept includes @ref destructible "destructible<T>".
1010      */
~any()1011     ~any()
1012     {
1013         table.template find<destructible<T> >()(data);
1014     }
1015 
1016 #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
1017     /** INTERNAL ONLY */
operator param<Concept,T&>()1018     operator param<Concept, T&>() & { return param<Concept, T&>(data, table); }
1019     /** INTERNAL ONLY */
operator param<Concept,T&&>()1020     operator param<Concept, T&&>() && { return param<Concept, T&&>(data, table); }
1021 #endif
1022 private:
1023     /** INTERNAL ONLY */
_boost_type_erasure_swap(any & other)1024     void _boost_type_erasure_swap(any& other)
1025     {
1026         ::std::swap(data, other.data);
1027         ::std::swap(table, other.table);
1028     }
1029     /** INTERNAL ONLY */
1030     template<class Other>
_boost_type_erasure_resolve_assign(const Other & other)1031     void _boost_type_erasure_resolve_assign(const Other& other)
1032     {
1033         _boost_type_erasure_assign_impl(
1034             other,
1035             false? this->_boost_type_erasure_deduce_assign(
1036                 ::boost::type_erasure::detail::make_fallback(
1037                     other,
1038                     ::boost::mpl::bool_<
1039                         sizeof(
1040                             ::boost::type_erasure::detail::check_overload(
1041                                 ::boost::declval<any&>().
1042                                     _boost_type_erasure_deduce_assign(other)
1043                             )
1044                         ) == sizeof(::boost::type_erasure::detail::yes)
1045                     >()
1046                 )
1047             ) : 0,
1048             ::boost::type_erasure::is_relaxed<Concept>()
1049         );
1050     }
1051     /** INTERNAL ONLY */
1052     template<class Other, class U>
_boost_type_erasure_assign_impl(const Other & other,const assignable<T,U> *,::boost::mpl::false_)1053     void _boost_type_erasure_assign_impl(
1054         const Other& other,
1055         const assignable<T, U>*,
1056         ::boost::mpl::false_)
1057     {
1058         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1059     }
1060     /** INTERNAL ONLY */
1061     template<class Other, class U>
_boost_type_erasure_assign_impl(const Other & other,const assignable<T,U> *,::boost::mpl::true_)1062     void _boost_type_erasure_assign_impl(
1063         const Other& other,
1064         const assignable<T, U>*,
1065         ::boost::mpl::true_)
1066     {
1067         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1068     }
1069     /** INTERNAL ONLY */
1070     template<class Other>
_boost_type_erasure_assign_impl(const Other & other,const void *,::boost::mpl::true_)1071     void _boost_type_erasure_assign_impl(
1072         const Other& other,
1073         const void*,
1074         ::boost::mpl::true_)
1075     {
1076         any temp(other);
1077         _boost_type_erasure_swap(temp);
1078     }
1079     /** INTERNAL ONLY */
1080     template<class Concept2, class Tag2>
_boost_type_erasure_resolve_assign(const any<Concept2,Tag2> & other)1081     void _boost_type_erasure_resolve_assign(const any<Concept2, Tag2>& other)
1082     {
1083         _boost_type_erasure_assign_impl(
1084             other,
1085             false? this->_boost_type_erasure_deduce_assign(
1086                 ::boost::type_erasure::detail::make_fallback(
1087                     other,
1088                     ::boost::mpl::bool_<
1089                         sizeof(
1090                             ::boost::type_erasure::detail::check_overload(
1091                                 ::boost::declval<any&>().
1092                                     _boost_type_erasure_deduce_assign(other)
1093                             )
1094                         ) == sizeof(::boost::type_erasure::detail::yes)
1095                     >()
1096                 )
1097             ) : 0,
1098             false? this->_boost_type_erasure_deduce_constructor(
1099                 ::boost::type_erasure::detail::make_fallback(
1100                     other,
1101                     ::boost::mpl::bool_<
1102                         sizeof(
1103                             ::boost::type_erasure::detail::check_overload(
1104                                 ::boost::declval<any&>().
1105                                     _boost_type_erasure_deduce_constructor(other)
1106                             )
1107                         ) == sizeof(::boost::type_erasure::detail::yes)
1108                     >()
1109                 )
1110             ) : 0,
1111             ::boost::type_erasure::is_relaxed<Concept>()
1112         );
1113     }
1114     /** INTERNAL ONLY */
1115     template<class Other, class U>
_boost_type_erasure_assign_impl(const Other & other,const assignable<T,U> *,const void *,::boost::mpl::false_)1116     void _boost_type_erasure_assign_impl(
1117         const Other& other,
1118         const assignable<T, U>*,
1119         const void*,
1120         ::boost::mpl::false_)
1121     {
1122         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1123     }
1124     /** INTERNAL ONLY */
1125     template<class Other, class U>
_boost_type_erasure_assign_impl(const Other & other,const assignable<T,U> *,const void *,::boost::mpl::true_)1126     void _boost_type_erasure_assign_impl(
1127         const Other& other,
1128         const assignable<T, U>*,
1129         const void*,
1130         ::boost::mpl::true_)
1131     {
1132         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1133     }
1134     /** INTERNAL ONLY */
1135     template<class Other, class Sig>
_boost_type_erasure_assign_impl(const Other & other,const void *,const constructible<Sig> *,::boost::mpl::true_)1136     void _boost_type_erasure_assign_impl(
1137         const Other& other,
1138         const void*,
1139         const constructible<Sig>*,
1140         ::boost::mpl::true_)
1141     {
1142         any temp(other);
1143         _boost_type_erasure_swap(temp);
1144     }
1145     /** INTERNAL ONLY */
1146     template<class Other, class U, class Sig>
_boost_type_erasure_assign_impl(const Other & other,const assignable<T,U> *,const constructible<Sig> *,::boost::mpl::true_)1147     void _boost_type_erasure_assign_impl(
1148         const Other& other,
1149         const assignable<T, U>*,
1150         const constructible<Sig>*,
1151         ::boost::mpl::true_)
1152     {
1153         if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other))
1154         {
1155             ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
1156         }
1157         else
1158         {
1159             any temp(other);
1160             _boost_type_erasure_swap(temp);
1161         }
1162     }
1163     friend struct ::boost::type_erasure::detail::access;
1164     // The table has to be initialized first for exception
1165     // safety in some constructors.
1166     table_type table;
1167     ::boost::type_erasure::detail::storage data;
1168 };
1169 
1170 template<class Concept, class T>
1171 class any<Concept, T&> :
1172     public ::boost::type_erasure::detail::compute_bases<
1173         ::boost::type_erasure::any<Concept, T&>,
1174         Concept,
1175         T
1176     >::type
1177 {
1178     typedef ::boost::type_erasure::binding<Concept> table_type;
1179 public:
1180     /** INTERNAL ONLY */
1181     typedef Concept _boost_type_erasure_concept_type;
1182     /** INTERNAL ONLY */
any(const::boost::type_erasure::detail::storage & data_arg,const table_type & table_arg)1183     any(const ::boost::type_erasure::detail::storage& data_arg,
1184         const table_type& table_arg)
1185       : data(data_arg),
1186         table(table_arg)
1187     {}
1188     /**
1189      * Constructs an @ref any from a reference.
1190      *
1191      * \param arg The object to bind the reference to.
1192      *
1193      * \pre @c U is a model of @c Concept.
1194      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1195      *
1196      * \throws Nothing.
1197      */
1198     template<class U>
any(U & arg,typename::boost::disable_if<::boost::mpl::or_<::boost::is_const<U>,::boost::type_erasure::detail::is_any<U>>>::type * =0)1199     any(U& arg
1200 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1201         ,  typename ::boost::disable_if<
1202             ::boost::mpl::or_<
1203                 ::boost::is_const<U>,
1204                 ::boost::type_erasure::detail::is_any<U>
1205             >
1206         >::type* = 0
1207 #endif
1208         )
1209       : table((
1210             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
1211             ::boost::type_erasure::make_binding<
1212                 ::boost::mpl::map< ::boost::mpl::pair<T, U> >
1213             >()
1214         ))
1215     {
1216         data.data = ::boost::addressof(arg);
1217     }
1218     /**
1219      * Constructs an @ref any from a reference.
1220      *
1221      * \param arg The object to bind the reference to.
1222      * \param binding Specifies the actual types that
1223      *        all the placeholders should bind to.
1224      *
1225      * \pre @c U is a model of @c Concept.
1226      * \pre @c Map is an MPL map with an entry for every
1227      *         non-deduced placeholder referred to by @c Concept.
1228      *
1229      * \throws Nothing.
1230      */
1231     template<class U, class Map>
any(U & arg,const static_binding<Map> & binding_arg)1232     any(U& arg, const static_binding<Map>& binding_arg)
1233       : table((
1234             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1235             binding_arg
1236         ))
1237     {
1238         BOOST_MPL_ASSERT((::boost::is_same<
1239             typename ::boost::mpl::at<Map, T>::type, U>));
1240         data.data = ::boost::addressof(arg);
1241     }
1242     /**
1243      * Constructs an @ref any from another reference.
1244      *
1245      * \param other The reference to copy.
1246      *
1247      * \throws Nothing.
1248      */
any(const any & other)1249     any(const any& other)
1250       : data(other.data),
1251         table(other.table)
1252     {}
1253 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
any(any & other)1254     any(any& other)
1255       : data(other.data),
1256         table(other.table)
1257     {}
1258 #endif
1259     /**
1260      * Constructs an @ref any from another @ref any.
1261      *
1262      * \param other The object to bind the reference to.
1263      *
1264      * \throws Nothing.
1265      */
any(any<Concept,T> & other)1266     any(any<Concept, T>& other)
1267       : data(::boost::type_erasure::detail::access::data(other)),
1268         table(::boost::type_erasure::detail::access::table(other))
1269     {}
1270     /**
1271      * Constructs an @ref any from another reference.
1272      *
1273      * \param other The reference to copy.
1274      *
1275      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1276      * \pre After substituting @c T for @c Tag2, the requirements of
1277      *      @c Concept2 must be a superset of the requirements of
1278      *      @c Concept.
1279      *
1280      * \throws std::bad_alloc
1281      */
1282     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2 &> & other,typename::boost::disable_if<::boost::mpl::or_<::boost::is_same<Concept,Concept2>,::boost::is_const<Tag2>>>::type * =0)1283     any(const any<Concept2, Tag2&>& other
1284 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1285         , typename ::boost::disable_if<
1286             ::boost::mpl::or_<
1287                 ::boost::is_same<Concept, Concept2>,
1288                 ::boost::is_const<Tag2>
1289             >
1290         >::type* = 0
1291 #endif
1292         )
1293       : data(::boost::type_erasure::detail::access::data(other)),
1294         table(
1295             ::boost::type_erasure::detail::access::table(other),
1296             ::boost::mpl::map<
1297                 ::boost::mpl::pair<
1298                     T,
1299                     Tag2
1300                 >
1301             >())
1302     {}
1303     /**
1304      * Constructs an @ref any from another @ref any.
1305      *
1306      * \param other The object to bind the reference to.
1307      *
1308      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1309      * \pre After substituting @c T for @c Tag2, the requirements of
1310      *      @c Concept2 must be a superset of the requirements of
1311      *      @c Concept.
1312      *
1313      * \throws std::bad_alloc
1314      */
1315     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other,typename::boost::disable_if<::boost::mpl::or_<::boost::is_same<Concept,Concept2>,::boost::is_const<typename::boost::remove_reference<Tag2>::type>>>::type * =0)1316     any(any<Concept2, Tag2>& other
1317 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1318         , typename ::boost::disable_if<
1319             ::boost::mpl::or_<
1320                 ::boost::is_same<Concept, Concept2>,
1321                 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
1322             >
1323         >::type* = 0
1324 #endif
1325         )
1326       : data(::boost::type_erasure::detail::access::data(other)),
1327         table(
1328             ::boost::type_erasure::detail::access::table(other),
1329             ::boost::mpl::map<
1330                 ::boost::mpl::pair<
1331                     T,
1332                     typename ::boost::remove_reference<Tag2>::type
1333                 >
1334             >())
1335     {}
1336     /**
1337      * Constructs an @ref any from another reference.
1338      *
1339      * \param other The reference to copy.
1340      * \param binding Specifies the mapping between the two concepts.
1341      *
1342      * \pre @c Map must be an MPL map with keys for all the non-deduced
1343      *      placeholders used by @c Concept and values for the corresponding
1344      *      placeholders in @c Concept2.
1345      * \pre After substituting placeholders according to @c Map, the
1346      *      requirements of @c Concept2 must be a superset of the
1347      *      requirements of @c Concept.
1348      *
1349      * \throws std::bad_alloc
1350      */
1351     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2 &> & other,const static_binding<Map> & binding_arg,typename::boost::disable_if<::boost::is_const<Tag2>>::type * =0)1352     any(const any<Concept2, Tag2&>& other, const static_binding<Map>& binding_arg
1353 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1354         , typename ::boost::disable_if< ::boost::is_const<Tag2> >::type* = 0
1355 #endif
1356         )
1357       : data(::boost::type_erasure::detail::access::data(other)),
1358         table(::boost::type_erasure::detail::access::table(other), binding_arg)
1359     {}
1360     /**
1361      * Constructs an @ref any from another @ref any.
1362      *
1363      * \param other The object to bind the reference to.
1364      * \param binding Specifies the mapping between the two concepts.
1365      *
1366      * \pre @c Map must be an MPL map with keys for all the non-deduced
1367      *      placeholders used by @c Concept and values for the corresponding
1368      *      placeholders in @c Concept2.
1369      * \pre After substituting placeholders according to @c Map, the
1370      *      requirements of @c Concept2 must be a superset of the
1371      *      requirements of @c Concept.
1372      *
1373      * \throws std::bad_alloc
1374      */
1375     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> & other,const static_binding<Map> & binding_arg,typename::boost::disable_if<::boost::is_const<typename::boost::remove_reference<Tag2>::type>>::type * =0)1376     any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg
1377 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1378         , typename ::boost::disable_if<
1379             ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
1380         >::type* = 0
1381 #endif
1382         )
1383       : data(::boost::type_erasure::detail::access::data(other)),
1384         table(::boost::type_erasure::detail::access::table(other), binding_arg)
1385     {}
1386     /**
1387      * Constructs an @ref any from another reference.
1388      *
1389      * \param other The reference to copy.
1390      * \param binding Specifies the bindings of placeholders to actual types.
1391      *
1392      * \pre The type stored in @c other must match the type expected by
1393      *      @c binding.
1394      *
1395      * \post binding_of(*this) == @c binding
1396      *
1397      * \throws Nothing.
1398      */
1399     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2 &> & other,const binding<Concept> & binding_arg,typename::boost::disable_if<::boost::is_const<Tag2>>::type * =0)1400     any(const any<Concept2, Tag2&>& other, const binding<Concept>& binding_arg
1401 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1402         , typename ::boost::disable_if<
1403             ::boost::is_const<Tag2>
1404         >::type* = 0
1405 #endif
1406         )
1407       : data(::boost::type_erasure::detail::access::data(other)),
1408         table(binding_arg)
1409     {}
1410     /**
1411      * Constructs an @ref any from another @ref any.
1412      *
1413      * \param other The object to bind the reference to.
1414      * \param binding Specifies the bindings of placeholders to actual types.
1415      *
1416      * \pre The type stored in @c other must match the type expected by
1417      *      @c binding.
1418      *
1419      * \post binding_of(*this) == @c binding
1420      *
1421      * \throws Nothing.
1422      */
1423     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> & other,const binding<Concept> & binding_arg,typename::boost::disable_if<::boost::is_const<typename::boost::remove_reference<Tag2>::type>>::type * =0)1424     any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg
1425 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1426         , typename ::boost::disable_if<
1427             ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
1428         >::type* = 0
1429 #endif
1430         )
1431       : data(::boost::type_erasure::detail::access::data(other)),
1432         table(binding_arg)
1433     {}
1434 
1435     /**
1436      * Assigns to an @ref any.
1437      *
1438      * If an appropriate overload of @ref assignable is not available
1439      * and @ref relaxed is in @c Concept, falls back on
1440      * constructing from @c other.
1441      *
1442      * \throws Whatever the assignment operator of the contained
1443      *         type throws.  When falling back on construction,
1444      *         throws @c std::bad_alloc.  In this case assignment
1445      *         provides the strong exception guarantee.  When
1446      *         calling the assignment operator of the contained type,
1447      *         the exception guarantee is whatever the contained type provides.
1448      */
operator =(const any & other)1449     any& operator=(const any& other)
1450     {
1451         _boost_type_erasure_resolve_assign(other);
1452         return *this;
1453     }
1454 
1455     /**
1456      * Assigns to an @ref any.
1457      *
1458      * If an appropriate overload of @ref assignable is not available
1459      * and @ref relaxed is in @c Concept, falls back on
1460      * constructing from @c other.
1461      *
1462      * \throws Whatever the assignment operator of the contained
1463      *         type throws.  When falling back on construction,
1464      *         throws @c std::bad_alloc.  In this case assignment
1465      *         provides the strong exception guarantee.  When
1466      *         calling the assignment operator of the contained type,
1467      *         the exception guarantee is whatever the contained type provides.
1468      */
1469     template<class U>
operator =(U & other)1470     any& operator=(U& other)
1471     {
1472         _boost_type_erasure_resolve_assign(other);
1473         return *this;
1474     }
1475 
1476     /**
1477      * Assigns to an @ref any.
1478      *
1479      * If an appropriate overload of @ref assignable is not available
1480      * and @ref relaxed is in @c Concept, falls back on
1481      * constructing from @c other.
1482      *
1483      * \throws Whatever the assignment operator of the contained
1484      *         type throws.  When falling back on construction,
1485      *         throws @c std::bad_alloc.  In this case assignment
1486      *         provides the strong exception guarantee.  When
1487      *         calling the assignment operator of the contained type,
1488      *         the exception guarantee is whatever the contained type provides.
1489      */
1490     template<class U>
operator =(const U & other)1491     any& operator=(const U& other)
1492     {
1493         _boost_type_erasure_resolve_assign(other);
1494         return *this;
1495     }
1496 
1497 #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
1498     /** INTERNAL ONLY */
operator param<Concept,T&>() const1499     operator param<Concept, T&>() const { return param<Concept, T&>(data, table); }
1500 #endif
1501 private:
1502 
1503     /** INTERNAL ONLY */
_boost_type_erasure_swap(any & other)1504     void _boost_type_erasure_swap(any& other)
1505     {
1506         ::std::swap(data, other.data);
1507         ::std::swap(table, other.table);
1508     }
1509     /** INTERNAL ONLY */
1510     template<class Other>
_boost_type_erasure_resolve_assign(Other & other)1511     void _boost_type_erasure_resolve_assign(Other& other)
1512     {
1513         _boost_type_erasure_assign_impl(
1514             other,
1515             false? this->_boost_type_erasure_deduce_assign(
1516                 ::boost::type_erasure::detail::make_fallback(
1517                     other,
1518                     ::boost::mpl::bool_<
1519                         sizeof(
1520                             ::boost::type_erasure::detail::check_overload(
1521                                 ::boost::declval<any&>().
1522                                     _boost_type_erasure_deduce_assign(other)
1523                             )
1524                         ) == sizeof(::boost::type_erasure::detail::yes)
1525                     >()
1526                 )
1527             ) : 0,
1528             ::boost::type_erasure::is_relaxed<Concept>()
1529         );
1530     }
1531     /** INTERNAL ONLY */
1532     template<class Other, class U>
_boost_type_erasure_assign_impl(Other & other,const assignable<T,U> *,::boost::mpl::false_)1533     void _boost_type_erasure_assign_impl(
1534         Other& other,
1535         const assignable<T, U>*,
1536         ::boost::mpl::false_)
1537     {
1538         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
1539     }
1540     /** INTERNAL ONLY */
1541     template<class Other, class U>
_boost_type_erasure_assign_impl(Other & other,const assignable<T,U> *,::boost::mpl::true_)1542     void _boost_type_erasure_assign_impl(
1543         Other& other,
1544         const assignable<T, U>*,
1545         ::boost::mpl::true_)
1546     {
1547         if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) {
1548             ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
1549         } else {
1550             any temp(other);
1551             _boost_type_erasure_swap(temp);
1552         }
1553     }
1554     /** INTERNAL ONLY */
1555     template<class Other>
_boost_type_erasure_assign_impl(Other & other,const void *,::boost::mpl::true_)1556     void _boost_type_erasure_assign_impl(
1557         Other& other,
1558         const void*,
1559         ::boost::mpl::true_)
1560     {
1561         any temp(other);
1562         _boost_type_erasure_swap(temp);
1563     }
1564 
1565     friend struct ::boost::type_erasure::detail::access;
1566     ::boost::type_erasure::detail::storage data;
1567     table_type table;
1568 };
1569 
1570 #ifdef BOOST_MSVC
1571 #pragma warning(pop)
1572 #endif
1573 
1574 template<class Concept, class T>
1575 class any<Concept, const T&> :
1576     public ::boost::type_erasure::detail::compute_bases<
1577         ::boost::type_erasure::any<Concept, const T&>,
1578         Concept,
1579         T
1580     >::type
1581 {
1582     typedef ::boost::type_erasure::binding<Concept> table_type;
1583 public:
1584     /** INTERNAL ONLY */
1585     typedef Concept _boost_type_erasure_concept_type;
1586     /** INTERNAL ONLY */
any(const::boost::type_erasure::detail::storage & data_arg,const table_type & table_arg)1587     any(const ::boost::type_erasure::detail::storage& data_arg,
1588         const table_type& table_arg)
1589       : data(data_arg),
1590         table(table_arg)
1591     {}
1592     /**
1593      * Constructs an @ref any from a reference.
1594      *
1595      * \param arg The object to bind the reference to.
1596      *
1597      * \pre @c U is a model of @c Concept.
1598      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1599      *
1600      * \throws Nothing.
1601      */
1602     template<class U>
any(const U & arg)1603     any(const U& arg)
1604       : table((
1605             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
1606             ::boost::type_erasure::make_binding<
1607                 ::boost::mpl::map< ::boost::mpl::pair<T, U> >
1608             >()
1609         ))
1610     {
1611         data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
1612     }
1613     /**
1614      * Constructs an @ref any from a reference.
1615      *
1616      * \param arg The object to bind the reference to.
1617      * \param binding Specifies the actual types that
1618      *        all the placeholders should bind to.
1619      *
1620      * \pre @c U is a model of @c Concept.
1621      * \pre @c Map is an MPL map with an entry for every
1622      *         non-deduced placeholder referred to by @c Concept.
1623      *
1624      * \throws Nothing.
1625      */
1626     template<class U, class Map>
any(const U & arg,const static_binding<Map> & binding_arg)1627     any(const U& arg, const static_binding<Map>& binding_arg)
1628       : table((
1629             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1630             binding_arg
1631         ))
1632     {
1633         BOOST_MPL_ASSERT((::boost::is_same<
1634             typename ::boost::mpl::at<Map, T>::type, U>));
1635         data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
1636     }
1637     /**
1638      * Constructs an @ref any from another @ref any.
1639      *
1640      * \param other The reference to copy.
1641      *
1642      * \throws Nothing.
1643      */
any(const any & other)1644     any(const any& other)
1645       : data(other.data),
1646         table(other.table)
1647     {}
1648     /**
1649      * Constructs an @ref any from another @ref any.
1650      *
1651      * \param other The reference to copy.
1652      *
1653      * \throws Nothing.
1654      */
any(const any<Concept,T &> & other)1655     any(const any<Concept, T&>& other)
1656       : data(::boost::type_erasure::detail::access::data(other)),
1657         table(::boost::type_erasure::detail::access::table(other))
1658     {}
1659     /**
1660      * Constructs an @ref any from another @ref any.
1661      *
1662      * \param other The object to bind the reference to.
1663      *
1664      * \throws Nothing.
1665      */
any(const any<Concept,T> & other)1666     any(const any<Concept, T>& other)
1667       : data(::boost::type_erasure::detail::access::data(other)),
1668         table(::boost::type_erasure::detail::access::table(other))
1669     {}
1670 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1671     /**
1672      * Constructs an @ref any from another @ref any.
1673      *
1674      * \param other The object to bind the reference to.
1675      *
1676      * \throws Nothing.
1677      */
any(const any<Concept,T &&> & other)1678     any(const any<Concept, T&&>& other)
1679       : data(::boost::type_erasure::detail::access::data(other)),
1680         table(::boost::type_erasure::detail::access::table(other))
1681     {}
1682 #endif
1683     /**
1684      * Constructs an @ref any from another @ref any.
1685      *
1686      * \param other The object to bind the reference to.
1687      *
1688      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1689      * \pre After substituting @c T for @c Tag2, the requirements of
1690      *      @c Concept2 must be a superset of the requirements of
1691      *      @c Concept.
1692      *
1693      * \throws std::bad_alloc
1694      */
1695     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other,typename::boost::disable_if<::boost::is_same<Concept,Concept2>>::type * =0)1696     any(const any<Concept2, Tag2>& other
1697 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1698         , typename ::boost::disable_if< ::boost::is_same<Concept, Concept2> >::type* = 0
1699 #endif
1700         )
1701       : data(::boost::type_erasure::detail::access::data(other)),
1702         table(
1703             ::boost::type_erasure::detail::access::table(other),
1704             ::boost::mpl::map<
1705                 ::boost::mpl::pair<
1706                     T,
1707                     typename ::boost::remove_const<
1708                         typename ::boost::remove_reference<Tag2>::type
1709                     >::type
1710                 >
1711             >())
1712     {}
1713     /**
1714      * Constructs an @ref any from another @ref any.
1715      *
1716      * \param other The object to bind the reference to.
1717      * \param binding Specifies the mapping between the two concepts.
1718      *
1719      * \pre @c Map must be an MPL map with keys for all the non-deduced
1720      *      placeholders used by @c Concept and values for the corresponding
1721      *      placeholders in @c Concept2.
1722      * \pre After substituting placeholders according to @c Map, the
1723      *      requirements of @c Concept2 must be a superset of the
1724      *      requirements of @c Concept.
1725      *
1726      * \throws std::bad_alloc
1727      */
1728     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2> & other,const static_binding<Map> & binding_arg)1729     any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
1730       : data(::boost::type_erasure::detail::access::data(other)),
1731         table(::boost::type_erasure::detail::access::table(other), binding_arg)
1732     {}
1733     /**
1734      * Constructs an @ref any from another @ref any.
1735      *
1736      * \param other The object to bind the reference to.
1737      * \param binding Specifies the bindings of placeholders to actual types.
1738      *
1739      * \pre The type stored in @c other must match the type expected by
1740      *      @c binding.
1741      *
1742      * \post binding_of(*this) == @c binding
1743      *
1744      * \throws Nothing.
1745      */
1746     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2> & other,const binding<Concept> & binding_arg)1747     any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
1748       : data(::boost::type_erasure::detail::access::data(other)),
1749         table(binding_arg)
1750     {}
1751 
1752 
1753     /**
1754      * Assigns to an @ref any.
1755      *
1756      * \pre @ref relaxed is in @c Concept.
1757      *
1758      * \throws Nothing.
1759      */
operator =(const any & other)1760     any& operator=(const any& other)
1761     {
1762         BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
1763         any temp(other);
1764         _boost_type_erasure_swap(temp);
1765         return *this;
1766     }
1767     /**
1768      * Assigns to an @ref any.
1769      *
1770      * \pre @ref relaxed is in @c Concept.
1771      *
1772      * \throws std::bad_alloc.  Provides the strong exception guarantee.
1773      */
1774     template<class U>
operator =(const U & other)1775     any& operator=(const U& other)
1776     {
1777         BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
1778         any temp(other);
1779         _boost_type_erasure_swap(temp);
1780         return *this;
1781     }
1782 
1783 #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
1784     /** INTERNAL ONLY */
operator param<Concept,const T&>() const1785     operator param<Concept, const T&>() const { return param<Concept, const T&>(data, table); }
1786 #endif
1787 private:
1788     /** INTERNAL ONLY */
_boost_type_erasure_swap(any & other)1789     void _boost_type_erasure_swap(any& other)
1790     {
1791         ::std::swap(data, other.data);
1792         ::std::swap(table, other.table);
1793     }
1794     friend struct ::boost::type_erasure::detail::access;
1795     ::boost::type_erasure::detail::storage data;
1796     table_type table;
1797 };
1798 
1799 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1800 
1801 template<class Concept, class T>
1802 class any<Concept, T&&> :
1803     public ::boost::type_erasure::detail::compute_bases<
1804         ::boost::type_erasure::any<Concept, T&&>,
1805         Concept,
1806         T
1807     >::type
1808 {
1809     typedef ::boost::type_erasure::binding<Concept> table_type;
1810 public:
1811     /** INTERNAL ONLY */
1812     typedef Concept _boost_type_erasure_concept_type;
1813     /** INTERNAL ONLY */
any(const::boost::type_erasure::detail::storage & data_arg,const table_type & table_arg)1814     any(const ::boost::type_erasure::detail::storage& data_arg,
1815         const table_type& table_arg)
1816       : data(data_arg),
1817         table(table_arg)
1818     {}
1819     /**
1820      * Constructs an @ref any from a reference.
1821      *
1822      * \param arg The object to bind the reference to.
1823      *
1824      * \pre @c U is a model of @c Concept.
1825      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1826      *
1827      * \throws Nothing.
1828      */
1829     template<class U>
any(U && arg,typename::boost::disable_if<::boost::mpl::or_<::boost::is_reference<U>,::boost::is_const<U>,::boost::type_erasure::detail::is_any<U>>>::type * =0)1830     any(U&& arg
1831 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1832         ,  typename ::boost::disable_if<
1833             ::boost::mpl::or_<
1834                 ::boost::is_reference<U>,
1835                 ::boost::is_const<U>,
1836                 ::boost::type_erasure::detail::is_any<U>
1837             >
1838         >::type* = 0
1839 #endif
1840         )
1841       : table((
1842             BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
1843             ::boost::type_erasure::make_binding<
1844                 ::boost::mpl::map< ::boost::mpl::pair<T, U> >
1845             >()
1846         ))
1847     {
1848         data.data = ::boost::addressof(arg);
1849     }
1850     /**
1851      * Constructs an @ref any from a reference.
1852      *
1853      * \param arg The object to bind the reference to.
1854      * \param binding Specifies the actual types that
1855      *        all the placeholders should bind to.
1856      *
1857      * \pre @c U is a model of @c Concept.
1858      * \pre @c Map is an MPL map with an entry for every
1859      *         non-deduced placeholder referred to by @c Concept.
1860      *
1861      * \throws Nothing.
1862      */
1863     template<class U, class Map>
any(U && arg,const static_binding<Map> & binding_arg)1864     any(U&& arg, const static_binding<Map>& binding_arg)
1865       : table((
1866             BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
1867             binding_arg
1868         ))
1869     {
1870         BOOST_MPL_ASSERT((::boost::is_same<
1871             typename ::boost::mpl::at<Map, T>::type, U>));
1872         data.data = ::boost::addressof(arg);
1873     }
1874     /**
1875      * Constructs an @ref any from another rvalue reference.
1876      *
1877      * \param other The reference to copy.
1878      *
1879      * \throws Nothing.
1880      */
1881 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
any(any && other)1882     any(any&& other)
1883       : data(other.data),
1884         table(std::move(other.table))
1885     {}
any(const any & other)1886     any(const any& other)
1887       : data(other.data),
1888         table(other.table)
1889     {}
1890 #endif
1891     /**
1892      * Constructs an @ref any from another @ref any.
1893      *
1894      * \param other The object to bind the reference to.
1895      *
1896      * \throws Nothing.
1897      */
any(any<Concept,T> && other)1898     any(any<Concept, T>&& other)
1899       : data(::boost::type_erasure::detail::access::data(other)),
1900         table(std::move(::boost::type_erasure::detail::access::table(other)))
1901     {}
1902     /**
1903      * Constructs an @ref any from another rvalue reference.
1904      *
1905      * \param other The reference to copy.
1906      *
1907      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1908      * \pre After substituting @c T for @c Tag2, the requirements of
1909      *      @c Concept2 must be a superset of the requirements of
1910      *      @c Concept.
1911      *
1912      * \throws std::bad_alloc
1913      */
1914     template<class Concept2, class Tag2>
any(any<Concept2,Tag2 &&> && other,typename::boost::disable_if<::boost::mpl::or_<::boost::is_reference<Tag2>,::boost::is_same<Concept,Concept2>,::boost::is_const<Tag2>>>::type * =0)1915     any(any<Concept2, Tag2&&>&& other
1916 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1917         , typename ::boost::disable_if<
1918             ::boost::mpl::or_<
1919                 ::boost::is_reference<Tag2>,
1920                 ::boost::is_same<Concept, Concept2>,
1921                 ::boost::is_const<Tag2>
1922             >
1923         >::type* = 0
1924 #endif
1925         )
1926       : data(::boost::type_erasure::detail::access::data(other)),
1927         table(
1928             std::move(::boost::type_erasure::detail::access::table(other)),
1929             ::boost::mpl::map<
1930                 ::boost::mpl::pair<
1931                     T,
1932                     Tag2
1933                 >
1934             >())
1935     {}
1936     /**
1937      * Constructs an @ref any from another @ref any.
1938      *
1939      * \param other The object to bind the reference to.
1940      *
1941      * \pre @c Concept must not refer to any non-deduced placeholder besides @c T.
1942      * \pre After substituting @c T for @c Tag2, the requirements of
1943      *      @c Concept2 must be a superset of the requirements of
1944      *      @c Concept.
1945      *
1946      * \throws std::bad_alloc
1947      */
1948     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other,typename::boost::disable_if<::boost::mpl::or_<::boost::is_same<Concept,Concept2>,::boost::is_const<typename::boost::remove_reference<Tag2>::type>>>::type * =0)1949     any(any<Concept2, Tag2>&& other
1950 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1951         , typename ::boost::disable_if<
1952             ::boost::mpl::or_<
1953                 ::boost::is_same<Concept, Concept2>,
1954                 ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
1955             >
1956         >::type* = 0
1957 #endif
1958         )
1959       : data(::boost::type_erasure::detail::access::data(other)),
1960         table(
1961             std::move(::boost::type_erasure::detail::access::table(other)),
1962             ::boost::mpl::map<
1963                 ::boost::mpl::pair<
1964                     T,
1965                     typename ::boost::remove_reference<Tag2>::type
1966                 >
1967             >())
1968     {}
1969     /**
1970      * Constructs an @ref any from another reference.
1971      *
1972      * \param other The reference to copy.
1973      * \param binding Specifies the mapping between the two concepts.
1974      *
1975      * \pre @c Map must be an MPL map with keys for all the non-deduced
1976      *      placeholders used by @c Concept and values for the corresponding
1977      *      placeholders in @c Concept2.
1978      * \pre After substituting placeholders according to @c Map, the
1979      *      requirements of @c Concept2 must be a superset of the
1980      *      requirements of @c Concept.
1981      *
1982      * \throws std::bad_alloc
1983      */
1984     template<class Concept2, class Tag2, class Map>
any(const any<Concept2,Tag2 &&> & other,const static_binding<Map> & binding_arg,typename::boost::disable_if<::boost::is_const<Tag2>>::type * =0)1985     any(const any<Concept2, Tag2&&>& other, const static_binding<Map>& binding_arg
1986 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
1987         , typename ::boost::disable_if< ::boost::is_const<Tag2> >::type* = 0
1988 #endif
1989         )
1990       : data(::boost::type_erasure::detail::access::data(other)),
1991         table(std::move(::boost::type_erasure::detail::access::table(other)), binding_arg)
1992     {}
1993     /**
1994      * Constructs an @ref any from another @ref any.
1995      *
1996      * \param other The object to bind the reference to.
1997      * \param binding Specifies the mapping between the two concepts.
1998      *
1999      * \pre @c Map must be an MPL map with keys for all the non-deduced
2000      *      placeholders used by @c Concept and values for the corresponding
2001      *      placeholders in @c Concept2.
2002      * \pre After substituting placeholders according to @c Map, the
2003      *      requirements of @c Concept2 must be a superset of the
2004      *      requirements of @c Concept.
2005      *
2006      * \throws std::bad_alloc
2007      */
2008     template<class Concept2, class Tag2, class Map>
any(any<Concept2,Tag2> && other,const static_binding<Map> & binding_arg,typename::boost::disable_if<::boost::is_const<typename::boost::remove_reference<Tag2>::type>>::type * =0)2009     any(any<Concept2, Tag2>&& other, const static_binding<Map>& binding_arg
2010 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
2011         , typename ::boost::disable_if<
2012             ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2013         >::type* = 0
2014 #endif
2015         )
2016       : data(::boost::type_erasure::detail::access::data(other)),
2017         table(::boost::type_erasure::detail::access::table(other), binding_arg)
2018     {}
2019     /**
2020      * Constructs an @ref any from another rvalue reference.
2021      *
2022      * \param other The reference to copy.
2023      * \param binding Specifies the bindings of placeholders to actual types.
2024      *
2025      * \pre The type stored in @c other must match the type expected by
2026      *      @c binding.
2027      *
2028      * \post binding_of(*this) == @c binding
2029      *
2030      * \throws Nothing.
2031      */
2032     template<class Concept2, class Tag2>
any(const any<Concept2,Tag2 &&> & other,const binding<Concept> & binding_arg,typename::boost::disable_if<::boost::is_const<Tag2>>::type * =0)2033     any(const any<Concept2, Tag2&&>& other, const binding<Concept>& binding_arg
2034 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
2035         , typename ::boost::disable_if<
2036             ::boost::is_const<Tag2>
2037         >::type* = 0
2038 #endif
2039         )
2040       : data(::boost::type_erasure::detail::access::data(other)),
2041         table(binding_arg)
2042     {}
2043     /**
2044      * Constructs an @ref any from another @ref any.
2045      *
2046      * \param other The object to bind the reference to.
2047      * \param binding Specifies the bindings of placeholders to actual types.
2048      *
2049      * \pre The type stored in @c other must match the type expected by
2050      *      @c binding.
2051      *
2052      * \post binding_of(*this) == @c binding
2053      *
2054      * \throws Nothing.
2055      */
2056     template<class Concept2, class Tag2>
any(any<Concept2,Tag2> && other,const binding<Concept> & binding_arg,typename::boost::disable_if<::boost::is_const<typename::boost::remove_reference<Tag2>::type>>::type * =0)2057     any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg
2058 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
2059         , typename ::boost::disable_if<
2060             ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
2061         >::type* = 0
2062 #endif
2063         )
2064       : data(::boost::type_erasure::detail::access::data(other)),
2065         table(binding_arg)
2066     {}
2067 
2068     /**
2069      * Assigns to an @ref any.
2070      *
2071      * If an appropriate overload of @ref assignable is not available
2072      * and @ref relaxed is in @c Concept, falls back on
2073      * constructing from @c other.
2074      *
2075      * \throws Whatever the assignment operator of the contained
2076      *         type throws.  When falling back on construction,
2077      *         throws @c std::bad_alloc.  In this case assignment
2078      *         provides the strong exception guarantee.  When
2079      *         calling the assignment operator of the contained type,
2080      *         the exception guarantee is whatever the contained type provides.
2081      */
operator =(const any & other)2082     any& operator=(const any& other)
2083     {
2084         _boost_type_erasure_resolve_assign(other);
2085         return *this;
2086     }
2087 
2088     /**
2089      * Assigns to an @ref any.
2090      *
2091      * If an appropriate overload of @ref assignable is not available
2092      * and @ref relaxed is in @c Concept, falls back on
2093      * constructing from @c other.
2094      *
2095      * \throws Whatever the assignment operator of the contained
2096      *         type throws.  When falling back on construction,
2097      *         throws @c std::bad_alloc.  In this case assignment
2098      *         provides the strong exception guarantee.  When
2099      *         calling the assignment operator of the contained type,
2100      *         the exception guarantee is whatever the contained type provides.
2101      */
2102     template<class U>
operator =(U & other)2103     any& operator=(U& other)
2104     {
2105         _boost_type_erasure_resolve_assign(other);
2106         return *this;
2107     }
2108 
2109     /**
2110      * Assigns to an @ref any.
2111      *
2112      * If an appropriate overload of @ref assignable is not available
2113      * and @ref relaxed is in @c Concept, falls back on
2114      * constructing from @c other.
2115      *
2116      * \throws Whatever the assignment operator of the contained
2117      *         type throws.  When falling back on construction,
2118      *         throws @c std::bad_alloc.  In this case assignment
2119      *         provides the strong exception guarantee.  When
2120      *         calling the assignment operator of the contained type,
2121      *         the exception guarantee is whatever the contained type provides.
2122      */
2123     template<class U>
operator =(const U & other)2124     any& operator=(const U& other)
2125     {
2126         _boost_type_erasure_resolve_assign(other);
2127         return *this;
2128     }
2129 
2130 #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
2131     /** INTERNAL ONLY */
operator param<Concept,T&&>() const2132     operator param<Concept, T&&>() const { return param<Concept, T&&>(data, table); }
2133 #endif
2134 private:
2135 
2136     /** INTERNAL ONLY */
_boost_type_erasure_swap(any & other)2137     void _boost_type_erasure_swap(any& other)
2138     {
2139         ::std::swap(data, other.data);
2140         ::std::swap(table, other.table);
2141     }
2142     /** INTERNAL ONLY */
2143     template<class Other>
_boost_type_erasure_resolve_assign(Other & other)2144     void _boost_type_erasure_resolve_assign(Other& other)
2145     {
2146         _boost_type_erasure_assign_impl(
2147             other,
2148             false? this->_boost_type_erasure_deduce_assign(
2149                 ::boost::type_erasure::detail::make_fallback(
2150                     other,
2151                     ::boost::mpl::bool_<
2152                         sizeof(
2153                             ::boost::type_erasure::detail::check_overload(
2154                                 ::boost::declval<any&>().
2155                                     _boost_type_erasure_deduce_assign(other)
2156                             )
2157                         ) == sizeof(::boost::type_erasure::detail::yes)
2158                     >()
2159                 )
2160             ) : 0,
2161             ::boost::type_erasure::is_relaxed<Concept>()
2162         );
2163     }
2164     /** INTERNAL ONLY */
2165     template<class Other, class U>
_boost_type_erasure_assign_impl(Other & other,const assignable<T,U> *,::boost::mpl::false_)2166     void _boost_type_erasure_assign_impl(
2167         Other& other,
2168         const assignable<T, U>*,
2169         ::boost::mpl::false_)
2170     {
2171         ::boost::type_erasure::call(assignable<T, U>(), *this, other);
2172     }
2173     /** INTERNAL ONLY */
2174     template<class Other, class U>
_boost_type_erasure_assign_impl(Other & other,const assignable<T,U> *,::boost::mpl::true_)2175     void _boost_type_erasure_assign_impl(
2176         Other& other,
2177         const assignable<T, U>*,
2178         ::boost::mpl::true_)
2179     {
2180         if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) {
2181             ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
2182         } else {
2183             any temp(other);
2184             _boost_type_erasure_swap(temp);
2185         }
2186     }
2187     /** INTERNAL ONLY */
2188     template<class Other>
_boost_type_erasure_assign_impl(Other & other,const void *,::boost::mpl::true_)2189     void _boost_type_erasure_assign_impl(
2190         Other& other,
2191         const void*,
2192         ::boost::mpl::true_)
2193     {
2194         any temp(other);
2195         _boost_type_erasure_swap(temp);
2196     }
2197 
2198     friend struct ::boost::type_erasure::detail::access;
2199     ::boost::type_erasure::detail::storage data;
2200     table_type table;
2201 };
2202 
2203 #endif
2204 
2205 }
2206 }
2207 
2208 #endif
2209