Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78429 - in sandbox/type_erasure: . boost boost/type_erasure boost/type_erasure/detail libs libs/type_erasure libs/type_erasure/doc libs/type_erasure/example libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-05-11 22:37:32


Author: steven_watanabe
Date: 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
New Revision: 78429
URL: http://svn.boost.org/trac/boost/changeset/78429

Log:
Import type_erasure
Added:
   sandbox/type_erasure/
   sandbox/type_erasure/Jamfile.v2 (contents, props changed)
   sandbox/type_erasure/Jamroot.jam (contents, props changed)
   sandbox/type_erasure/LICENSE_1_0.txt (contents, props changed)
   sandbox/type_erasure/boost/
   sandbox/type_erasure/boost/type_erasure/
   sandbox/type_erasure/boost/type_erasure/any.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/any_cast.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/binding.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/binding_of.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/builtin.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/call.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/callable.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/check_match.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/concept_interface.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/concept_of.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/config.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/constructible.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/derived.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/
   sandbox/type_erasure/boost/type_erasure/detail/access.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/construct.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/get_placeholders.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/get_signature.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/storage.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/detail/vtable.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/is_placeholder.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/iterator.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/operators.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/placeholder.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/rebind_any.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/relaxed_match.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/require_match.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/static_binding.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/tuple.hpp (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/typeid_of.hpp (contents, props changed)
   sandbox/type_erasure/libs/
   sandbox/type_erasure/libs/type_erasure/
   sandbox/type_erasure/libs/type_erasure/doc/
   sandbox/type_erasure/libs/type_erasure/doc/Jamfile.jam (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/
   sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/basic.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/compose.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/construction.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/custom.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/multi.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/overload.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/print_sequence.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/example/references.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/index.html (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/
   sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const1.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const2.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const3.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const4.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const5.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const6.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_ref.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_val.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_increment_discard_const.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_cref.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_ref.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_init.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_add.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_add_assign.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_any_cast.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_assign.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_binding_of.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_construct.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_construct_cref.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_construct_ref.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_dereference.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_equal.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_increment.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_less.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_negate.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_nested.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_reference.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_relaxed_match.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_stream.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_subscript.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_tuple.cpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_typeid_of.cpp (contents, props changed)

Added: sandbox/type_erasure/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/Jamfile.v2 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,28 @@
+# Copyright Rene Rivera 2007.
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# Usage:
+#
+# bjam [options | properties | targets]
+#
+# Options:
+#
+# --boost=<BOOST> The directotory of a Boost source tree.
+# Default; BOOST env var (if found)
+# Default; ../boost (if found)
+#
+# --boost-build=<BOOST_BUILD>
+# The directory for the Boost.Build v2 files.
+# Default; BOOST_BUILD_PATH env var (if found)
+# Default; BOOST_BUILD env var (if found)
+# Default; <BOOST>/tools/build/v2 (if found)
+
+#~ If we have the Boost sources we can use the project...
+
+if [ GLOB $(BOOST) : [ modules.peek project : JAMFILE ] ]
+{
+ use-project /boost : $(BOOST) ;
+}

Added: sandbox/type_erasure/Jamroot.jam
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/Jamroot.jam 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,9 @@
+
+import modules ;
+
+local boost = [ modules.peek : BOOST ] ;
+
+project type_erasure : requirements <include>$(boost) <include>. ;
+
+# This seems to prevent some Boost.Build errors that otherwise occur :-(
+use-project /boost : $(boost) ;

Added: sandbox/type_erasure/LICENSE_1_0.txt
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/LICENSE_1_0.txt 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.

Added: sandbox/type_erasure/boost/type_erasure/any.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/any.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,1214 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED
+
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/utility/declval.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/type_erasure/detail/access.hpp>
+#include <boost/type_erasure/detail/any_base.hpp>
+#include <boost/type_erasure/detail/normalize.hpp>
+#include <boost/type_erasure/detail/storage.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/binding.hpp>
+#include <boost/type_erasure/static_binding.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Sig>
+struct constructible;
+
+template<class T>
+struct destructible;
+
+template<class T, class U>
+struct assignable;
+
+namespace detail {
+
+template<class Derived, class Concept, class T>
+struct compute_bases
+{
+ typedef typename ::boost::mpl::fold<
+ typename ::boost::type_erasure::detail::collect_concepts<
+ Concept
+ >::type,
+ ::boost::type_erasure::any_base<Derived>,
+ ::boost::type_erasure::concept_interface<
+ ::boost::mpl::_2,
+ ::boost::mpl::_1,
+ T
+ >
+ >::type type;
+};
+
+template<class T>
+T make(T*) { return T(); }
+
+// This dance is necessary to avoid errors calling
+// an ellipsis function with a non-trivially-copyable
+// argument.
+
+typedef char no;
+struct yes { no dummy[2]; };
+
+template<class Op>
+yes check_overload(const Op*);
+no check_overload(const void*);
+
+struct fallback {};
+
+template<class T>
+fallback make_fallback(const T&, boost::mpl::false_)
+{
+ return fallback();
+}
+
+template<class T>
+const T& make_fallback(const T& arg, boost::mpl::true_)
+{
+ return arg;
+}
+
+template<class T>
+struct is_any : ::boost::mpl::false_ {};
+
+template<class Concept, class T>
+struct is_any<any<Concept, T> > : ::boost::mpl::true_ {};
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4355)
+#pragma warning(disable:4521)
+#endif
+
+/**
+ * The class template @ref any provides runtime polymorphism.
+ *
+ * \tparam Concept The concept that the type should model.
+ * \tparam T A placeholder specifying which type this is.
+ *
+ * @c Concept is defined as follows:
+ * - The built-in concepts provided by the library are valid concepts.
+ * - Any user-defined primitive concept is a valid concept.
+ * - An MPL Forward Sequence of concepts is a valid concept.
+ *
+ * Note that this definition is recursive and allows concepts to
+ * composed in a natural way.
+ */
+template<class Concept, class T = _self>
+class any :
+ public ::boost::type_erasure::detail::compute_bases<
+ ::boost::type_erasure::any<Concept, T>,
+ Concept,
+ T
+ >::type
+{
+ typedef ::boost::type_erasure::binding<Concept> table_type;
+public:
+ /** INTERNAL ONLY */
+ typedef Concept _boost_type_erasure_concept_type;
+ /** INTERNAL ONLY */
+ any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg)
+ : table(table_arg),
+ data(data_arg)
+ {}
+ /**
+ * Constructs an @ref any to hold a copy of @c data.
+ *
+ * \param data The object to construct the @ref any from.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c U must be \CopyConstructible.
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of @c U throws.
+ */
+ template<class U>
+ explicit any(const U& data_arg)
+ : table(
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ >()
+ ),
+ data(data_arg)
+ {}
+ /**
+ * Constructs an @ref any to hold a copy of @c data.
+ *
+ * \param data The object to construct the @ref any from.
+ * \param binding Specifies the actual types that
+ * all the placeholders should bind to.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c U must be \CopyConstructible.
+ * \pre @c Map is an MPL map with an entry for every
+ * placeholder referred to by @c Concept.
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of @c U throws.
+ */
+ template<class U, class Map>
+ any(const U& data_arg, const static_binding<Map>& binding_arg)
+ : table(binding_arg),
+ data(data_arg)
+ {}
+ /**
+ * Copies an @ref any.
+ *
+ * \param other The object to make a copy of.
+ *
+ * \pre @c Concept must contain @ref constructible<T(const T&)>.
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of the contained type throws.
+ */
+ any(const any& other)
+ : table(other.table),
+ data(::boost::type_erasure::call(constructible<T(const T&)>(), other))
+ {}
+ /**
+ * Upcasts from an @ref any with stricter requirements to
+ * an @ref any with weaker requirements.
+ *
+ * \param other The object to make a copy of.
+ *
+ * \pre @c Concept must contain @ref constructible<T(const T&)>.
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ * \pre After substituting @c T for @c Tag2, the requirements of
+ * @c Concept2 must be a superset of of the requirements of
+ * @c Concept.
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of the contained type throws.
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2>& other)
+ : table(
+ ::boost::type_erasure::detail::access::table(other),
+ ::boost::mpl::map<
+ ::boost::mpl::pair<
+ T,
+ typename ::boost::remove_const<
+ typename ::boost::remove_reference<Tag2>::type
+ >::type
+ >
+ >()
+ ),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to make a copy of.
+ * \param binding Specifies the mapping between the two concepts.
+ *
+ * \pre @c Concept must contain @ref constructible<T(const T&)>.
+ * \pre @c Map must be an MPL map with keys for all the placeholders
+ * used by @c Concept and values for the corresponding
+ * placeholders in @c Concept2.
+ * \pre After substituting placeholders according to @c Map, the
+ * requirements of @c Concept2 must be a superset of of the
+ * requirements of @c Concept.
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of the contained type throws.
+ */
+ template<class Concept2, class Tag2, class Map>
+ any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
+ : table(::boost::type_erasure::detail::access::table(other), binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to make a copy of.
+ * \param binding Specifies the bindings of placeholders to actual types.
+ *
+ * \pre @c Concept must contain @ref constructible<T(const T&)>.
+ * \pre The type stored in @c other must match the type expected by
+ * @c binding.
+ *
+ * \post binding_of(*this) == @c binding
+ *
+ * \throws std::bad_alloc or whatever that the copy
+ * constructor of the contained type throws.
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
+ : table(binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+ /**
+ * Calls a constructor of the contained type. The bindings
+ * will be deduced from the arguments.
+ *
+ * \param arg The arguments to be passed to the underlying constructor.
+ *
+ * \pre @c Concept must contain a matching instance of @ref constructible.
+ * \pre At least one of the arguments must by an @ref any with the
+ * same @c Concept as this.
+ * \pre The bindings of all the arguments that are @ref any's, must
+ * be the same.
+ *
+ * \throws std::bad_alloc or whatever that the
+ * constructor of the contained type throws.
+ */
+ template<class... U>
+ explicit any(U&&... arg);
+
+ /**
+ * Calls a constructor of the contained type.
+ *
+ * \param binding Specifies the bindings of placeholders to actual types.
+ * \param arg The arguments to be passed to the underlying constructor.
+ *
+ * \pre @c Concept must contain a matching instance of @ref constructible.
+ * \pre The contained type of every argument that is an @ref any, must
+ * be the same as that specified by @c binding.
+ *
+ * \post binding_of(*this) == @c binding
+ *
+ * \throws std::bad_alloc or whatever that the
+ * constructor of the contained type throws.
+ */
+ template<class... U>
+ explicit any(const binding<Concept>& binding_arg, U&&... arg)
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(arg...) : 0
+ )(arg...)
+ )
+ {}
+
+#else
+ // construction from a reference
+ any(const any<Concept, T&>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+ any(any<Concept, T&>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+ any(const any<Concept, const T&>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+ any(any<Concept, const T&>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+
+ // disambiguating overloads
+ template<class U, class Map>
+ any(U& data_arg, static_binding<Map>& binding_arg)
+ : table(binding_arg),
+ data(data_arg)
+ {}
+ template<class U, class Map>
+ any(const U& data_arg, static_binding<Map>& binding_arg)
+ : table(binding_arg),
+ data(data_arg)
+ {}
+ template<class U, class Map>
+ any(U& data_arg, const static_binding<Map>& binding_arg)
+ : table(binding_arg),
+ data(data_arg)
+ {}
+ template<class Concept2, class Tag2, class Map>
+ any(any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
+ : table(::boost::type_erasure::detail::access::table(other), binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ template<class Concept2, class Tag2, class Map>
+ any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
+ : table(::boost::type_erasure::detail::access::table(other), binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ template<class Concept2, class Tag2, class Map>
+ any(const any<Concept2, Tag2>& other, static_binding<Map>& binding_arg)
+ : table(::boost::type_erasure::detail::access::table(other), binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ template<class Concept2, class Tag2>
+ any(any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
+ : table(binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ template<class Concept2, class Tag2>
+ any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
+ : table(binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2>& other, binding<Concept>& binding_arg)
+ : table(binding_arg),
+ data(::boost::type_erasure::call(
+ constructible<
+ typename ::boost::remove_const<
+ typename boost::remove_reference<Tag2>::type
+ >::type(const typename boost::remove_reference<Tag2>::type&)
+ >(), other)
+ )
+ {}
+
+ // One argument is a special case. The argument must be an any
+ // and the constructor must be explicit.
+ template<class Tag2>
+ explicit any(const any<Concept, Tag2>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+ template<class Tag2>
+ explicit any(any<Concept, Tag2>& other)
+ : table(::boost::type_erasure::detail::access::table(other)),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(other) : 0
+ ), other)
+ )
+ {}
+
+ explicit any(const binding<Concept>& binding_arg)
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::constructible<T()>()
+ )
+ )
+ {}
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+ template<class R, class... A, class... U>
+ const table_type& _boost_type_erasure_extract_table(
+ ::boost::type_erasure::constructible<R(A...)>*,
+ U&... u)
+ {
+ return *::boost::type_erasure::detail::extract_table(static_cast<void(*)(A...)>(0), u...);
+ }
+
+ template<class U0, class U1, class... U>
+ any(const U0& u0, const U1& u1, const U&... u)
+ : table(
+ _boost_type_erasure_extract_table(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u1, u...) : 0,
+ u0, u1, u...
+ )
+ ),
+ data(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u1, u...) : 0
+ )(u0, u1, u...)
+ )
+ {}
+
+ template<class U0, class U1, class... U>
+ any(U0& u0, U1& u1, U&... u)
+ : table(
+ _boost_type_erasure_extract_table(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u1, u...) : 0,
+ u0, u1, u...
+ )
+ ),
+ data(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u1, u...) : 0
+ )(u0, u1, u...)
+ )
+ {}
+
+ template<class U0, class... U>
+ any(const binding<Concept>& binding_arg, const U0& u0, const U&... u)
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u...) : 0
+ ),
+ u0, u...
+ )
+ )
+ {}
+
+ template<class U0, class... U>
+ any(const binding<Concept>& binding_arg, U0& u0, U&... u)
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u...) : 0
+ ),
+ u0, u...
+ )
+ )
+ {}
+
+ // disambiguate
+ template<class U0, class... U>
+ any(binding<Concept>& binding_arg, U0& u0, U&... u)
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(u0, u...) : 0
+ ),
+ u0, u...
+ )
+ )
+ {}
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/construct.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+#endif
+
+ /**
+ * Assigns to an @ref any.
+ *
+ * If an appropriate overload of @ref assignable is not available
+ * and @ref relaxed_match is in @c Concept, falls back on
+ * constructing from @c other.
+ *
+ * \throws Whatever the assignment operator of the contained
+ * type throws. When falling back on construction,
+ * throws @c std::bad_alloc or whatever the copy
+ * constructor of the contained type throws. In
+ * this case assignment provides the strong exception
+ * guarantee. When calling the assignment operator
+ * of the contained type, the exception guarantee is
+ * whatever the contained type provides.
+ */
+ any& operator=(const any& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+ /**
+ * Assigns to an @ref any.
+ *
+ * If an appropriate overload of @ref assignable is not available
+ * and @ref relaxed_match is in @c Concept, falls back on
+ * constructing from @c other.
+ *
+ * \throws Whatever the assignment operator of the contained
+ * type throws. When falling back on construction,
+ * throws @c std::bad_alloc or whatever the copy
+ * constructor of the contained type throws. In
+ * this case assignment provides the strong exception
+ * guarantee. When calling an assignment operator
+ * of the contained type, the exception guarantee is
+ * whatever the contained type provides.
+ */
+ template<class U>
+ any& operator=(const U& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+ /**
+ * \pre @c Concept includes @c destructible<T>.
+ */
+ ~any()
+ {
+ table.template find<destructible<T> >()(data);
+ }
+private:
+ /** INTERNAL ONLY */
+ void _boost_type_erasure_swap(any& other)
+ {
+ ::std::swap(data, other.data);
+ ::std::swap(table, other.table);
+ }
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_resolve_assign(const Other& other)
+ {
+ _boost_type_erasure_assign_impl(
+ other,
+ false? this->_boost_type_erasure_deduce_assign(
+ ::boost::type_erasure::detail::make_fallback(
+ other,
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(other)
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >()
+ )
+ ) : 0,
+ ::boost::type_erasure::is_relaxed<Concept>()
+ );
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const assignable<T, U>*,
+ ::boost::mpl::false_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const assignable<T, U>*,
+ ::boost::mpl::true_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+ }
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const void*,
+ ::boost::mpl::true_)
+ {
+ any temp(other);
+ _boost_type_erasure_swap(temp);
+ }
+ /** INTERNAL ONLY */
+ template<class Concept2, class Tag2>
+ void _boost_type_erasure_resolve_assign(const any<Concept2, Tag2>& other)
+ {
+ _boost_type_erasure_assign_impl(
+ other,
+ false? this->_boost_type_erasure_deduce_assign(
+ ::boost::type_erasure::detail::make_fallback(
+ other,
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(other)
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >()
+ )
+ ) : 0,
+ false? this->_boost_type_erasure_deduce_constructor(
+ ::boost::type_erasure::detail::make_fallback(
+ other,
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_constructor(other)
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >()
+ )
+ ) : 0,
+ ::boost::type_erasure::is_relaxed<Concept>()
+ );
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const assignable<T, U>*,
+ const void*,
+ ::boost::mpl::false_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const assignable<T, U>*,
+ const void*,
+ ::boost::mpl::true_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class Sig>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const void*,
+ const constructible<Sig>*,
+ ::boost::mpl::true_)
+ {
+ any temp(other);
+ _boost_type_erasure_swap(temp);
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U, class Sig>
+ void _boost_type_erasure_assign_impl(
+ const Other& other,
+ const assignable<T, U>*,
+ const constructible<Sig>*,
+ ::boost::mpl::true_)
+ {
+ if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other))
+ {
+ ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other);
+ }
+ else
+ {
+ any temp(other);
+ _boost_type_erasure_swap(temp);
+ }
+ }
+ friend struct ::boost::type_erasure::detail::access;
+ // The table has to be initialized first for exception
+ // safety in some constructors.
+ table_type table;
+ ::boost::type_erasure::detail::storage data;
+};
+
+template<class Concept, class T>
+class any<Concept, T&> :
+ public ::boost::type_erasure::detail::compute_bases<
+ ::boost::type_erasure::any<Concept, T&>,
+ Concept,
+ T
+ >::type
+{
+ typedef ::boost::type_erasure::binding<Concept> table_type;
+public:
+ /** INTERNAL ONLY */
+ typedef Concept _boost_type_erasure_concept_type;
+ /** INTERNAL ONLY */
+ any(const ::boost::type_erasure::detail::storage& data_arg,
+ const table_type& table_arg)
+ : data(data_arg),
+ table(table_arg)
+ {}
+ /**
+ * Constructs an @ref any from a reference.
+ *
+ * \param arg The object to bind the reference to.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ *
+ * \throws Nothing.
+ */
+ template<class U>
+ explicit any(U& arg
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::mpl::or_<
+ ::boost::is_const<U>,
+ ::boost::type_erasure::detail::is_any<U>
+ >
+ >::type* = 0
+#endif
+ )
+ : table(
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ >()
+ )
+ {
+ data.data = ::boost::addressof(arg);
+ }
+ /**
+ * Constructs an @ref any from a reference.
+ *
+ * \param arg The object to bind the reference to.
+ * \param binding Specifies the actual types that
+ * all the placeholders should bind to.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c Map is an MPL map with an entry for every
+ * placeholder referred to by @c Concept.
+ *
+ * \throws Nothing.
+ */
+ template<class U, class Map>
+ any(U& arg, const static_binding<Map>& binding_arg)
+ : table(binding_arg)
+ {
+ data.data = ::boost::addressof(arg);
+ }
+ /**
+ * Constructs an @ref any from another reference.
+ *
+ * \param other The reference to copy.
+ *
+ * \throws Nothing.
+ */
+ any(const any& other)
+ : data(other.data),
+ table(other.table)
+ {}
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ any(any& other)
+ : data(other.data),
+ table(other.table)
+ {}
+#endif
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ *
+ * \throws Nothing.
+ */
+ any(any<Concept, T>& other)
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other))
+ {}
+ /**
+ * Constructs an @ref any from another reference.
+ *
+ * \param other The reference to copy.
+ *
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ * \pre After substituting @c T for @c Tag2, the requirements of
+ * @c Concept2 must be a superset of of the requirements of
+ * @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2&>& other
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::mpl::or_<
+ ::boost::is_same<Concept, Concept2>,
+ ::boost::is_const<Tag2>
+ >
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(
+ ::boost::type_erasure::detail::access::table(other),
+ ::boost::mpl::map<
+ ::boost::mpl::pair<
+ T,
+ Tag2
+ >
+ >())
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ *
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ * \pre After substituting @c T for @c Tag2, the requirements of
+ * @c Concept2 must be a superset of of the requirements of
+ * @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2>
+ any(any<Concept2, Tag2>& other
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::mpl::or_<
+ ::boost::is_same<Concept, Concept2>,
+ ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
+ >
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(
+ ::boost::type_erasure::detail::access::table(other),
+ ::boost::mpl::map<
+ ::boost::mpl::pair<
+ T,
+ typename ::boost::remove_reference<Tag2>::type
+ >
+ >())
+ {}
+ /**
+ * Constructs an @ref any from another reference.
+ *
+ * \param other The reference to copy.
+ * \param binding Specifies the mapping between the two concepts.
+ *
+ * \pre @c Map must be an MPL map with keys for all the placeholders
+ * used by @c Concept and values for the corresponding
+ * placeholders in @c Concept2.
+ * \pre After substituting placeholders according to @c Map, the
+ * requirements of @c Concept2 must be a superset of of the
+ * requirements of @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2, class Map>
+ any(const any<Concept2, Tag2&>& other, const static_binding<Map>& binding_arg
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if< ::boost::is_const<Tag2> >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other), binding_arg)
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ * \param binding Specifies the mapping between the two concepts.
+ *
+ * \pre @c Map must be an MPL map with keys for all the placeholders
+ * used by @c Concept and values for the corresponding
+ * placeholders in @c Concept2.
+ * \pre After substituting placeholders according to @c Map, the
+ * requirements of @c Concept2 must be a superset of of the
+ * requirements of @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2, class Map>
+ any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other), binding_arg)
+ {}
+ /**
+ * Constructs an @ref any from another reference.
+ *
+ * \param other The reference to copy.
+ * \param binding Specifies the bindings of placeholders to actual types.
+ *
+ * \pre The type stored in @c other must match the type expected by
+ * @c binding.
+ *
+ * \post binding_of(*this) == @c binding
+ *
+ * \throws Nothing.
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2&>& other, const binding<Concept>& binding_arg
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::is_const<Tag2>
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(binding_arg)
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ * \param binding Specifies the bindings of placeholders to actual types.
+ *
+ * \pre The type stored in @c other must match the type expected by
+ * @c binding.
+ *
+ * \post binding_of(*this) == @c binding
+ *
+ * \throws Nothing.
+ */
+ template<class Concept2, class Tag2>
+ any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::is_const<typename ::boost::remove_reference<Tag2>::type>
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(binding_arg)
+ {}
+private:
+ friend struct ::boost::type_erasure::detail::access;
+ ::boost::type_erasure::detail::storage data;
+ table_type table;
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template<class Concept, class T>
+class any<Concept, const T&> :
+ public ::boost::type_erasure::detail::compute_bases<
+ ::boost::type_erasure::any<Concept, const T&>,
+ Concept,
+ T
+ >::type
+{
+ typedef ::boost::type_erasure::binding<Concept> table_type;
+public:
+ /** INTERNAL ONLY */
+ typedef Concept _boost_type_erasure_concept_type;
+ /** INTERNAL ONLY */
+ any(const ::boost::type_erasure::detail::storage& data_arg,
+ const table_type& table_arg)
+ : data(data_arg),
+ table(table_arg)
+ {}
+ /**
+ * Constructs an @ref any from a reference.
+ *
+ * \param arg The object to bind the reference to.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ *
+ * \throws Nothing.
+ */
+ template<class U>
+ explicit any(const U& arg)
+ : table(
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ >()
+ )
+ {
+ data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
+ }
+ /**
+ * Constructs an @ref any from a reference.
+ *
+ * \param arg The object to bind the reference to.
+ * \param binding Specifies the actual types that
+ * all the placeholders should bind to.
+ *
+ * \pre @c U is a model of @c Concept.
+ * \pre @c Map is an MPL map with an entry for every
+ * placeholder referred to by @c Concept.
+ *
+ * \throws Nothing.
+ */
+ template<class U, class Map>
+ any(const U& arg, const static_binding<Map>& binding_arg)
+ : table(binding_arg)
+ {
+ data.data = const_cast<void*>(static_cast<const void*>(::boost::addressof(arg)));
+ }
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The reference to copy.
+ *
+ * \throws Nothing.
+ */
+ any(const any& other)
+ : data(other.data),
+ table(other.table)
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The reference to copy.
+ *
+ * \throws Nothing.
+ */
+ any(const any<Concept, T&>& other)
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other))
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ *
+ * \throws Nothing.
+ */
+ any(const any<Concept, T>& other)
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other))
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ *
+ * \pre @c Concept must not refer to any placeholder besides @c T.
+ * \pre After substituting @c T for @c Tag2, the requirements of
+ * @c Concept2 must be a superset of of the requirements of
+ * @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2>& other
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if< ::boost::is_same<Concept, Concept2> >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(
+ ::boost::type_erasure::detail::access::table(other),
+ ::boost::mpl::map<
+ ::boost::mpl::pair<
+ T,
+ typename ::boost::remove_const<
+ typename ::boost::remove_reference<Tag2>::type
+ >::type
+ >
+ >())
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ * \param binding Specifies the mapping between the two concepts.
+ *
+ * \pre @c Map must be an MPL map with keys for all the placeholders
+ * used by @c Concept and values for the corresponding
+ * placeholders in @c Concept2.
+ * \pre After substituting placeholders according to @c Map, the
+ * requirements of @c Concept2 must be a superset of of the
+ * requirements of @c Concept.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Tag2, class Map>
+ any(const any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg)
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(::boost::type_erasure::detail::access::table(other), binding_arg)
+ {}
+ /**
+ * Constructs an @ref any from another @ref any.
+ *
+ * \param other The object to bind the reference to.
+ * \param binding Specifies the bindings of placeholders to actual types.
+ *
+ * \pre The type stored in @c other must match the type expected by
+ * @c binding.
+ *
+ * \post binding_of(*this) == @c binding
+ *
+ * \throws Nothing.
+ */
+ template<class Concept2, class Tag2>
+ any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg)
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(binding_arg)
+ {}
+private:
+ friend struct ::boost::type_erasure::detail::access;
+ ::boost::type_erasure::detail::storage data;
+ table_type table;
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/any_cast.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/any_cast.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,183 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_ANY_CAST_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_ANY_CAST_HPP_INCLUDED
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/detail/access.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+namespace detail {
+
+template<class Concept, class T>
+void* get_pointer(::boost::type_erasure::any<Concept, T>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class Concept, class T>
+const void* get_pointer(const ::boost::type_erasure::any<Concept, T>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class Concept, class T>
+void* get_pointer(::boost::type_erasure::any<Concept, T&>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class Concept, class T>
+void* get_pointer(const ::boost::type_erasure::any<Concept, T&>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class Concept, class T>
+const void* get_pointer(::boost::type_erasure::any<Concept, const T&>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class Concept, class T>
+const void* get_pointer(const ::boost::type_erasure::any<Concept, const T&>& arg)
+{
+ return ::boost::type_erasure::detail::access::data(arg).data;
+}
+
+template<class T, class Concept, class Tag>
+bool check_any_cast(const any<Concept, Tag>&, ::boost::mpl::true_)
+{
+ return true;
+}
+
+template<class T, class Concept, class Tag>
+bool check_any_cast(const any<Concept, Tag>& arg, ::boost::mpl::false_)
+{
+ typedef typename ::boost::remove_cv<
+ typename ::boost::remove_reference<Tag>::type
+ >::type tag_type;
+ return ::boost::type_erasure::detail::access::table(arg)
+ .template find<typeid_<tag_type> >()() == typeid(T);
+}
+
+template<class T, class Concept, class Tag>
+bool check_any_cast(const any<Concept, Tag>& arg)
+{
+ return ::boost::type_erasure::detail::check_any_cast<T>(
+ arg, ::boost::is_void<typename ::boost::remove_reference<T>::type>());
+}
+
+}
+
+/**
+ * Exception thrown when an any_cast to a reference or value fails.
+ */
+class bad_any_cast : public std::bad_cast {};
+
+/**
+ * Attempts to extract the object that @c arg holds.
+ * If casting to a pointer fails, @ref any_cast returns
+ * a null pointer. Casting to @c void* always succeeds
+ * and returns the address of stored object.
+ *
+ * \pre if @c arg is a pointer, @c T must be a pointer type.
+ * \pre @c Concept must contain @ref typeid_<tt>&lt;Tag&gt;</tt>.
+ *
+ * \throws bad_any_cast if @c arg doesn't contain
+ * an object of type @c T and we're casting
+ * to a value or reference.
+ */
+template<class T, class Concept, class Tag>
+T any_cast(any<Concept, Tag>& arg)
+{
+ if(::boost::type_erasure::detail::check_any_cast<T>(arg)) {
+ return *static_cast<
+ typename ::boost::remove_reference<
+ typename ::boost::add_const<T>::type
+ >::type*
+ >(::boost::type_erasure::detail::get_pointer(arg));
+ } else {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_any_cast());
+ }
+}
+
+/** \overload */
+template<class T, class Concept, class Tag>
+T any_cast(const any<Concept, Tag>& arg)
+{
+ typedef typename ::boost::remove_cv<
+ typename ::boost::remove_reference<Tag>::type
+ >::type tag_type;
+ if(::boost::type_erasure::detail::check_any_cast<T>(arg)) {
+ return *static_cast<
+ typename ::boost::remove_reference<
+ typename ::boost::add_const<T>::type
+ >::type*
+ >(::boost::type_erasure::detail::get_pointer(arg));
+ } else {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_any_cast());
+ }
+}
+
+/** \overload */
+template<class T, class Concept, class Tag>
+T any_cast(any<Concept, Tag>* arg)
+{
+ BOOST_MPL_ASSERT((::boost::is_pointer<T>));
+ typedef typename ::boost::remove_cv<
+ typename ::boost::remove_reference<Tag>::type
+ >::type tag_type;
+ if(::boost::type_erasure::detail::check_any_cast<
+ typename ::boost::remove_pointer<T>::type>(*arg)) {
+ return static_cast<
+ typename ::boost::remove_pointer<T>::type*>(
+ ::boost::type_erasure::detail::get_pointer(*arg));
+ } else {
+ return 0;
+ }
+}
+
+/** \overload */
+template<class T, class Concept, class Tag>
+T any_cast(const any<Concept, Tag>* arg)
+{
+ BOOST_MPL_ASSERT((::boost::is_pointer<T>));
+ typedef typename ::boost::remove_cv<
+ typename ::boost::remove_reference<Tag>::type
+ >::type tag_type;
+ if(::boost::type_erasure::detail::check_any_cast<
+ typename ::boost::remove_pointer<T>::type>(*arg)) {
+ return static_cast<
+ typename ::boost::remove_pointer<T>::type*>(
+ ::boost::type_erasure::detail::get_pointer(*arg));
+ } else {
+ return 0;
+ }
+}
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/binding.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/binding.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,166 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_BINDING_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/type_erasure/static_binding.hpp>
+#include <boost/type_erasure/detail/adapt_to_vtable.hpp>
+#include <boost/type_erasure/detail/rebind_placeholders.hpp>
+#include <boost/type_erasure/detail/vtable.hpp>
+#include <boost/type_erasure/detail/normalize.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * Stores the binding of a @c Concept to a set of actual types.
+ * @c Concept is interpreted in the same way as with @ref any.
+ */
+template<class Concept>
+class binding
+{
+ typedef typename ::boost::type_erasure::detail::normalize_concept<
+ Concept>::type normalized;
+ typedef typename ::boost::mpl::transform<normalized,
+ ::boost::type_erasure::detail::maybe_adapt_to_vtable< ::boost::mpl::_1>
+ >::type actual_concept;
+ typedef typename ::boost::type_erasure::detail::make_vtable<
+ actual_concept>::type table_type;
+public:
+
+ /**
+ * \pre @c Map must be an MPL map with an entry for each placeholder
+ * referred to by @c Concept.
+ *
+ * \throws Nothing.
+ */
+ template<class Map>
+ explicit binding(const Map&)
+ {
+ set<Map>();
+ }
+
+ /**
+ * \pre @c Map must be an MPL map with an entry for each placeholder
+ * referred to by @c Concept.
+ *
+ * \throws Nothing.
+ */
+ template<class Map>
+ binding(const static_binding<Map>&)
+ {
+ set<Map>();
+ }
+
+ /**
+ * Converts from another set of bindings.
+ *
+ * \pre Map must be an MPL map with an entry for each placeholder
+ * referred to by @c Concept. The mapped type should be the
+ * corresponding placeholder in Concept2.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Map>
+ binding(const binding<Concept2>& other, const Map&)
+ : manager(new table_type)
+ {
+ manager->template convert_from<Map>(*other.table);
+ table = manager.get();
+ }
+
+ /**
+ * Converts from another set of bindings.
+ *
+ * \pre Map must be an MPL map with an entry for each placeholder
+ * referred to by @c Concept. The mapped type should be the
+ * corresponding placeholder in Concept2.
+ *
+ * \throws std::bad_alloc
+ */
+ template<class Concept2, class Map>
+ binding(const binding<Concept2>& other, const static_binding<Map>&)
+ : manager(new table_type)
+ {
+ manager->template convert_from<Map>(*other.table);
+ table = manager.get();
+ }
+
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+
+ /** Special case optimization. */
+ template<class Map>
+ binding(const binding& other, const Map&)
+ : table(other.table)
+ {
+ table_type t;
+ t.template convert_from<Map>(*other.table);
+ }
+
+ /** Special case optimization. */
+ template<class Map>
+ binding(const binding& other, const static_binding<Map>&)
+ : table(other.table)
+ {
+ table_type t;
+ t.template convert_from<Map>(*other.table);
+ }
+
+#endif
+
+ /**
+ * \return true iff the sets of types that the placeholders
+ * bind to are the same for both arguments.
+ *
+ * \throws Nothing.
+ */
+ friend bool operator==(const binding& lhs, const binding& rhs)
+ { return *lhs.table == *rhs.table; }
+
+ /**
+ * \return true iff the arguments do not map to identical
+ * sets of types.
+ *
+ * \throws Nothing.
+ */
+ friend bool operator!=(const binding& lhs, const binding& rhs)
+ { return !(lhs == rhs); }
+
+ /** INTERNAL ONLY */
+ template<class T>
+ typename T::type find() const { return table->lookup((T*)0); }
+private:
+ template<class C2>
+ friend class binding;
+ /** INTERNAL ONLY */
+ template<class Bindings>
+ void set()
+ {
+ table = &::boost::type_erasure::detail::make_vtable_init<
+ typename ::boost::mpl::transform<actual_concept,
+ ::boost::type_erasure::detail::rebind_placeholders<
+ ::boost::mpl::_1, Bindings>
+ >::type,
+ table_type
+ >::type::value;
+ }
+ const table_type* table;
+ ::boost::shared_ptr<table_type> manager;
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/binding_of.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/binding_of.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,35 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_BINDING_OF_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_BINDING_OF_HPP_INCLUDED
+
+#include <boost/type_erasure/detail/access.hpp>
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/binding.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * \return The type bindings of an @ref any.
+ *
+ * \throws Nothing.
+ */
+template<class Concept, class T>
+const binding<Concept>& binding_of(const any<Concept, T>& arg)
+{
+ return ::boost::type_erasure::detail::access::table(arg);
+}
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/builtin.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/builtin.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,98 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_BUILTIN_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_BUILTIN_HPP_INCLUDED
+
+#include <boost/mpl/vector.hpp>
+#include <boost/type_erasure/detail/storage.hpp>
+#include <boost/type_erasure/placeholder.hpp>
+#include <boost/type_erasure/constructible.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <typeinfo>
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * The @ref destructible concept enables forwarding to
+ * the destructor of the contained type. This is required
+ * whenever an @ref any is created by value.
+ *
+ * \note The @ref destructible concept rarely needs to
+ * be specified explicitly, because it is included in
+ * the @ref copy_constructible concept.
+ */
+template<class T = _self>
+struct destructible
+{
+ /** INTERNAL ONLY */
+ typedef void (*type)(detail::storage&);
+ /** INTERNAL ONLY */
+ static void value(detail::storage& arg)
+ {
+ delete static_cast<T*>(arg.data);
+ }
+};
+
+/**
+ * The @ref copy_constructible concept allows objects to
+ * be copied and destroyed.
+ *
+ * \note This concept is defined to match C++ 2003,
+ * [lib.copyconstructible]. It is not equivalent to
+ * the concept of the same name in C++0x.
+ */
+template<class T = _self>
+struct copy_constructible :
+ ::boost::mpl::vector<constructible<T(const T&)>, destructible<T> >
+{};
+
+/**
+ * Enables assignment of @ref any types.
+ */
+template<class T = _self, class U = T>
+struct assignable
+{
+ static void apply(T& dst, const U& src) { dst = src; }
+};
+
+/** INTERNAL ONLY */
+template<class T, class U, class Base>
+struct concept_interface<assignable<T, U>, Base, T> : Base
+{
+ using Base::_boost_type_erasure_deduce_assign;
+ assignable<T, U>* _boost_type_erasure_deduce_assign(
+ typename ::boost::type_erasure::rebind_any<Base, const U&>::type)
+ {
+ return 0;
+ }
+};
+
+/**
+ * Enables runtime type information. This is required
+ * to use @ref any_cast or @ref typeid_of.
+ */
+template<class T = _self>
+struct typeid_
+{
+ /** INTERNAL ONLY */
+ typedef const std::type_info& (*type)();
+ /** INTERNAL ONLY */
+ static const std::type_info& value()
+ {
+ return typeid(T);
+ }
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/call.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/call.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,539 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_CALL_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CALL_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/inc.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/type_erasure/detail/access.hpp>
+#include <boost/type_erasure/detail/adapt_to_vtable.hpp>
+#include <boost/type_erasure/detail/extract_concept.hpp>
+#include <boost/type_erasure/detail/get_signature.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/concept_of.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/require_match.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class Placeholder>
+class any;
+
+template<class Concept>
+class binding;
+
+namespace detail {
+
+template<class T>
+struct is_placeholder_arg :
+ ::boost::type_erasure::is_placeholder<
+ typename ::boost::remove_cv<
+ typename ::boost::remove_reference<T>::type
+ >::type
+ >
+{};
+
+template<class T, class Table>
+int maybe_get_table(const T& arg, const Table*& table, boost::mpl::true_)
+{
+ if(table == 0) {
+ table = &::boost::type_erasure::detail::access::table(arg);
+ }
+ return 0;
+}
+
+template<class T, class Table>
+int maybe_get_table(const T&, const Table*&, boost::mpl::false_) { return 0; }
+
+template<class T>
+::boost::type_erasure::detail::storage& convert_arg(any_base<T>& arg, boost::mpl::true_)
+{
+ return ::boost::type_erasure::detail::access::data(arg);
+}
+
+template<class Concept, class T>
+const ::boost::type_erasure::detail::storage&
+convert_arg(any_base<any<Concept, const T&> >& arg, boost::mpl::true_)
+{
+ return ::boost::type_erasure::detail::access::data(arg);
+}
+
+template<class T>
+const ::boost::type_erasure::detail::storage&
+convert_arg(const any_base<T>& arg, boost::mpl::true_)
+{
+ return ::boost::type_erasure::detail::access::data(arg);
+}
+
+template<class T>
+T& convert_arg(T& arg, boost::mpl::false_) { return arg; }
+
+}
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+/**
+ * Dispatches a type erased function.
+ *
+ * If @c binding is not specified, it will be deduced from
+ * the arguments.
+ *
+ * \pre The type of every @ref any in @c args must match that
+ * specified by @c binding.
+ *
+ * \return The result of the operation. If the
+ * result type is a placeholder, the result will be
+ * converted to the appropriate @ref any type.
+ */
+template<class Concept, class Op, class... U>
+typename ::boost::type_erasure::detail::call_impl<Sig, U..., Concept>::type
+call(const binding<Concept>& binding_arg, const Op&, U&&... args);
+
+/**
+ * \overload
+ */
+template<class Op, class... U>
+typename ::boost::type_erasure::detail::call_impl<Sig, U...>::type
+call(const Op&, U&&... args);
+
+#else
+
+namespace detail {
+
+template<class Sig, class Args, class Concept = void>
+struct call_impl;
+
+template<class Op, class Args, class Concept = void>
+struct call_result :
+ call_impl<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ Args,
+ Concept>
+{};
+
+template<class C1, class Args, class Concept>
+struct call_result<
+ ::boost::type_erasure::binding<C1>,
+ Args,
+ Concept
+>
+{};
+
+}
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+namespace detail {
+
+template<class... T>
+void ignore(const T&...) {}
+
+template<class R, class... T, class... U>
+const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::extract_concept<void(T...), U...>::type>*
+extract_table(R(*)(T...), const U&... arg)
+{
+ const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::extract_concept<
+ void(T...), U...>::type>* result = 0;
+
+ // the order that we run maybe_get_table in doesn't matter
+ ignore(::boost::type_erasure::detail::maybe_get_table(
+ arg,
+ result,
+ ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
+
+ BOOST_ASSERT(result != 0);
+ return result;
+}
+
+template<class Sig, class Args, class Concept, bool ReturnsAny>
+struct call_impl_dispatch;
+
+template<class R, class... T, class... U, class Concept>
+struct call_impl_dispatch<R(T...), void(U...), Concept, false>
+{
+ typedef R type;
+ template<class F>
+ static R apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
+ {
+ return table->template find<F>()(
+ ::boost::type_erasure::detail::convert_arg(
+ arg,
+ ::boost::type_erasure::detail::is_placeholder_arg<T>())...);
+ }
+};
+
+template<class R, class... T, class... U, class Concept>
+struct call_impl_dispatch<R(T...), void(U...), Concept, true>
+{
+ typedef ::boost::type_erasure::any<Concept, R> type;
+ template<class F>
+ static type apply(const ::boost::type_erasure::binding<Concept>* table, U... arg)
+ {
+ return type(table->template find<F>()(
+ ::boost::type_erasure::detail::convert_arg(
+ arg,
+ ::boost::type_erasure::detail::is_placeholder_arg<T>())...), *table);
+ }
+};
+
+template<class R, class... T, class... U, class Concept>
+struct call_impl<R(T...), void(U...), Concept> :
+ ::boost::type_erasure::detail::call_impl_dispatch<
+ R(T...),
+ void(U...),
+ Concept,
+ ::boost::type_erasure::detail::is_placeholder_arg<R>::value
+ >
+{
+};
+
+template<class R, class... T, class... U>
+struct call_impl<R(T...), void(U&...), void> :
+ ::boost::type_erasure::detail::call_impl_dispatch<
+ R(T...),
+ void(U&...),
+ typename ::boost::type_erasure::detail::extract_concept<
+ void(T...),
+ U...
+ >::type,
+ ::boost::type_erasure::detail::is_placeholder_arg<R>::value
+ >
+{
+};
+
+}
+
+template<
+ class Concept,
+ class Op,
+ class... U
+>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(U&...),
+ Concept
+>::type
+unchecked_call(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op&,
+ U&... arg)
+{
+ return ::boost::type_erasure::detail::call_impl<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ void(U&...),
+ Concept
+ >::template apply<
+ typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
+ >(&table, arg...);
+}
+
+template<class Concept, class Op, class... U>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(U&...),
+ Concept
+>::type
+call(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& f,
+ U&... arg)
+{
+ ::boost::type_erasure::require_match(table, f, arg...);
+ return ::boost::type_erasure::unchecked_call(table, f, arg...);
+}
+
+template<class Op, class... U>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(U&...)
+>::type
+unchecked_call(
+ const Op&,
+ U&... arg)
+{
+ return ::boost::type_erasure::detail::call_impl<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ void(U&...)
+ >::template apply<
+ typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
+ >(::boost::type_erasure::detail::extract_table(
+ static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...),
+ arg...);
+}
+
+template<class Op, class... U>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(U&...)
+>::type
+call(
+ const Op& f,
+ U&... arg)
+{
+ ::boost::type_erasure::require_match(f, arg...);
+ return ::boost::type_erasure::unchecked_call(f, arg...);
+}
+
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/call.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+#endif
+
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_CONVERT_ARG(z, n, data) \
+ ::boost::type_erasure::detail::convert_arg( \
+ BOOST_PP_CAT(arg, n), \
+ ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>())
+
+#define BOOST_TYPE_ERASURE_GET_TABLE(z, n, data) \
+ ::boost::type_erasure::detail::maybe_get_table( \
+ BOOST_PP_CAT(arg, n), \
+ result, \
+ ::boost::type_erasure::detail::is_placeholder_arg<BOOST_PP_CAT(T, n)>());
+
+namespace detail {
+
+#if N != 0
+
+template<
+ class R,
+ BOOST_PP_ENUM_PARAMS(N, class T),
+ BOOST_PP_ENUM_PARAMS(N, class U)>
+const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
+ BOOST_PP_ENUM_PARAMS(N, T),
+ BOOST_PP_ENUM_PARAMS(N, U)>::type>*
+BOOST_PP_CAT(extract_table, N)(R(*)(BOOST_PP_ENUM_PARAMS(N, T)), BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &arg))
+{
+ const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
+ BOOST_PP_ENUM_PARAMS(N, T),
+ BOOST_PP_ENUM_PARAMS(N, U)>::type>* result = 0;
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_TABLE, ~)
+ BOOST_ASSERT(result != 0);
+ return result;
+}
+
+#endif
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
+ class Concept
+#if N != 0
+ = typename ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
+ BOOST_PP_ENUM_PARAMS(N, T),
+ BOOST_PP_ENUM_PARAMS(N, U)
+ >::type
+#endif
+ ,
+ bool ReturnsAny = ::boost::type_erasure::detail::is_placeholder_arg<R>::value>
+struct BOOST_PP_CAT(call_impl, N);
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
+ class Concept
+>
+struct BOOST_PP_CAT(call_impl, N)<
+ R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
+ Concept,
+ false
+>
+{
+ typedef R type;
+ template<class F>
+ static R apply(const ::boost::type_erasure::binding<Concept>* table
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ {
+ return table->template find<F>()(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~));
+ }
+};
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
+ class Concept
+>
+struct BOOST_PP_CAT(call_impl, N)<
+ R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, U),
+ Concept,
+ true
+>
+{
+ typedef ::boost::type_erasure::any<Concept, R> type;
+ template<class F>
+ static type apply(const ::boost::type_erasure::binding<Concept>* table
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+ {
+ return type(table->template find<F>()(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONVERT_ARG, ~)), *table);
+ }
+};
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U),
+ class Concept
+>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)), Concept>
+ : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U), Concept>
+{};
+
+#if N != 0
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))>
+ : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
+{};
+
+#endif
+
+}
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ Concept
+>::type
+unchecked_call(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op&
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ return ::boost::type_erasure::detail::call_impl<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ Concept
+ >::template apply<
+ typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
+ >(&table BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)),
+ Concept
+>::type
+call(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& f
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ ::boost::type_erasure::require_match(table, f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ return ::boost::type_erasure::unchecked_call(table, f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#if N != 0
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+>::type
+unchecked_call(
+ const Op&
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ return ::boost::type_erasure::detail::call_impl<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+ >::template apply<
+ typename ::boost::type_erasure::detail::adapt_to_vtable<Op>::type
+ >(
+ ::boost::type_erasure::detail::BOOST_PP_CAT(extract_table, N)(
+ (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0,
+ BOOST_PP_ENUM_PARAMS(N, arg))
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, arg)
+ );
+}
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+typename ::boost::type_erasure::detail::call_result<
+ Op,
+ void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+>::type
+call(
+ const Op& f
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ ::boost::type_erasure::require_match(f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ return ::boost::type_erasure::unchecked_call(f BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#endif
+
+#undef BOOST_TYPE_ERASURE_GET_TABLE
+#undef BOOST_TYPE_ERASURE_CONVERT_ARG
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/callable.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/callable.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,360 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_CALLABLE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CALLABLE_HPP_INCLUDED
+
+#include <boost/utility/declval.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * The @ref callable concept allows an @ref any to hold function objects.
+ * @c Sig is interpreted in the same way as for Boost.Function.
+ * @c F must be a @ref placeholder.
+ *
+ * Multiple instances of @ref callable can be used
+ * simultaneously. Overload resolution works normally.
+ * Note that unlike Boost.Function, @ref callable
+ * does not provide result_type. It does, however,
+ * support @c boost::result_of.
+ */
+template<class Sig, class F = _self>
+struct callable {};
+
+namespace detail {
+
+template<class Sig>
+struct result_of_callable;
+
+}
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<class R, class... T, class F>
+struct callable<R(T...), F>
+{
+ static R apply(F& f, T... arg)
+ {
+ return f(arg...);
+ }
+};
+
+template<class... T, class F>
+struct callable<void(T...), F>
+{
+ static void apply(F& f, T... arg)
+ {
+ f(arg...);
+ }
+};
+
+template<class R, class F, class Base, class Enable, class... T>
+struct concept_interface<callable<R(T...), F>, Base, F, Enable>
+ : Base
+{
+ template<class Sig>
+ struct result :
+ ::boost::type_erasure::detail::result_of_callable<Sig>
+ {};
+ typedef void _boost_type_erasure_is_callable;
+ typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[1];
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type...);
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::rebind_any<Base, T>::type... arg)
+ {
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this, arg...);
+ }
+};
+
+template<class R, class F, class Base, class Enable, class... T>
+struct concept_interface<callable<R(T...), const F>, Base, F, Enable>
+ : Base
+{
+ template<class Sig>
+ struct result :
+ ::boost::type_erasure::detail::result_of_callable<Sig>
+ {};
+ typedef void _boost_type_erasure_is_callable;
+ typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[1];
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type...) const;
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator()(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type... arg) const
+ {
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this, arg...);
+ }
+};
+
+template<class R, class F, class Base, class... T>
+struct concept_interface<
+ callable<R(T...), F>,
+ Base,
+ F,
+ typename Base::_boost_type_erasure_is_callable
+>
+ : Base
+{
+ typedef typename ::boost::mpl::push_back<
+ typename Base::_boost_type_erasure_callable_results,
+ R
+ >::type _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[
+ ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
+ using Base::_boost_type_erasure_deduce_callable;
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type...);
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::rebind_any<Base, T>::type... arg)
+ {
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this, arg...);
+ }
+};
+
+template<class R, class F, class Base, class... T>
+struct concept_interface<
+ callable<R(T...), const F>,
+ Base,
+ F,
+ typename Base::_boost_type_erasure_is_callable
+>
+ : Base
+{
+ typedef typename ::boost::mpl::push_back<
+ typename Base::_boost_type_erasure_callable_results,
+ R
+ >::type _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[
+ ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
+ using Base::_boost_type_erasure_deduce_callable;
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type...) const;
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::rebind_any<Base, T>::type... arg) const
+ {
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this, arg...);
+ }
+};
+
+namespace detail {
+
+template<class This, class... T>
+struct result_of_callable<This(T...)>
+{
+ typedef typename ::boost::mpl::at_c<
+ typename This::_boost_type_erasure_callable_results,
+ sizeof(::boost::declval<This>().
+ _boost_type_erasure_deduce_callable(::boost::declval<T>()...)) - 1
+ >::type type;
+};
+
+}
+
+#else
+
+/** INTERNAL ONLY */
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/callable.hpp>
+/** INTERNAL ONLY */
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_DEC(BOOST_TYPE_ERASURE_MAX_ARITY))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+#define BOOST_TYPE_ERASURE_DECLVAL(z, n, data) ::boost::declval<BOOST_PP_CAT(T, n)>()
+
+#define BOOST_TYPE_ERASURE_REBIND(z, n, data)\
+ typename ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(T, n)>::type BOOST_PP_CAT(arg, n)
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F>
+struct callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>
+{
+ static R apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
+ {
+ return f(BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+};
+
+template<BOOST_PP_ENUM_PARAMS(N, class T) BOOST_PP_COMMA_IF(N) class F>
+struct callable<void(BOOST_PP_ENUM_PARAMS(N, T)), F>
+{
+ static void apply(F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, T, arg))
+ {
+ f(BOOST_PP_ENUM_PARAMS(N, arg));
+ }
+};
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
+struct concept_interface<
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
+ Base,
+ F,
+ Enable
+>
+ : Base
+{
+ template<class Sig>
+ struct result :
+ ::boost::type_erasure::detail::result_of_callable<Sig>
+ {};
+ typedef void _boost_type_erasure_is_callable;
+ typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[1];
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
+ {
+ return ::boost::type_erasure::call(
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
+ *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ }
+};
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base, class Enable>
+struct concept_interface<
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
+ Base,
+ F,
+ Enable
+>
+ : Base
+{
+ template<class Sig>
+ struct result :
+ ::boost::type_erasure::detail::result_of_callable<Sig>
+ {};
+ typedef void _boost_type_erasure_is_callable;
+ typedef ::boost::mpl::vector<R> _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[1];
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
+ {
+ return ::boost::type_erasure::call(
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
+ *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ }
+};
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
+struct concept_interface<
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>,
+ Base,
+ F,
+ typename Base::_boost_type_erasure_is_callable
+>
+ : Base
+{
+ typedef typename ::boost::mpl::push_back<
+ typename Base::_boost_type_erasure_callable_results,
+ R
+ >::type _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[
+ ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
+ using Base::_boost_type_erasure_deduce_callable;
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~));
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~))
+ {
+ return ::boost::type_erasure::call(
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), F>(),
+ *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ }
+};
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class F, class Base>
+struct concept_interface<
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>,
+ Base,
+ F,
+ typename Base::_boost_type_erasure_is_callable
+>
+ : Base
+{
+ typedef typename ::boost::mpl::push_back<
+ typename Base::_boost_type_erasure_callable_results,
+ R
+ >::type _boost_type_erasure_callable_results;
+ typedef char (&_boost_type_erasure_callable_size)[
+ ::boost::mpl::size<_boost_type_erasure_callable_results>::value];
+ using Base::_boost_type_erasure_deduce_callable;
+ _boost_type_erasure_callable_size
+ _boost_type_erasure_deduce_callable(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const;
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, ~)) const
+ {
+ return ::boost::type_erasure::call(
+ callable<R(BOOST_PP_ENUM_PARAMS(N, T)), const F>(),
+ *this BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+ }
+};
+
+namespace detail {
+
+template<class This BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct result_of_callable<This(BOOST_PP_ENUM_PARAMS(N, T))>
+{
+ typedef typename ::boost::mpl::at_c<
+ typename This::_boost_type_erasure_callable_results,
+ sizeof(::boost::declval<This>().
+ _boost_type_erasure_deduce_callable(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_DECLVAL, ~))) - 1
+ >::type type;
+};
+
+}
+
+#undef BOOST_TYPE_ERASURE_DECLVAL
+#undef BOOST_TYPE_ERASURE_REBIND
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/check_match.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/check_match.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,265 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_CHECK_MATCH_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CHECK_MATCH_HPP_INCLUDED
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/type_erasure/detail/extract_concept.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/detail/access.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class T>
+struct typeid_;
+
+template<class Concept>
+class binding;
+
+namespace detail {
+
+template<class P, class T, class Table>
+bool maybe_check_table(const T& arg, const Table*& table, boost::mpl::true_)
+{
+ if(table == 0) {
+ table = &::boost::type_erasure::detail::access::table(arg);
+ return true;
+ } else {
+ return table->template find< ::boost::type_erasure::typeid_<P> >()() ==
+ ::boost::type_erasure::detail::access::table(arg).
+ template find< ::boost::type_erasure::typeid_<P> >()();
+ }
+}
+
+template<class P, class T, class Table>
+bool maybe_check_table(const T&, const Table*&, boost::mpl::false_)
+{
+ return true;
+}
+
+template<class Concept, class T>
+struct should_check :
+ boost::mpl::and_<
+ ::boost::type_erasure::is_placeholder<T>,
+ ::boost::type_erasure::is_relaxed<Concept>
+ >
+{};
+
+}
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+/**
+ * If @ref relaxed_match is in @c Concept, checks whether the
+ * arguments to @c f match the types specified by
+ * @c binding. If @ref relaxed_match is not in @c Concept,
+ * returns true. If @c binding is not specified, it will
+ * be deduced from the arguments.
+ */
+template<class Concept, class Op, class... U>
+bool check_match(const binding<Concept>& binding_arg, const Op& f, U&&... args);
+
+/**
+ * \overload
+ */
+template<class Op, class... U>
+bool check_match(const Op& f, U&&... args);
+
+#else
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+namespace detail {
+
+template<class Concept>
+bool check_table(const ::boost::type_erasure::binding<Concept>* t, void(*)())
+{
+ return true;
+}
+
+template<class Concept, class R, class T0, class... T, class U0, class... U>
+bool check_table(
+ const ::boost::type_erasure::binding<Concept>* t,
+ R(*)(T0, T...),
+ const U0& arg0,
+ const U&... arg)
+{
+ typedef typename ::boost::remove_cv<
+ typename ::boost::remove_reference<T0>::type
+ >::type t0;
+ if(!::boost::type_erasure::detail::maybe_check_table<t0>(
+ arg0,
+ t,
+ ::boost::type_erasure::detail::should_check<Concept, t0>()))
+ return false;
+
+ return check_table(t, static_cast<void(*)(T...)>(0), arg...);
+}
+
+}
+
+template<class Concept, class Op, class... U>
+bool check_match(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op&,
+ U&... arg)
+{
+
+ return ::boost::type_erasure::detail::check_table(
+ &table,
+ static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0),
+ arg...);
+}
+
+template<
+ class Op,
+ class... U
+>
+bool check_match(
+ const Op&,
+ U&... arg)
+{
+ const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::extract_concept<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type, U...>::type>* p = 0;
+
+ return ::boost::type_erasure::detail::check_table(
+ p, static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...);
+}
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/check_match.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+#endif
+
+}
+}
+
+#endif
+
+#else
+
+namespace detail {
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_CHECK_TABLE(z, n, data) \
+ typedef typename ::boost::remove_cv< \
+ typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type \
+ >::type BOOST_PP_CAT(t, n); \
+ if(!::boost::type_erasure::detail::maybe_check_table<BOOST_PP_CAT(t, n)>( \
+ BOOST_PP_CAT(arg, n), \
+ t, \
+ ::boost::type_erasure::detail::should_check<Concept, BOOST_PP_CAT(t, n)>())) \
+ return false;
+
+template<
+ class Concept,
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)>
+bool
+BOOST_PP_CAT(check_table, N)(
+ const ::boost::type_erasure::binding<Concept>* t,
+ R (*)(BOOST_PP_ENUM_PARAMS(N, T))
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, const U, &arg))
+{
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CHECK_TABLE, ~)
+ return true;
+}
+
+#if N != 0
+
+template<class Sig BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)>
+struct BOOST_PP_CAT(do_extract_concept, N);
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+struct BOOST_PP_CAT(do_extract_concept, N)<
+ R(BOOST_PP_ENUM_PARAMS(N, T))
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, U)
+>
+ : ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
+ BOOST_PP_ENUM_PARAMS(N, T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
+{};
+
+#endif
+
+}
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+bool check_match(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+
+ return ::boost::type_erasure::detail::BOOST_PP_CAT(check_table, N)(
+ &table,
+ (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#if N != 0
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+bool check_match(
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ const ::boost::type_erasure::binding<
+ typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ BOOST_PP_ENUM_PARAMS(N, U)>::type>* p = 0;
+
+ return ::boost::type_erasure::detail::BOOST_PP_CAT(check_table, N)(
+ p,
+ (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#undef BOOST_TYPE_ERASURE_CHECK_TABLE
+#undef N
+
+#endif
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/concept_interface.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/concept_interface.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,34 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_CONCEPT_INTERFACE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CONCEPT_INTERFACE_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * The @ref concept_interface class can be specialized to
+ * add behavior to an @ref any.
+ *
+ * \tparam Concept The concept that we're specializing
+ * @ref concept_interface for.
+ * \tparam Base The base of this class. Specializations of @ref
+ * concept_interface must inherit publicly from this type.
+ * \tparam ID The placeholder representing this type.
+ * \tparam Enable A dummy parameter that can be used for SFINAE.
+ */
+template<class Concept, class Base, class ID, class Enable = void>
+struct concept_interface : Base {};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/concept_of.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/concept_of.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,48 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_CONCEPT_OF_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CONCEPT_OF_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class T>
+class any;
+
+/**
+ * A metafunction returning the concept corresponding
+ * to an @ref any. It will also work for all bases
+ * of @ref any, so it can be applied to the @c Base
+ * parameter of @ref concept_interface.
+ */
+template<class T>
+struct concept_of
+{
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+ typedef detail::unspecified type;
+#else
+ typedef typename ::boost::type_erasure::concept_of<
+ typename T::_boost_type_erasure_derived_type
+ >::type type;
+#endif
+};
+
+/** INTERNAL ONLY */
+template<class Concept, class T>
+struct concept_of< ::boost::type_erasure::any<Concept, T> >
+{
+ typedef Concept type;
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/config.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/config.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,27 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_CONFIG_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CONFIG_HPP_INCLUDED
+
+#ifndef BOOST_TYPE_ERASURE_MAX_FUNCTIONS
+/** The maximum number of functions that an @ref boost::type_erasure::any "any" can have. */
+#define BOOST_TYPE_ERASURE_MAX_FUNCTIONS 50
+#endif
+#ifndef BOOST_TYPE_ERASURE_MAX_ARITY
+/** The maximum number of arguments that functions in the library support. */
+#define BOOST_TYPE_ERASURE_MAX_ARITY 5
+#endif
+#ifndef BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE
+/** The maximum number of elements in a @ref boost::type_erasure::tuple "tuple". */
+#define BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE 5
+#endif
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/constructible.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/constructible.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,130 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_CONSTRUCTIBLE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_CONSTRUCTIBLE_HPP_INCLUDED
+
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/type_erasure/detail/storage.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Sig>
+struct constructible;
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+/**
+ * The @ref constructible concept enables calling the
+ * constructor of a type contained by an @ref any.
+ * @c Sig should be a function signature. The return
+ * type is the placeholder specifying the type to
+ * be constructed. The arguments are the argument
+ * types of the constructor.
+ */
+template<class Sig>
+struct constructible {};
+
+#elif !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<class R, class... T>
+struct constructible<R(T...)>
+{
+ static ::boost::type_erasure::detail::storage
+ apply(T... arg)
+ {
+ ::boost::type_erasure::detail::storage result;
+ result.data = new R(arg...);
+ return result;
+ }
+};
+
+/// INTERNAL ONLY
+template<class Base, class R, class... T, class Tag>
+struct concept_interface<
+ ::boost::type_erasure::constructible<R(T...)>,
+ Base,
+ Tag
+> : Base
+{
+ using Base::_boost_type_erasure_deduce_constructor;
+ ::boost::type_erasure::constructible<R(T...)>*
+ _boost_type_erasure_deduce_constructor(
+ typename ::boost::type_erasure::rebind_any<Base, T>::type...)
+ {
+ return 0;
+ }
+};
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/constructible.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_ARG_DECL(z, n, data) \
+ typename ::boost::type_erasure::rebind_any< \
+ Base, \
+ BOOST_PP_CAT(T, n) \
+ >::type
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct constructible<R(BOOST_PP_ENUM_PARAMS(N, T))>
+{
+ static ::boost::type_erasure::detail::storage
+ apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
+ {
+ ::boost::type_erasure::detail::storage result;
+ result.data = new R(BOOST_PP_ENUM_PARAMS(N, arg));
+ return result;
+ }
+};
+
+template<class Base, class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Tag>
+struct concept_interface<
+ ::boost::type_erasure::constructible<R(BOOST_PP_ENUM_PARAMS(N, T))>,
+ Base,
+ Tag
+> : Base
+{
+ using Base::_boost_type_erasure_deduce_constructor;
+ ::boost::type_erasure::constructible<R(BOOST_PP_ENUM_PARAMS(N, T))>*
+ _boost_type_erasure_deduce_constructor(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_ARG_DECL, ~))
+ {
+ return 0;
+ }
+};
+
+#undef BOOST_TYPE_ERASURE_ARG_DECL
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/derived.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/derived.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,35 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DERIVED_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DERIVED_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * A metafunction which returns the full @ref any type,
+ * when given any of its base classes. This is primarily
+ * intended to be used when implementing @ref concept_interface.
+ */
+template<class T>
+struct derived
+{
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+ typedef detail::unspecified type;
+#else
+ typedef typename T::_boost_type_erasure_derived_type type;
+#endif
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/access.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/access.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,57 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_ACCESS_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_ACCESS_HPP_INCLUDED
+
+#include <boost/type_erasure/detail/storage.hpp>
+#include <boost/type_erasure/detail/any_base.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class T>
+class any;
+
+namespace detail {
+
+struct access
+{
+ template<class Derived>
+ static const typename Derived::table_type&
+ table(const ::boost::type_erasure::any_base<Derived>& arg)
+ {
+ return static_cast<const Derived&>(arg).table;
+ }
+ template<class Derived>
+ static ::boost::type_erasure::detail::storage&
+ data(::boost::type_erasure::any_base<Derived>& arg)
+ {
+ return static_cast<Derived&>(arg).data;
+ }
+ template<class Concept, class T>
+ static const ::boost::type_erasure::detail::storage&
+ data(::boost::type_erasure::any_base< ::boost::type_erasure::any<Concept, const T&> >& arg)
+ {
+ return static_cast< ::boost::type_erasure::any<Concept, const T&>&>(arg).data;
+ }
+ template<class Derived>
+ static const ::boost::type_erasure::detail::storage&
+ data(const ::boost::type_erasure::any_base<Derived>& arg)
+ {
+ return static_cast<const Derived&>(arg).data;
+ }
+};
+
+}
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,275 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_ADAPT_TO_VTABLE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_ADAPT_TO_VTABLE_HPP_INCLUDED
+
+#include <boost/utility/addressof.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/type_erasure/detail/get_signature.hpp>
+#include <boost/type_erasure/detail/storage.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/config.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+namespace detail {
+
+template<class T, class Bindings>
+struct rebind_placeholders;
+
+template<class T, class Bindings>
+struct rebind_placeholders_in_argument;
+
+template<class PrimitiveConcept, class Sig>
+struct vtable_adapter;
+
+template<class PrimitiveConcept, class Sig, class Bindings>
+struct rebind_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Bindings>
+{
+ typedef vtable_adapter<
+ typename rebind_placeholders<PrimitiveConcept, Bindings>::type,
+ typename rebind_placeholders_in_argument<Sig, Bindings>::type
+ > type;
+};
+
+template<class T>
+struct replace_param_for_vtable
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ const ::boost::type_erasure::detail::storage&,
+ T
+ >::type type;
+};
+
+template<class T>
+struct replace_param_for_vtable<T&>
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ ::boost::type_erasure::detail::storage&,
+ T&
+ >::type type;
+};
+
+template<class T>
+struct replace_param_for_vtable<const T&>
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ const ::boost::type_erasure::detail::storage&,
+ const T&
+ >::type type;
+};
+
+template<class T>
+struct replace_result_for_vtable
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ ::boost::type_erasure::detail::storage,
+ T
+ >::type type;
+};
+
+template<class T>
+struct replace_result_for_vtable<T&>
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ ::boost::type_erasure::detail::storage&,
+ T&
+ >::type type;
+};
+
+template<class T>
+struct replace_result_for_vtable<const T&>
+{
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
+ ::boost::type_erasure::detail::storage&,
+ const T&
+ >::type type;
+};
+
+template<class Sig>
+struct get_vtable_signature;
+
+BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
+
+template<class T>
+struct is_internal_concept :
+ ::boost::type_erasure::detail::has_type<T>
+{};
+
+template<class PrimitiveConcept>
+struct adapt_to_vtable
+{
+ typedef ::boost::type_erasure::detail::vtable_adapter<
+ PrimitiveConcept,
+ typename ::boost::type_erasure::detail::get_vtable_signature<
+ typename ::boost::type_erasure::detail::get_signature<
+ PrimitiveConcept
+ >::type
+ >::type
+ > type;
+};
+
+template<class Concept>
+struct maybe_adapt_to_vtable
+{
+ typedef typename ::boost::mpl::eval_if<
+ ::boost::type_erasure::detail::is_internal_concept<Concept>,
+ ::boost::mpl::identity<Concept>,
+ ::boost::type_erasure::detail::adapt_to_vtable<Concept>
+ >::type type;
+};
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<class PrimitiveConcept, class Sig, class ConceptSig>
+struct vtable_adapter_impl;
+
+template<class PrimitiveConcept, class R, class... T, class R2, class... U>
+struct vtable_adapter_impl<PrimitiveConcept, R(T...), R2(U...)>
+{
+ typedef R (*type)(T...);
+ static R value(T... arg)
+ {
+ return PrimitiveConcept::apply(
+ ::boost::type_erasure::detail::extract<U>(arg)...);
+ }
+};
+
+template<class PrimitiveConcept, class... T, class R2, class... U>
+struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage&(T...), R2(U...)>
+{
+ typedef ::boost::type_erasure::detail::storage (*type)(T...);
+ static ::boost::type_erasure::detail::storage value(T... arg)
+ {
+ ::boost::type_erasure::detail::storage result;
+ typename ::boost::remove_reference<R2>::type* p =
+ ::boost::addressof(
+ PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(arg)...));
+ result.data = const_cast<void*>(static_cast<const void*>(p));
+ return result;
+ }
+};
+
+template<class PrimitiveConcept, class Sig>
+struct vtable_adapter
+ : vtable_adapter_impl<
+ PrimitiveConcept,
+ Sig,
+ typename ::boost::type_erasure::detail::get_signature<
+ PrimitiveConcept
+ >::type
+ >
+{};
+
+template<class R, class... T>
+struct get_vtable_signature<R(T...)>
+{
+ typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
+ R
+ >::type type(typename ::boost::type_erasure::detail::replace_param_for_vtable<T>::type...);
+};
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/adapt_to_vtable.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+#define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
+ ::boost::type_erasure::detail::extract< \
+ typename traits:: \
+ BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
+ >(BOOST_PP_CAT(arg, n))
+#define BOOST_TYPE_ERASURE_REPLACE_PARAM(z, n, data) \
+ typename ::boost::type_erasure::detail::replace_param_for_vtable< \
+ BOOST_PP_CAT(T, n)>::type
+
+template<class PrimitiveConcept, class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct vtable_adapter<PrimitiveConcept, R(BOOST_PP_ENUM_PARAMS(N, T))>
+{
+ typedef R (*type)(BOOST_PP_ENUM_PARAMS(N, T));
+ static R value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
+ {
+ typedef typename ::boost::function_traits<
+ typename ::boost::type_erasure::detail::get_signature<
+ PrimitiveConcept
+ >::type
+ > traits;
+ return PrimitiveConcept::apply(
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
+ }
+};
+
+template<class PrimitiveConcept
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct vtable_adapter<PrimitiveConcept, ::boost::type_erasure::detail::storage&(BOOST_PP_ENUM_PARAMS(N, T))>
+{
+ typedef ::boost::type_erasure::detail::storage (*type)(BOOST_PP_ENUM_PARAMS(N, T));
+ static ::boost::type_erasure::detail::storage value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
+ {
+ typedef typename ::boost::function_traits<
+ typename ::boost::type_erasure::detail::get_signature<
+ PrimitiveConcept
+ >::type
+ > traits;
+ ::boost::type_erasure::detail::storage result;
+ typename ::boost::remove_reference<typename traits::result_type>::type* p =
+ ::boost::addressof(
+ PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~)));
+ result.data = const_cast<void*>(static_cast<const void*>(p));
+ return result;
+ }
+};
+
+template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct get_vtable_signature<R(BOOST_PP_ENUM_PARAMS(N, T))>
+{
+ typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
+ R
+ >::type type(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REPLACE_PARAM, ~));
+};
+
+#undef BOOST_TYPE_ERASURE_REPLACE_PARAM
+#undef BOOST_TYPE_ERASURE_EXTRACT
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,28 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_ANY_BASE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_ANY_BASE_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+template<class Derived>
+struct any_base
+{
+ typedef Derived _boost_type_erasure_derived_type;
+ void* _boost_type_erasure_deduce_constructor(...) { return 0; }
+ void* _boost_type_erasure_deduce_assign(...) { return 0; }
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/construct.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/construct.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,106 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+// NO #include GUARD.
+
+#define N BOOST_PP_ITERATION()
+
+#if N > 1
+
+ template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+ >
+ const table_type& _boost_type_erasure_extract_table(
+ ::boost::type_erasure::constructible<R(BOOST_PP_ENUM_PARAMS(N, A))>*
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u))
+ {
+ return *::boost::type_erasure::detail::BOOST_PP_CAT(extract_table, N)(
+ (R(*)(BOOST_PP_ENUM_PARAMS(N, A)))0,
+ BOOST_PP_ENUM_PARAMS(N, u));
+ }
+
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ any(BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &u))
+ : table(
+ _boost_type_erasure_extract_table(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ ),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ ), BOOST_PP_ENUM_PARAMS(N, u))
+ )
+ {}
+
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ any(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))
+ : table(
+ _boost_type_erasure_extract_table(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ ),
+ data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ ), BOOST_PP_ENUM_PARAMS(N, u))
+ )
+ {}
+
+#endif
+
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ any(const binding<Concept>& binding_arg BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, const U, &u))
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ )
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ )
+ {}
+
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ any(const binding<Concept>& binding_arg BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u))
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ )
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ )
+ {}
+
+ // disambiguate
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ any(binding<Concept>& binding_arg BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u))
+ : table(binding_arg),
+ data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(BOOST_PP_ENUM_PARAMS(N, u)) : 0
+ )
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ )
+ {}
+
+#undef N

Added: sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/extract_concept.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,126 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_EXTRACT_CONCEPT_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_EXTRACT_CONCEPT_HPP_INCLUDED
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/inc.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/concept_of.hpp>
+#include <boost/type_erasure/config.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class T, class U>
+struct combine_concepts;
+
+template<class T>
+struct combine_concepts<T, T> { typedef T type; };
+template<class T>
+struct combine_concepts<T, void> { typedef T type; };
+template<class T>
+struct combine_concepts<void, T> { typedef T type; };
+template<>
+struct combine_concepts<void, void> { typedef void type; };
+
+template<class T, class U>
+struct maybe_extract_concept
+{
+ typedef typename ::boost::mpl::eval_if<
+ ::boost::type_erasure::is_placeholder<
+ typename ::boost::remove_cv<
+ typename ::boost::remove_reference<T>::type
+ >::type
+ >,
+ ::boost::type_erasure::concept_of<U>,
+ ::boost::mpl::identity<void>
+ >::type type;
+};
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<class Args, class... U>
+struct extract_concept;
+
+template<class R, class T0, class... T, class U0, class... U>
+struct extract_concept<R(T0, T...), U0, U...>
+{
+ typedef typename ::boost::type_erasure::detail::combine_concepts<
+ typename ::boost::type_erasure::detail::maybe_extract_concept<
+ T0, U0
+ >::type,
+ typename ::boost::type_erasure::detail::extract_concept<
+ void(T...),
+ U...
+ >::type
+ >::type type;
+};
+
+template<>
+struct extract_concept<void()>
+{
+ typedef void type;
+};
+
+#else
+//#endif
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/extract_concept.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_EXTRACT_CONCEPT(z, n, data) \
+ typedef typename ::boost::type_erasure::detail::combine_concepts< \
+ typename ::boost::type_erasure::detail::maybe_extract_concept< \
+ BOOST_PP_CAT(T, n), BOOST_PP_CAT(U, n) \
+ >::type, \
+ BOOST_PP_CAT(concept, n) \
+ >::type BOOST_PP_CAT(concept, BOOST_PP_INC(n));
+
+template<
+ BOOST_PP_ENUM_PARAMS(N, class T),
+ BOOST_PP_ENUM_PARAMS(N, class U)>
+struct BOOST_PP_CAT(extract_concept, N)
+{
+ typedef void concept0;
+
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_EXTRACT_CONCEPT, ~)
+
+ typedef BOOST_PP_CAT(concept, N) type;
+};
+
+#undef BOOST_TYPE_ERASURE_EXTRACT_CONCEPT
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/get_placeholders.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/get_placeholders.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,148 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_GET_PLACEHOLDERS_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_GET_PLACEHOLDERS_HPP_INCLUDED
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/insert.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class T, class Out>
+struct get_placeholders_in_argument
+{
+ typedef typename ::boost::mpl::eval_if<
+ ::boost::type_erasure::is_placeholder<T>,
+ ::boost::mpl::insert<Out, T>,
+ ::boost::mpl::identity<Out>
+ >::type type;
+};
+
+template<class T, class Out>
+struct get_placeholders;
+
+template<class T, class Out>
+struct get_placeholders_in_argument<T&, Out>
+{
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
+ T,
+ Out
+ >::type type;
+};
+
+template<class T, class Out>
+struct get_placeholders_in_argument<const T, Out>
+{
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
+ T,
+ Out
+ >::type type;
+};
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<class Out, class... T>
+struct get_placeholders_impl;
+
+template<class Out, class T0, class... T>
+struct get_placeholders_impl<Out, T0, T...>
+{
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
+ T0,
+ typename get_placeholders_impl<Out, T...>::type
+ >::type type;
+};
+
+template<class Out>
+struct get_placeholders_impl<Out>
+{
+ typedef Out type;
+};
+
+template<template<class...> class T, class... U, class Out>
+struct get_placeholders<T<U...>, Out>
+{
+ typedef typename get_placeholders_impl<Out, U...>::type type;
+};
+
+template<class R, class... T, class Out>
+struct get_placeholders_in_argument<R(T...), Out>
+{
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
+ R,
+ Out
+ >::type type0;
+ typedef typename get_placeholders_impl<type0, T...>::type type;
+};
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/get_placeholders.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+#define BOOST_TYPE_ERASURE_GET_PLACEHOLDER(z, n, data) \
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument< \
+ BOOST_PP_CAT(data, n), BOOST_PP_CAT(type, n)>::type \
+ BOOST_PP_CAT(type, BOOST_PP_INC(n));
+
+#if N != 0
+
+template<template<BOOST_PP_ENUM_PARAMS(N, class T)> class T,
+ BOOST_PP_ENUM_PARAMS(N, class T), class Out>
+struct get_placeholders<T<BOOST_PP_ENUM_PARAMS(N, T)>, Out>
+{
+ typedef Out type0;
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_PLACEHOLDER, T)
+ typedef BOOST_PP_CAT(type, N) type;
+};
+
+#endif
+
+template<class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Out>
+struct get_placeholders_in_argument<R(BOOST_PP_ENUM_PARAMS(N, T)), Out>
+{
+ typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
+ R,
+ Out
+ >::type type0;
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_PLACEHOLDER, T)
+ typedef BOOST_PP_CAT(type, N) type;
+};
+
+#undef BOOST_TYPE_ERASURE_GET_PLACEHOLDER
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/get_signature.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/get_signature.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,33 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_GET_SIGNATURE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_GET_SIGNATURE_HPP_INCLUDED
+
+#include <boost/typeof/typeof.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class Concept>
+struct get_signature {
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, &Concept::apply)
+ typedef typename boost::remove_pointer<
+ typename nested::type
+ >::type type;
+};
+
+}
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/normalize.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,100 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_NORMALIZE_HPP_INCLUDED
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/set.hpp>
+#include <boost/mpl/insert.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/type_erasure/detail/get_placeholders.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/builtin.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class Concept, class Out = ::boost::mpl::set0<> >
+struct normalize_concept_impl
+{
+ typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
+ ::boost::mpl::fold<Concept, Out, normalize_concept_impl< ::boost::mpl::_2, ::boost::mpl::_1> >,
+ ::boost::mpl::insert<Out, Concept>
+ >::type type;
+};
+
+struct append_typeinfo
+{
+ template<class Set, class T>
+ struct apply
+ {
+ typedef typename ::boost::mpl::insert<
+ Set,
+ ::boost::type_erasure::typeid_<T>
+ >::type type;
+ };
+};
+
+template<class Seq>
+struct add_typeinfo
+{
+ typedef typename ::boost::mpl::fold<
+ Seq,
+ ::boost::mpl::set0<>,
+ ::boost::type_erasure::detail::get_placeholders<
+ ::boost::mpl::_2,
+ ::boost::mpl::_1
+ >
+ >::type placeholders;
+ typedef typename ::boost::mpl::fold<
+ placeholders,
+ Seq,
+ ::boost::type_erasure::detail::append_typeinfo
+ >::type type;
+};
+
+template<class Concept>
+struct normalize_concept
+{
+ typedef typename normalize_concept_impl<Concept>::type basic;
+ typedef typename ::boost::mpl::copy<
+ typename ::boost::mpl::eval_if<
+ ::boost::type_erasure::is_relaxed<Concept>,
+ ::boost::type_erasure::detail::add_typeinfo<basic>,
+ ::boost::mpl::identity<basic>
+ >::type,
+ ::boost::mpl::back_inserter< ::boost::mpl::vector0<> >
+ >::type type;
+};
+
+template<class Concept, class Out = ::boost::mpl::set0<> >
+struct collect_concepts
+{
+ typedef typename ::boost::mpl::insert<
+ Out,
+ Concept
+ >::type type1;
+ typedef typename ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
+ ::boost::mpl::fold<Concept, type1, collect_concepts< ::boost::mpl::_2, ::boost::mpl::_1> >,
+ ::boost::mpl::identity<type1>
+ >::type type;
+};
+
+}
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/rebind_placeholders.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,123 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_REBIND_PLACEHOLDERS_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_REBIND_PLACEHOLDERS_HPP_INCLUDED
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class T, class Bindings>
+struct rebind_placeholders;
+
+template<class T, class Bindings>
+struct rebind_placeholders_in_argument
+{
+ typedef typename ::boost::mpl::eval_if<is_placeholder<T>,
+ ::boost::mpl::at<Bindings, T>,
+ ::boost::mpl::identity<T>
+ >::type type;
+};
+
+template<class T, class Bindings>
+struct rebind_placeholders_in_argument<T&, Bindings>
+{
+ typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
+ T,
+ Bindings
+ >::type& type;
+};
+
+template<class T, class Bindings>
+struct rebind_placeholders_in_argument<const T, Bindings>
+{
+ typedef const typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
+ T,
+ Bindings
+ >::type type;
+};
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template<template<class...> class T, class... U, class Bindings>
+struct rebind_placeholders<T<U...>, Bindings>
+{
+ typedef T<typename rebind_placeholders_in_argument<U, Bindings>::type...> type;
+};
+
+template<class R, class... T, class Bindings>
+struct rebind_placeholders_in_argument<R(T...), Bindings>
+{
+ typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
+ R,
+ Bindings
+ >::type type(typename rebind_placeholders_in_argument<T, Bindings>::type...);
+};
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/rebind_placeholders.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+#define BOOST_TYPE_ERASURE_REBIND(z, n, data) \
+ typename rebind_placeholders_in_argument<BOOST_PP_CAT(data, n), Bindings>::type
+
+#if N != 0
+
+template<template<BOOST_PP_ENUM_PARAMS(N, class T)> class T,
+ BOOST_PP_ENUM_PARAMS(N, class T), class Bindings>
+struct rebind_placeholders<T<BOOST_PP_ENUM_PARAMS(N, T)>, Bindings>
+{
+ typedef T<BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, T)> type;
+};
+
+#endif
+
+template<class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Bindings>
+struct rebind_placeholders_in_argument<R(BOOST_PP_ENUM_PARAMS(N, T)), Bindings>
+{
+ typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
+ R,
+ Bindings
+ >::type type(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, T));
+};
+
+#undef BOOST_TYPE_ERASURE_REBIND
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/storage.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/storage.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,47 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED
+
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+struct storage
+{
+ storage() {}
+ template<class T>
+ storage(const T& arg) : data(new T(arg)) {}
+ void* data;
+};
+
+template<class T>
+T extract(T arg) { return arg; }
+
+template<class T>
+T extract(storage& arg)
+{
+ return *static_cast<typename ::boost::remove_reference<T>::type*>(arg.data);
+}
+
+template<class T>
+T extract(const storage& arg)
+{
+ return *static_cast<const typename ::boost::remove_reference<T>::type*>(arg.data);
+}
+
+}
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/detail/vtable.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/vtable.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,287 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/type_erasure/detail/rebind_placeholders.hpp>
+#include <boost/type_erasure/config.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CONSTEXPR) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS)
+
+template<class... T>
+struct stored_arg_pack;
+
+template<class It, class End, class... T>
+struct make_arg_pack_impl
+{
+ typedef typename make_arg_pack_impl<
+ typename ::boost::mpl::next<It>::type,
+ End,
+ T...,
+ typename ::boost::mpl::deref<It>::type
+ >::type type;
+};
+
+template<class End, class... T>
+struct make_arg_pack_impl<End, End, T...>
+{
+ typedef stored_arg_pack<T...> type;
+};
+
+template<class Seq>
+struct make_arg_pack
+{
+ typedef typename make_arg_pack_impl<
+ typename ::boost::mpl::begin<Seq>::type,
+ typename ::boost::mpl::end<Seq>::type
+ >::type type;
+};
+
+template<class Args>
+struct make_vtable_impl;
+
+template<class Seq>
+struct make_vtable
+{
+ typedef typename ::boost::type_erasure::detail::make_vtable_impl<
+ typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
+ >::type type;
+};
+
+template<class Table, class Args>
+struct make_vtable_init_impl;
+
+template<class Seq, class Table>
+struct make_vtable_init
+{
+ typedef typename make_vtable_init_impl<
+ Table,
+ typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
+ >::type type;
+};
+
+template<class T>
+struct vtable_entry
+{
+ typename T::type value;
+ vtable_entry() = default;
+ constexpr vtable_entry(typename T::type arg) : value(arg) {}
+};
+
+template<class... T>
+struct compare_vtable;
+
+template<>
+struct compare_vtable<> {
+ template<class S>
+ static bool apply(const S& s1, const S& s2)
+ {
+ return true;
+ }
+};
+
+template<class T0, class... T>
+struct compare_vtable<T0, T...> {
+ template<class S>
+ static bool apply(const S& s1, const S& s2)
+ {
+ return static_cast<const vtable_entry<T0>&>(s1).value ==
+ static_cast<const vtable_entry<T0>&>(s2).value &&
+ compare_vtable<T...>::apply(s1, s2);
+ }
+};
+
+template<class... T>
+struct vtable_storage : vtable_entry<T>...
+{
+ vtable_storage() = default;
+
+ constexpr vtable_storage(typename T::type... arg)
+ : vtable_entry<T>(arg)... {}
+
+ template<class Bindings, class Src>
+ void convert_from(const Src& src)
+ {
+ *this = vtable_storage(
+ src.lookup(
+ (typename ::boost::type_erasure::detail::rebind_placeholders<
+ T, Bindings
+ >::type*)0)...);
+ }
+
+ bool operator==(const vtable_storage& other) const
+ { return compare_vtable<T...>::apply(*this, other); }
+
+ template<class U>
+ typename U::type lookup(U*) const
+ {
+ return static_cast<const vtable_entry<U>*>(this)->value;
+ }
+};
+
+template<class... T>
+struct make_vtable_impl<stored_arg_pack<T...> >
+{
+ typedef vtable_storage<T...> type;
+};
+
+template<class Table, class... T>
+struct vtable_init
+{
+ static constexpr Table value;
+};
+
+template<class Table, class... T>
+constexpr Table vtable_init<Table, T...>::value(T::value...);
+
+template<class Table, class... T>
+struct make_vtable_init_impl<Table, stored_arg_pack<T...> >
+{
+ typedef vtable_init<Table, T...> type;
+};
+
+#else
+
+template<int N>
+struct make_vtable_impl;
+
+template<class Seq>
+struct make_vtable
+{
+ typedef typename make_vtable_impl<
+ (::boost::mpl::size<Seq>::value)>::template apply<Seq>::type type;
+};
+
+template<int N>
+struct make_vtable_init_impl;
+
+template<class Seq, class Table>
+struct make_vtable_init
+{
+ typedef typename make_vtable_init_impl<
+ (::boost::mpl::size<Seq>::value)>::template apply<Seq, Table>::type type;
+};
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/vtable.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_TYPE_ERASURE_MAX_FUNCTIONS)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_VTABLE_ENTRY(z, n, data) \
+ typename BOOST_PP_CAT(T, n)::type BOOST_PP_CAT(t, n); \
+ typename BOOST_PP_CAT(T, n)::type lookup(BOOST_PP_CAT(T, n)*) const \
+ { \
+ return BOOST_PP_CAT(t, n); \
+ }
+
+#define BOOST_TYPE_ERASURE_VTABLE_COMPARE(z, n, data) \
+ && BOOST_PP_CAT(t, n) == other.BOOST_PP_CAT(t, n)
+
+#define BOOST_TYPE_ERASURE_VTABLE_INIT(z, n, data) \
+ BOOST_PP_CAT(data, n)::value
+
+#define BOOST_TYPE_ERASURE_AT(z, n, data) \
+ typename ::boost::mpl::at_c<data, n>::type
+
+#define BOOST_TYPE_ERASURE_CONVERT_ELEMENT(z, n, data) \
+ BOOST_PP_CAT(t, n) = src.lookup( \
+ (typename ::boost::type_erasure::detail::rebind_placeholders< \
+ BOOST_PP_CAT(T, n), Bindings \
+ >::type*)0 \
+ );
+
+template<BOOST_PP_ENUM_PARAMS(N, class T)>
+struct BOOST_PP_CAT(vtable_storage, N)
+{
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_ENTRY, ~)
+
+ template<class Bindings, class Src>
+ void convert_from(const Src& src)
+ {
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CONVERT_ELEMENT, ~)
+ }
+
+ bool operator==(const BOOST_PP_CAT(vtable_storage, N)& other) const
+ { return true BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_COMPARE, ~); }
+};
+
+template<>
+struct make_vtable_impl<N>
+{
+ template<class Seq>
+ struct apply
+ {
+ typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_storage, N)<
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_AT, Seq)
+ > type;
+ };
+};
+template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct BOOST_PP_CAT(vtable_init, N)
+{
+ static const Table value;
+};
+
+template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+const Table BOOST_PP_CAT(vtable_init, N)<
+ Table BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>::value =
+{
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_VTABLE_INIT, T)
+};
+
+template<>
+struct make_vtable_init_impl<N>
+{
+ template<class Seq, class Table>
+ struct apply
+ {
+ typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_init, N)<
+ Table
+ BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_AT, Seq)
+ > type;
+ };
+};
+
+#undef BOOST_TYPE_ERASURE_CONVERT_ELEMENT
+#undef BOOST_TYPE_ERASURE_AT
+#undef BOOST_TYPE_ERASURE_VTABLE_INIT
+#undef BOOST_TYPE_ERASURE_VTABLE_COMPARE
+#undef BOOST_TYPE_ERASURE_VTABLE_ENTRY
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/is_placeholder.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/is_placeholder.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,27 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_IS_PLACEHOLDER_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_IS_PLACEHOLDER_HPP_INCLUDED
+
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_erasure/placeholder.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/** A metafunction that indicates whether a type is a @ref placeholder. */
+template<class T>
+struct is_placeholder : ::boost::is_base_and_derived<placeholder_base, T> {};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/iterator.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,94 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_ITERATOR_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_ITERATOR_HPP_INCLUDED
+
+#include <iterator>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/builtin.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Pointer = ValueType*, class Reference = ValueType&>
+struct forward_iterator :
+ boost::mpl::vector<
+ copy_constructible<T>,
+ constructible<T()>,
+ equality_comparable<T>,
+ dereferenceable<Reference, T>,
+ incrementable<T>,
+ assignable<T>
+ >
+{};
+
+/// \cond show_operators
+
+template<class T, class ValueType, class DifferenceType, class Pointer, class Reference, class Base>
+struct concept_interface<forward_iterator<T, ValueType, DifferenceType, Pointer, Reference>, Base, T>
+ : Base
+{
+ typedef typename rebind_any<Base, ValueType>::type value_type;
+ typedef typename rebind_any<Base, Reference>::type reference;
+ typedef DifferenceType difference_type;
+ typedef Pointer pointer;
+ typedef std::forward_iterator_tag iterator_category;
+};
+
+/// \endcond
+
+template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Pointer = ValueType*, class Reference = ValueType&>
+struct bidirectional_iterator :
+ boost::mpl::vector<
+ forward_iterator<T, ValueType, DifferenceType, Pointer, Reference>,
+ decrementable<T>
+ >
+{};
+
+/// \cond show_operators
+
+template<class T, class ValueType, class DifferenceType, class Pointer, class Reference, class Base>
+struct concept_interface<bidirectional_iterator<T, ValueType, DifferenceType, Pointer, Reference>, Base, T>
+ : Base
+{
+ typedef std::bidirectional_iterator_tag iterator_category;
+};
+
+/// \endcond
+
+template<class T, class ValueType, class DifferenceType = std::ptrdiff_t, class Pointer = ValueType*, class Reference = ValueType&>
+struct random_access_iterator :
+ boost::mpl::vector<
+ bidirectional_iterator<T, ValueType, DifferenceType, Pointer, Reference>,
+ addable<T, DifferenceType, T>,
+ addable<DifferenceType, T, T>,
+ subtractable<T, DifferenceType, T>,
+ subtractable<T, T, DifferenceType>,
+ subscriptable<Reference, T, DifferenceType>
+ >
+{};
+
+/// \cond show_operators
+
+template<class T, class ValueType, class DifferenceType, class Pointer, class Reference, class Base>
+struct concept_interface<random_access_iterator<T, ValueType, DifferenceType, Pointer, Reference>, Base, T>
+ : Base
+{
+ typedef std::random_access_iterator_tag iterator_category;
+};
+
+/// \endcond
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/operators.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/operators.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,505 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_OPERATORS_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_OPERATORS_HPP_INCLUDED
+
+#include <iosfwd>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/placeholder.hpp>
+#include <boost/type_erasure/concept_of.hpp>
+#include <boost/type_erasure/derived.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/check_match.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/typeid_of.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class Placeholder>
+class any;
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(name, op) \
+ template<class T = _self> \
+ struct name \
+ { \
+ static void apply(T& arg) { op arg; } \
+ }; \
+ \
+ template<class T, class Base> \
+ struct concept_interface<name<T>, Base, T> : Base \
+ { \
+ typedef typename ::boost::type_erasure::derived<Base>::type _derived; \
+ _derived& operator op() \
+ { \
+ ::boost::type_erasure::call(name<T>(), *this); \
+ return static_cast<_derived&>(*this); \
+ } \
+ typename ::boost::type_erasure::rebind_any<Base, T>::type operator op(int) \
+ { \
+ typename ::boost::type_erasure::rebind_any<Base, T>::type result( \
+ static_cast<_derived&>(*this)); \
+ ::boost::type_erasure::call(name<T>(), *this); \
+ return result; \
+ } \
+ };
+
+/**
+ * The @ref incrementable concept allow pre and
+ * post increment on an @ref any. The contained
+ * type must provide a pre-increment operator.
+ */
+BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(incrementable, ++)
+/**
+ * The @ref decrementable concept allow pre and
+ * post decrement on an @ref any. The contained
+ * type must provide a pre-decrement operator.
+ */
+BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(decrementable, --)
+
+#undef BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_UNARY_OPERATOR(name, op) \
+ template<class T = _self, class R = T> \
+ struct name \
+ { \
+ static R apply(const T& arg) { return op arg; } \
+ }; \
+ \
+ template<class T, class R, class Base> \
+ struct concept_interface<name<T, R>, Base, T> : Base \
+ { \
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator op() const \
+ { \
+ return ::boost::type_erasure::call(name<T, R>(), *this); \
+ } \
+ };
+
+/**
+ * The @ref complementable concept allow use of the bitwise
+ * complement operator on an @ref any.
+ */
+BOOST_TYPE_ERASURE_UNARY_OPERATOR(complementable, ~)
+/**
+ * The @ref negatable concept allow use of the unary
+ * minus operator on an @ref any.
+ */
+BOOST_TYPE_ERASURE_UNARY_OPERATOR(negatable, -)
+
+#undef BOOST_TYPE_ERASURE_UNARY_OPERATOR
+
+template<class R, class T = _self>
+struct dereferenceable
+{
+ static R apply(const T& arg) { return *arg; }
+};
+
+/// \cond show_operators
+
+template<class R, class T, class Base>
+struct concept_interface<dereferenceable<R, T>, Base, T> : Base
+{
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator*() const
+ {
+ return ::boost::type_erasure::call(dereferenceable<R, T>(), *this);
+ }
+};
+
+/// \endcond
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_BINARY_OPERATOR(name, op) \
+ template<class T = _self, class U = T, class R = T> \
+ struct name \
+ { \
+ static R apply(const T& lhs, const U& rhs) { return lhs op rhs; } \
+ }; \
+ \
+ template<class T, class U, class R, class Base> \
+ struct concept_interface<name<T, U, R>, Base, T> : Base \
+ { \
+ friend typename rebind_any<Base, R>::type \
+ operator op(const typename derived<Base>::type& lhs, \
+ typename rebind_any<Base, const U&>::type rhs) \
+ { \
+ return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs); \
+ } \
+ }; \
+ \
+ template<class T, class U, class R, class Base> \
+ struct concept_interface< \
+ name<T, U, R>, \
+ Base, \
+ U, \
+ typename ::boost::disable_if< \
+ ::boost::type_erasure::is_placeholder<T> >::type \
+ > : Base \
+ { \
+ friend typename rebind_any<Base, R>::type \
+ operator op(const T& lhs, \
+ const typename derived<Base>::type& rhs) \
+ { \
+ return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs); \
+ } \
+ };
+
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(addable, +)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(subtractable, -)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(multipliable, *)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(dividable, /)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(modable, %)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(left_shiftable, <<)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(right_shiftable, >>)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitandable, &)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitorable, |)
+BOOST_TYPE_ERASURE_BINARY_OPERATOR(bitxorable, ^)
+
+#undef BOOST_TYPE_ERASURE_BINARY_OPERATOR
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(name, op) \
+ template<class T = _self, class U = T> \
+ struct name \
+ { \
+ static void apply(T& lhs, const U& rhs) { lhs op rhs; } \
+ }; \
+ \
+ template<class T, class U, class Base> \
+ struct concept_interface<name<T, U>, Base, T> : Base \
+ { \
+ friend typename derived<Base>::type& \
+ operator op(typename derived<Base>::type& lhs, \
+ typename rebind_any<Base, const U&>::type rhs) \
+ { \
+ ::boost::type_erasure::call(name<T, U>(),lhs, rhs); \
+ return lhs; \
+ } \
+ }; \
+ \
+ template<class T, class U, class Base> \
+ struct concept_interface< \
+ name<T, U>, \
+ Base, \
+ U, \
+ typename ::boost::disable_if< \
+ ::boost::type_erasure::is_placeholder<T> >::type \
+ > : Base \
+ { \
+ friend T& \
+ operator op(T& lhs, const typename derived<Base>::type& rhs) \
+ { \
+ ::boost::type_erasure::call(name<T, U>(),lhs, rhs); \
+ return lhs; \
+ } \
+ };
+
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(add_assignable, +=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(subtract_assignable, -=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(multiply_assignable, *=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(divide_assignable, /=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(mod_assignable, %=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(left_shift_assignable, <<=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(right_shift_assignable, >>=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitand_assignable, &=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitor_assignable, |=)
+BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(bitxor_assignable, ^=)
+
+#undef BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR
+
+template<class T = _self, class U = T>
+struct equality_comparable
+{
+ static bool apply(const T& lhs, const U& rhs) { return lhs == rhs; }
+};
+
+/// \cond show_operators
+
+template<class T, class U, class Base>
+struct concept_interface<equality_comparable<T, U>, Base, T> : Base
+{
+ friend bool operator==(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const U&>::type rhs)
+ {
+ if(::boost::type_erasure::check_match(equality_comparable<T, U>(), lhs, rhs)) {
+ return ::boost::type_erasure::unchecked_call(equality_comparable<T, U>(), lhs, rhs);
+ } else {
+ return false;
+ }
+ }
+ friend bool operator!=(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const U&>::type rhs)
+ {
+ return !(lhs == rhs);
+ }
+};
+
+template<class T, class U, class Base>
+struct concept_interface<
+ equality_comparable<T, U>,
+ Base,
+ U,
+ typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<T> >::type
+> : Base
+{
+ friend bool operator==(const T& lhs, const typename derived<Base>::type& rhs)
+ {
+ return ::boost::type_erasure::call(equality_comparable<T, U>(), lhs, rhs);
+ }
+ friend bool operator!=(const T& lhs, const typename derived<Base>::type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+};
+
+/// \endcond
+
+template<class T = _self, class U = T>
+struct less_than_comparable
+{
+ static bool apply(const T& lhs, const U& rhs) { return lhs < rhs; }
+};
+
+namespace detail {
+
+template<class F, class T, class U>
+bool less_impl(const F& f, const T& lhs, const U& rhs, ::boost::mpl::true_)
+{
+ if(::boost::type_erasure::check_match(f, lhs, rhs)) {
+ return ::boost::type_erasure::unchecked_call(f, lhs, rhs);
+ } else {
+ return ::boost::type_erasure::typeid_of(
+ static_cast<const typename derived<T>::type&>(lhs)
+ ).before(
+ ::boost::type_erasure::typeid_of(
+ static_cast<const typename derived<U>::type&>(rhs)
+ )
+ ) != false;
+ }
+}
+
+template<class F, class T, class U>
+bool less_impl(const F& f, const T& lhs, const U& rhs, ::boost::mpl::false_)
+{
+ return ::boost::type_erasure::call(f, lhs, rhs);
+}
+
+}
+
+/// \cond show_operators
+
+template<class T, class Base>
+struct concept_interface<less_than_comparable<T, T>, Base, T> : Base
+{
+ friend bool operator<(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const T&>::type rhs)
+ {
+ return ::boost::type_erasure::detail::less_impl(
+ less_than_comparable<T, T>(),
+ lhs, rhs,
+ ::boost::type_erasure::is_relaxed<
+ typename ::boost::type_erasure::concept_of<Base>::type>());
+ }
+ friend bool operator>=(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const T&>::type rhs)
+ {
+ return !(lhs < rhs);
+ }
+ friend bool operator>(typename rebind_any<Base, const T&>::type lhs,
+ const typename derived<Base>::type& rhs)
+ {
+ return rhs < lhs;
+ }
+ friend bool operator<=(typename rebind_any<Base, const T&>::type lhs,
+ const typename derived<Base>::type& rhs)
+ {
+ return !(rhs < lhs);
+ }
+};
+
+template<class T, class U, class Base>
+struct concept_interface<less_than_comparable<T, U>, Base, T> : Base
+{
+ friend bool operator<(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const U&>::type rhs)
+ {
+ return ::boost::type_erasure::call(less_than_comparable<T, U>(), lhs, rhs);
+ }
+ friend bool operator>=(const typename derived<Base>::type& lhs,
+ typename rebind_any<Base, const U&>::type rhs)
+ {
+ return !(lhs < rhs);
+ }
+ friend bool operator>(typename rebind_any<Base, const U&>::type lhs,
+ const typename derived<Base>::type& rhs)
+ {
+ return rhs < lhs;
+ }
+ friend bool operator<=(typename rebind_any<Base, const U&>::type lhs,
+ const typename derived<Base>::type& rhs)
+ {
+ return !(rhs < lhs);
+ }
+};
+
+template<class T, class U, class Base>
+struct concept_interface<
+ less_than_comparable<T, U>,
+ Base,
+ U,
+ typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<T> >::type
+> : Base
+{
+ friend bool operator<(const T& lhs, const typename derived<Base>::type& rhs)
+ {
+ return ::boost::type_erasure::call(less_than_comparable<T, U>(), lhs, rhs);
+ }
+ friend bool operator>=(const T& lhs, const typename derived<Base>::type& rhs)
+ {
+ return !(lhs < rhs);
+ }
+ friend bool operator>(const typename derived<Base>::type& lhs, const T& rhs)
+ {
+ return rhs < lhs;
+ }
+ friend bool operator<=(const typename derived<Base>::type& lhs, const T& rhs)
+ {
+ return !(rhs < lhs);
+ }
+};
+
+/// \endcond
+
+template<class R, class T = _self, class N = std::ptrdiff_t>
+struct subscriptable
+{
+ static R apply(T& arg, const N& index) { return arg[index]; }
+};
+
+/// \cond show_operators
+
+template<class R, class T, class N, class Base>
+struct concept_interface<subscriptable<R, T, N>, Base, T> : Base
+{
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
+ typename ::boost::type_erasure::rebind_any<Base, const N&>::type index)
+ {
+ return ::boost::type_erasure::call(subscriptable<R, T, N>(), *this, index);
+ }
+};
+
+template<class R, class T, class N, class Base>
+struct concept_interface<subscriptable<R, const T, N>, Base, T> : Base
+{
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator[](
+ typename ::boost::type_erasure::rebind_any<Base, const N&>::type index) const
+ {
+ return ::boost::type_erasure::call(subscriptable<R, const T, N>(), *this, index);
+ }
+};
+
+/// \endcond
+
+/**
+ * The @ref ostreamable concept allows an @ref any to be
+ * written to a @c std::ostream.
+ */
+template<class Os = std::ostream, class T = _self>
+struct ostreamable
+{
+ static void apply(Os& out, const T& arg) { out << arg; }
+};
+
+/// \cond show_operators
+
+template<class Base, class Os, class T>
+struct concept_interface<ostreamable<Os, T>, Base, Os> : Base
+{
+ friend typename ::boost::type_erasure::derived<Base>::type&
+ operator<<(typename ::boost::type_erasure::derived<Base>::type& lhs,
+ typename ::boost::type_erasure::rebind_any<Base, const T&>::type rhs)
+ {
+ ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
+ return lhs;
+ }
+};
+
+template<class Base, class Os, class T>
+struct concept_interface<
+ ostreamable<Os, T>,
+ Base,
+ T,
+ typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<Os> >::type
+> : Base
+{
+ friend Os&
+ operator<<(Os& lhs,
+ const typename ::boost::type_erasure::derived<Base>::type& rhs)
+ {
+ ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
+ return lhs;
+ }
+};
+
+/// \endcond
+
+/**
+ * The @ref istreamable concept allows an @ref any to be
+ * read from a @c std::istream.
+ */
+template<class Is = std::istream, class T = _self>
+struct istreamable
+{
+ static void apply(Is& out, T& arg) { out >> arg; }
+};
+
+/// \cond show_operators
+
+
+template<class Base, class Is, class T>
+struct concept_interface<istreamable<Is, T>, Base, Is> : Base
+{
+ friend typename ::boost::type_erasure::derived<Base>::type&
+ operator>>(typename ::boost::type_erasure::derived<Base>::type& lhs,
+ typename ::boost::type_erasure::rebind_any<Base, T&>::type rhs)
+ {
+ ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
+ return lhs;
+ }
+};
+
+template<class Base, class Is, class T>
+struct concept_interface<
+ istreamable<Is, T>,
+ Base,
+ T,
+ typename ::boost::disable_if< ::boost::type_erasure::is_placeholder<Is> >::type
+> : Base
+{
+ friend Is&
+ operator>>(Is& lhs,
+ typename ::boost::type_erasure::derived<Base>::type& rhs)
+ {
+ ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
+ return lhs;
+ }
+};
+
+/// \endcond
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/placeholder.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/placeholder.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,76 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_PLACEHOLDERS_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_PLACEHOLDERS_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+/** INTERNAL ONLY */
+struct placeholder_base {};
+
+/**
+ * Placeholders are used heavily throughout the library.
+ * Every placeholder must derive from @ref placeholder
+ * using CRTP. The library provides a number of placeholders,
+ * out of the box, but you are welcome to define your own,
+ * if you want more descriptive names. The placeholder
+ * @ref _self is special in that it is used as the default
+ * wherever possible.
+ *
+ * What exactly is a placeholder? Placeholders act as
+ * a substitute for template parameters in concepts.
+ * The library automatically replaces all the placeholders
+ * used in a concept with the actual types involved when
+ * it stores an object in an @ref any.
+ *
+ * For example, in the following,
+ *
+ * @code
+ * any<copy_constructible<_a>, _a> x(1);
+ * @endcode
+ *
+ * The library sees that we're constructing an @ref any
+ * that uses the @ref _a placeholder with an @c int.
+ * Thus it binds @ref _a to int and instantiates
+ * @ref copy_constructible "copy_constructible<int>".
+ *
+ * When there are multiple placeholders involved, you
+ * will have to use @ref tuple, or pass the bindings
+ * explicitly, but the substitution still works the
+ * same way.
+ */
+template<class Derived>
+struct placeholder : placeholder_base {};
+
+struct _a : placeholder<_a> {};
+struct _b : placeholder<_b> {};
+struct _c : placeholder<_c> {};
+struct _d : placeholder<_d> {};
+struct _e : placeholder<_e> {};
+struct _f : placeholder<_f> {};
+struct _g : placeholder<_g> {};
+
+/**
+ * \brief The default placeholder
+ *
+ * @ref _self is the default @ref placeholder used
+ * by @ref any. It should be used as a default
+ * by most concepts, so using concepts with no
+ * explicit arguments will "just work" as much as
+ * possible.
+ */
+struct _self : placeholder<_self> {};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,48 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_PLACEHOLDER_OF_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_PLACEHOLDER_OF_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class T>
+class any;
+
+/**
+ * A metafunction returning the (const/reference qualified) placeholder
+ * corresponding to an @ref any. It will also work for all bases
+ * of @ref any, so it can be applied to the @c Base
+ * parameter of @ref concept_interface.
+ */
+template<class T>
+struct placeholder_of
+{
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+ typedef detail::unspecified type;
+#else
+ typedef typename ::boost::type_erasure::placeholder_of<
+ typename T::_boost_type_erasure_derived_type
+ >::type type;
+#endif
+};
+
+/** INTERNAL ONLY */
+template<class Concept, class T>
+struct placeholder_of< ::boost::type_erasure::any<Concept, T> >
+{
+ typedef T type;
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/rebind_any.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/rebind_any.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,60 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_REBIND_ANY_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_REBIND_ANY_HPP_INCLUDED
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/concept_of.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept, class T>
+class any;
+
+/**
+ * A metafunction that returns any type corresponding
+ * to a placeholder. If @c T is not a placeholder,
+ * returns @c T unchanged. This class is intended
+ * to be used in @ref concept_interface to deduce
+ * the argument types from the arguments of the concept.
+ *
+ * @pre Any must be a specialization of @ref any a base
+ * class of such a specialization.
+ */
+template<class Any, class T>
+struct rebind_any
+{
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+ typedef detail::unspecified type;
+#else
+ typedef typename ::boost::mpl::if_<
+ ::boost::type_erasure::is_placeholder<
+ typename ::boost::remove_cv<
+ typename ::boost::remove_reference<T>::type
+ >::type
+ >,
+ ::boost::type_erasure::any<
+ typename ::boost::type_erasure::concept_of<Any>::type,
+ T
+ >,
+ T
+ >::type type;
+#endif
+};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/relaxed_match.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/relaxed_match.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,88 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_RELAXED_MATCH_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_RELAXED_MATCH_HPP_INCLUDED
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class T>
+struct is_relaxed;
+
+namespace detail {
+
+template<class T>
+struct is_relaxed_impl :
+ ::boost::mpl::not_<
+ typename ::boost::is_same<
+ typename ::boost::mpl::find_if<
+ T,
+ ::boost::type_erasure::is_relaxed< ::boost::mpl::_1>
+ >::type,
+ typename ::boost::mpl::end<T>::type
+ >::type
+ >::type
+{};
+
+}
+
+/**
+ * This special concept does not have any behavior by
+ * itself. However it affects the behavior of other
+ * concepts. In the presence of this concept, the
+ * requirement that all the arguments to a function
+ * must match is relaxed. Instead, if there is a
+ * reasonable default implementation, it will be used,
+ * otherwise a @ref bad_function_call exception will
+ * be thrown.
+ *
+ * The following concepts have special behavior with
+ * this flag:
+ * - @ref assignable "assignable": If the types are not the same,
+ * it will fall back on copy and swap.
+ * - @ref equality_comparable "equality_comparable": If the types do not
+ * match, it will return false.
+ * - @ref less_than_comparable "less_than_comparable": If the types do not
+ * match, the ordering will be according to
+ * @c std::type_info::before.
+ */
+struct relaxed_match : ::boost::mpl::vector0<> {};
+
+/**
+ * A metafunction indicating whether @c Concept
+ * includes @ref relaxed_match.
+ */
+template<class Concept>
+struct is_relaxed :
+ ::boost::mpl::eval_if< ::boost::mpl::is_sequence<Concept>,
+ ::boost::type_erasure::detail::is_relaxed_impl<Concept>,
+ ::boost::mpl::false_
+ >::type
+{};
+
+/** INTERNAL ONLY */
+template<>
+struct is_relaxed< ::boost::type_erasure::relaxed_match> :
+ ::boost::mpl::true_
+{};
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/require_match.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/require_match.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,258 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_REQUIRE_MATCH_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_REQUIRE_MATCH_HPP_INCLUDED
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/type_erasure/detail/extract_concept.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/check_match.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Concept>
+class binding;
+
+/**
+ * Exception thrown when the arguments to a primitive concept
+ * are incorrect.
+ */
+struct bad_function_call : ::std::invalid_argument
+{
+ bad_function_call() : ::std::invalid_argument("bad_function_call") {}
+};
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+/**
+ * Checks that the actual types stored in all the @ref any
+ * arguments match the types specified by @c binding. If
+ * they do not match then,
+ * - If @ref relaxed_match is in @c Concept, throws @ref bad_function_call.
+ * - Otherwise the behavior is undefined.
+ *
+ * If @c binding is not specified, it will be deduced from
+ * the arguments.
+ *
+ * \post @c call(binding, concept, args...) is valid.
+ */
+template<class Concept, class Op, class... U>
+void require_match(const binding<Concept>& binding_arg, const Op& f, U&&... args);
+
+/**
+ * \overload
+ */
+template<class Op, class... U>
+void require_match(const Op& f, U&&... args);
+
+#else
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+namespace detail {
+
+template<class Concept, class Op, class... U>
+void require_match_impl(
+ ::boost::mpl::true_,
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& op,
+ U&... arg)
+{
+ if(!::boost::type_erasure::check_match(table, op, arg...)) {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
+ }
+}
+
+template<class Concept, class Op, class... U>
+void require_match_impl(
+ ::boost::mpl::false_,
+ const ::boost::type_erasure::binding<Concept>&,
+ const Op&,
+ U&...)
+{}
+
+template<class Op, class... U>
+void require_match_impl(
+ ::boost::mpl::true_,
+ const Op& op,
+ U&... arg)
+{
+ if(!::boost::type_erasure::check_match(op, arg...)) {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
+ }
+}
+
+template<class Op, class... U>
+void require_match_impl(
+ ::boost::mpl::false_,
+ const Op&,
+ U&...)
+{}
+
+}
+
+template<class Concept, class Op, class... U>
+void require_match(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& op,
+ U&... arg)
+{
+ ::boost::type_erasure::is_relaxed<Concept> cond;
+ ::boost::type_erasure::detail::require_match_impl(cond, table, op, arg...);
+}
+
+template<class Op, class... U>
+void require_match(
+ const Op& op,
+ U&... arg)
+{
+ ::boost::type_erasure::is_relaxed<
+ typename ::boost::type_erasure::detail::extract_concept<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ U...>::type
+ > cond;
+ ::boost::type_erasure::detail::require_match_impl(cond, op, arg...);
+}
+
+#else
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/require_match.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+#endif
+
+#endif
+
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+namespace detail {
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match_impl(
+ ::boost::mpl::true_,
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ if(!::boost::type_erasure::check_match
+ (table, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg))) {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
+ }
+}
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match_impl(
+ ::boost::mpl::false_,
+ const ::boost::type_erasure::binding<Concept>&,
+ const Op&
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & BOOST_PP_INTERCEPT))
+{}
+
+#if N != 0
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match_impl(
+ ::boost::mpl::true_,
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ if(!::boost::type_erasure::check_match
+ (op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg))) {
+ BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
+ }
+}
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match_impl(
+ ::boost::mpl::false_,
+ const Op&
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & BOOST_PP_INTERCEPT))
+{}
+
+#endif
+
+}
+
+template<
+ class Concept,
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match(
+ const ::boost::type_erasure::binding<Concept>& table,
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ ::boost::type_erasure::is_relaxed<Concept> cond;
+ ::boost::type_erasure::detail::require_match_impl
+ (cond, table, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#if N != 0
+
+template<
+ class Op
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+void require_match(
+ const Op& op
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, & arg))
+{
+ ::boost::type_erasure::is_relaxed<
+ typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
+ typename ::boost::type_erasure::detail::get_signature<Op>::type,
+ BOOST_PP_ENUM_PARAMS(N, U)>::type
+ > cond;
+ ::boost::type_erasure::detail::require_match_impl
+ (cond, op BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
+}
+
+#endif
+
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/static_binding.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/static_binding.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,36 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_STATIC_BINDING_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_STATIC_BINDING_HPP_INCLUDED
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * Represents a mapping from placeholders to the actual types
+ * that they bind to.
+ *
+ * \pre @c Map must be an MPL map whose keys are placeholders.
+ */
+template<class Map>
+struct static_binding {};
+
+/**
+ * A convenience function to prevent constructor calls
+ * from being parsed as function declarations.
+ */
+template<class Map>
+static_binding<Map> make_binding() { return static_binding<Map>(); }
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/tuple.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/tuple.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,389 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/map.hpp>
+#include <boost/fusion/include/category_of.hpp>
+#include <boost/fusion/include/iterator_facade.hpp>
+#include <boost/fusion/include/sequence_facade.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/static_binding.hpp>
+#include <boost/type_erasure/config.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/** INTERNAL ONLY */
+struct na {};
+
+namespace detail {
+
+template<int N, class Tuple>
+struct get_impl;
+
+template<class Concept,
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T, ::boost::type_erasure::na)>
+struct tuple_storage;
+
+}
+
+/** INTERNAL ONLY */
+template<class Tuple, int N>
+class tuple_iterator :
+ public ::boost::fusion::iterator_facade<
+ tuple_iterator<Tuple, N>,
+ ::boost::fusion::random_access_traversal_tag
+ >
+{
+public:
+ typedef ::boost::mpl::int_<N> index;
+ explicit tuple_iterator(Tuple& t_arg) : t(&t_arg) {}
+ template<class It>
+ struct value_of
+ {
+ typedef typename ::boost::type_erasure::detail::get_impl<
+ It::index::value,
+ Tuple
+ >::value_type type;
+ };
+ template<class It>
+ struct deref :
+ ::boost::type_erasure::detail::get_impl<It::index::value, Tuple>
+ {
+ typedef typename ::boost::type_erasure::detail::get_impl<
+ It::index::value,
+ Tuple
+ >::type type;
+ static type call(It it)
+ {
+ return ::boost::type_erasure::detail::get_impl<
+ It::index::value,
+ Tuple
+ >::call(*it.t);
+ }
+ };
+ template<class It, class M>
+ struct advance
+ {
+ typedef tuple_iterator<Tuple, (It::index::value+M::value)> type;
+ static type call(It it) { return type(*it.t); }
+ };
+ template<class It>
+ struct next : advance<It, ::boost::mpl::int_<1> > {};
+ template<class It>
+ struct prior : advance<It, ::boost::mpl::int_<-1> > {};
+ template<class It1, class It2>
+ struct distance
+ {
+ typedef typename ::boost::mpl::minus<
+ typename It2::index,
+ typename It1::index
+ >::type type;
+ static type call(It1, It2) { return type(); }
+ };
+private:
+ Tuple* t;
+};
+
+/** INTERNAL ONLY */
+template<class Derived>
+struct tuple_base :
+ ::boost::fusion::sequence_facade<
+ Derived,
+ ::boost::fusion::random_access_traversal_tag
+ >
+{
+ template<class Seq>
+ struct begin
+ {
+ typedef ::boost::type_erasure::tuple_iterator<Seq, 0> type;
+ static type call(Seq& seq) { return type(seq); }
+ };
+ template<class Seq>
+ struct end
+ {
+ typedef ::boost::type_erasure::tuple_iterator<
+ Seq,
+ Seq::tuple_size::value
+ > type;
+ static type call(Seq& seq) { return type(seq); }
+ };
+ template<class Seq>
+ struct size
+ {
+ typedef typename Seq::tuple_size type;
+ static type call(Seq& seq) { return type(); }
+ };
+ template<class Seq>
+ struct empty
+ {
+ typedef typename boost::mpl::equal_to<
+ typename Seq::tuple_size,
+ boost::mpl::int_<0>
+ >::type type;
+ static type call(Seq& seq) { return type(); }
+ };
+ template<class Seq, class N>
+ struct at : ::boost::type_erasure::detail::get_impl<N::value, Seq> {};
+ template<class Seq, class N>
+ struct value_at
+ {
+ typedef typename ::boost::type_erasure::detail::get_impl<
+ N::value,
+ Seq
+ >::value_type type;
+ };
+};
+
+#ifdef BOOST_TYPE_ERASURE_DOXYGEN
+
+/**
+ * @ref tuple is a Boost.Fusion Random Access Sequence containing
+ * @ref any "anys". Concept is interpreted in the same way as for
+ * @ref any. The remaining arguments must be (possibly const
+ * and/or reference qualified) placeholders.
+ */
+template<class Concept, class... T>
+class tuple
+{
+public:
+ /**
+ * Constructs a tuple. Each element of @c args will
+ * be used to initialize the corresponding member.
+ */
+ template<class... U>
+ explicit tuple(U&&... args);
+};
+
+template<int N, class Concept, class... T>
+any<Concept, TN>& get(tuple<Concept, T...>& arg);
+template<int N, class Concept, class... T>
+const any<Concept, TN>& get(const tuple<Concept, T...>& arg);
+
+#else
+
+template<class Concept,
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T, ::boost::type_erasure::na)>
+class tuple;
+
+template<
+ int N,
+ class Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T)
+>
+typename detail::get_impl<
+ N,
+ tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >
+>::type get(
+ tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >& arg)
+{
+ return detail::get_impl<
+ N,
+ tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >
+ >::call(arg);
+}
+
+template<
+ int N,
+ class Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T)
+>
+typename detail::get_impl<
+ N,
+ const tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >
+>::type get(
+ const tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >& arg)
+{
+ return detail::get_impl<
+ N,
+ const tuple<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T)
+ >
+ >::call(arg);
+}
+
+#endif
+
+/** INTERNAL ONLY */
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/tuple.hpp>
+/** INTERNAL ONLY */
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE)
+#include BOOST_PP_ITERATE()
+
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_TAG_TYPEDEF(z, n, data) \
+ typedef BOOST_PP_CAT(T, n) BOOST_PP_CAT(tag_type, n); \
+ typedef typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type \
+ BOOST_PP_CAT(tag, n);
+
+#define BOOST_TYPE_ERASURE_PAIR(z, n, data) \
+ ::boost::mpl::pair<BOOST_PP_CAT(tag, n), BOOST_PP_CAT(U, n)>
+
+#define BOOST_TYPE_ERASURE_CONSTRUCT(z, n, data)\
+ BOOST_PP_CAT(t, n)(BOOST_PP_CAT(u, n), table)
+
+#define BOOST_TYPE_ERASURE_MEMBER(z, n, data)\
+ ::boost::type_erasure::any<Concept, BOOST_PP_CAT(T, n)> BOOST_PP_CAT(t, n);
+
+#if N == 1
+#define BOOST_TYPE_ERASURE_EXPLICIT explicit
+#else
+#define BOOST_TYPE_ERASURE_EXPLICIT
+#endif
+
+namespace detail {
+
+template<class Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+struct tuple_storage
+#if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE
+ <Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>
+#endif
+{
+#if N
+ template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)>
+ tuple_storage(
+ const Table& table BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u))
+ :
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONSTRUCT, ~) {}
+#else
+ template<class Table>
+ explicit tuple_storage(const Table&) {}
+#endif
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_MEMBER, `)
+};
+
+#if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE
+
+template<class Tuple>
+struct get_impl<N, Tuple>
+{
+ typedef any<
+ typename Tuple::concept_type,
+ typename Tuple::BOOST_PP_CAT(tag_type, N)
+ > value_type;
+ typedef value_type& type;
+ static type call(Tuple& arg)
+ { return arg.impl.BOOST_PP_CAT(t, N); }
+};
+
+template<class Tuple>
+struct get_impl<N, const Tuple>
+{
+ typedef any<
+ typename Tuple::concept_type,
+ typename Tuple::BOOST_PP_CAT(tag_type, N)
+ > value_type;
+ typedef const value_type& type;
+ static type call(const Tuple& arg)
+ { return arg.impl.BOOST_PP_CAT(t, N); }
+};
+
+#endif
+
+}
+
+template<class Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+class tuple
+#if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE
+ <Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>
+#endif
+ : public tuple_base<tuple<Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> >
+{
+ typedef Concept concept_type;
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_TAG_TYPEDEF, ~)
+public:
+ typedef ::boost::mpl::int_<N> tuple_size;
+#if N
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+#endif
+ BOOST_TYPE_ERASURE_EXPLICIT
+ tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)) :
+ impl(
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map<
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~)
+ >
+ >()
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ {}
+#if N
+ template<BOOST_PP_ENUM_PARAMS(N, class U)>
+ BOOST_TYPE_ERASURE_EXPLICIT
+ tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &u)) :
+ impl(
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map<
+ BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~)
+ >
+ >()
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, u)
+ )
+ {}
+#endif
+private:
+ template<int M, class Tuple>
+ friend struct ::boost::type_erasure::detail::get_impl;
+ ::boost::type_erasure::detail::tuple_storage<
+ Concept
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, T)
+ > impl;
+};
+
+#undef BOOST_TYPE_ERASURE_EXPLICIT
+#undef BOOST_TYPE_ERASURE_MEMBER
+#undef BOOST_TYPE_ERASURE_CONSTRUCT
+#undef BOOST_TYPE_ERASURE_PAIR
+#undef BOOST_TYPE_ERASURE_TAG_TYPEDEF
+#undef N
+
+#endif

Added: sandbox/type_erasure/boost/type_erasure/typeid_of.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/typeid_of.hpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,56 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_TYPEID_OF_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_TYPEID_OF_HPP_INCLUDED
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_erasure/detail/access.hpp>
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/binding.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+/**
+ * The first form returns the type currently stored in an @ref any.
+ *
+ * The second form returns the type corresponding to a
+ * placeholder in @c binding.
+ *
+ * \pre @c Concept includes @ref typeid_ "typeid_<T>".
+ * \pre @c T is a non-reference, CV-unqualified @ref placeholder.
+ */
+template<class Concept, class T>
+const std::type_info& typeid_of(const any<Concept, T>& arg)
+{
+ return ::boost::type_erasure::detail::access::table(arg).template find<
+ ::boost::type_erasure::typeid_<
+ typename ::boost::remove_cv<
+ typename ::boost::remove_reference<T>::type
+ >::type
+ >
+ >()();
+}
+
+/**
+ * \overload
+ */
+template<class T, class Concept>
+const std::type_info& typeid_of(const binding<Concept>& binding_arg)
+{
+ return binding_arg.template find< ::boost::type_erasure::typeid_<T> >()();
+}
+
+}
+}
+
+#endif

Added: sandbox/type_erasure/libs/type_erasure/doc/Jamfile.jam
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/doc/Jamfile.jam 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,58 @@
+# Boost.TypeErasure library
+#
+# Copyright 2011 Steven Watanabe
+#
+# Distributed under the Boost Software License version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import path ;
+using boostbook ;
+using quickbook ;
+using doxygen ;
+
+path-constant here : . ;
+path-constant boost-root : ../../../../../trunk ;
+
+# Figure out where the root of the boost tree is relative
+# to the html directory.
+local BOOST_ROOT = [ path.relative-to
+ [ path.join [ path.pwd ] html ]
+ [ path.root
+ [ path.make $(boost-root) ]
+ [ path.pwd ] ] ] ;
+
+xml type_erasure : type_erasure.qbk ;
+
+doxygen reference
+ :
+ [ glob ../../../boost/type_erasure/*.hpp ]
+ :
+ <doxygen:param>EXPAND_ONLY_PREDEF=YES
+ <doxygen:param>"ALIASES= \\
+ CopyConstructible=\"<a href=\\\"$(BOOST_ROOT)/doc/html/CopyConstructible.html\\\">CopyConstructible</a>\" "
+ <doxygen:param>"PREDEFINED= \\
+ \"BOOST_TYPE_ERASURE_DOXYGEN=1\" \\
+ \"BOOST_TYPE_ERASURE_UNARY_INPLACE_OPERATOR(name, op)=template<class T = _self> struct name { static void apply(T&); };\" \\
+ \"BOOST_TYPE_ERASURE_UNARY_OPERATOR(name, op)=template<class T = _self, class R = T> struct name { static R apply(const T&); };\" \\
+ \"BOOST_TYPE_ERASURE_BINARY_OPERATOR(name, op)=template<class T = _self, class U = T, class R = T> struct name { static R apply(const T&, const U&); };\" \\
+ \"BOOST_TYPE_ERASURE_ASSIGNMENT_OPERATOR(name, op)=template<class T = _self, class U = T> struct name { static void apply(T&, const U&); };\" \\
+ \"table_arg=table\" \\
+ \"binding_arg=binding\" \\
+ \"data_arg=data\""
+ <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+ <doxygen:param>QUIET=YES
+ <doxygen:param>WARN_IF_UNDOCUMENTED=NO
+ <doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>ENABLE_PREPROCESSING=YES
+ <doxygen:param>MACRO_EXPANSION=YES
+ <doxygen:param>SEARCH_INCLUDES=NO
+;
+
+boostbook standalone
+ :
+ type_erasure
+ :
+ <dependency>reference
+ <xsl:param>boost.root=../../../..
+;

Added: sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/doc/type_erasure.qbk 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,297 @@
+[library Boost.TypeErasure
+ [quickbook 1.5]
+ [authors [Watanabe, Steven]]
+ [copyright 2011 Steven Watanabe]
+ [license
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ [@http://www.boost.org/LICENSE_1_0.txt])
+ ]
+ [purpose Runtime polymorphism based on concepts]
+]
+
+[def __any [classref boost::type_erasure::any any]]
+[def __any_cast [funcref boost::type_erasure::any_cast any_cast]]
+[def __tuple [classref boost::type_erasure::tuple tuple]]
+[def __rebind_any [classref boost::type_erasure::rebind_any rebind_any]]
+[def __derived [classref boost::type_erasure::derived derived]]
+[def __concept_interface [classref boost::type_erasure::concept_interface concept_interface]]
+[def __constructible [classref boost::type_erasure::constructible constructible]]
+[def __destructible [classref boost::type_erasure::destructible destructible]]
+[def __copy_constructible [classref boost::type_erasure::copy_constructible copy_constructible]]
+[def __typeid_ [classref boost::type_erasure::typeid_ typeid_]]
+[def __relaxed_match [classref boost::type_erasure::relaxed_match relaxed_match]]
+[def __binding [classref boost::type_erasure::binding binding]]
+[def __placeholder [classref boost::type_erasure::placeholder placeholder]]
+[def __call [funcref boost::type_erasure::call call]]
+
+[def __addable [classref boost::type_erasure::addable addable]]
+[def __subtractable [classref boost::type_erasure::subtractable subtractable]]
+[def __multipliable [classref boost::type_erasure::multipliable multipliable]]
+[def __dividable [classref boost::type_erasure::dividable dividable]]
+[def __modable [classref boost::type_erasure::modable modable]]
+[def __bitandable [classref boost::type_erasure::bitandable bitandable]]
+[def __bitorable [classref boost::type_erasure::bitorable bitorable]]
+[def __bitxorable [classref boost::type_erasure::bitxorable bitxorable]]
+[def __left_shiftable [classref boost::type_erasure::left_shiftable left_shiftable]]
+[def __right_shiftable [classref boost::type_erasure::right_shiftable right_shiftable]]
+[def __add_assignable [classref boost::type_erasure::add_assignable add_assignable]]
+[def __subtract_assignable [classref boost::type_erasure::subtract_assignable subtract_assignable]]
+[def __multiply_assignable [classref boost::type_erasure::multiply_assignable multiply_assignable]]
+[def __divide_assignable [classref boost::type_erasure::divide_assignable divide_assignable]]
+[def __mod_assignable [classref boost::type_erasure::mod_assignable mod_assignable]]
+[def __bitand_assignable [classref boost::type_erasure::bitand_assignable bitand_assignable]]
+[def __bitor_assignable [classref boost::type_erasure::bitor_assignable bitor_assignable]]
+[def __bitxor_assignable [classref boost::type_erasure::bitxor_assignable bitxor_assignable]]
+[def __left_shift_assignable [classref boost::type_erasure::left_shift_assignable left_shift_assignable]]
+[def __right_shift_assignable [classref boost::type_erasure::right_shift_assignable right_shift_assignable]]
+[def __incrementable [classref boost::type_erasure::incrementable incrementable]]
+[def __decrementable [classref boost::type_erasure::decrementable decrementable]]
+[def __negatable [classref boost::type_erasure::negatable negatable]]
+[def __complementable [classref boost::type_erasure::complementable complementable]]
+[def __dereferenceable [classref boost::type_erasure::dereferenceable dereferenceable]]
+[def __callable [classref boost::type_erasure::callable callable]]
+[def __subscriptable [classref boost::type_erasure::subscriptable subscriptable]]
+[def __equality_comparable [classref boost::type_erasure::equality_comparable equality_comparable]]
+[def __less_than_comparable [classref boost::type_erasure::less_than_comparable less_than_comparable]]
+[def __ostreamable [classref boost::type_erasure::ostreamable ostreamable]]
+[def __istreamable [classref boost::type_erasure::istreamable istreamable]]
+
+
+[section:introduction Introduction]
+
+C++ provides runtime polymorphism through virtual
+functions. They are a very useful feature, but
+they do have some limitations.
+
+* They are intrusive. In generic programming, we can
+ design an interface which allows third-party types
+ to be adapted to it.
+* They require dynamic memory management. Of course,
+ most of the problems can be avoided by using an
+ appropriate smart pointer type. Even so, it still
+ acts like a pointer rather than a value.
+* Virtual functions' ability to apply multiple
+ independent concepts to a single object is limited.
+
+The Boost.TypeErasure library solves these problems
+allowing us to mirror static generic programming
+at runtime.
+
+[note TypeErasure is not an official Boost library.]
+
+[endsect]
+
+[section:reading How to read this documentation]
+
+To avoid excessive verbosity, all the examples
+assume that a few using directives are in place.
+
+ namespace mpl = boost::mpl;
+ using namespace boost::type_erasure;
+
+[endsect]
+
+[section:basic Basic Usage]
+[import ../example/basic.cpp]
+[basic]
+[endsect]
+
+[section:multi Functions with Multiple Arguments]
+[import ../example/multi.cpp]
+[multi]
+[endsect]
+
+[section:references Using References]
+[import ../example/references.cpp]
+[references]
+[endsect]
+
+[section:construction Construction]
+[import ../example/construction.cpp]
+[construction]
+[endsect]
+
+[section:concept Concepts in Depth]
+
+[section:custom Defining Custom Concepts]
+[import ../example/custom.cpp]
+[custom]
+[endsect]
+
+[section:compose Composing Concepts]
+[import ../example/compose.cpp]
+[compose]
+[endsect]
+
+[section:concept_map Concept Maps]
+[import ../example/concept_map.cpp]
+[concept_map]
+[endsect]
+
+[section:overload Overloading]
+[import ../example/overload.cpp]
+[overload]
+[endsect]
+
+[endsect]
+
+[section:examples Examples]
+
+[section:print_sequence A polymorphic range formatter]
+[import ../example/print_sequence.cpp]
+[print_sequence]
+[endsect]
+
+[endsect]
+
+[section:predef Predefined Concepts]
+
+In the following tables, `T` and `U` are the types that the operation
+applies to, `R` is the result type. `T` always defaults
+to `_self` to match the default behavior of any. These
+concepts assume normal semantics. Thus, comparison
+operators always return bool, and references will be
+added to the arguments and results as appropriate.
+
+[table:special Special Members
+ [[concept][notes]]
+ [[__constructible`<Sig>`][-]]
+ [[__copy_constructible`<T>`][-]]
+ [[__destructible`<T>`][-]]
+ [[__typeid_`<T>`][-]]
+]
+[table:unary Unary Operators
+ [[operator][concept][notes]]
+ [[`operator++`][__incrementable`<T>`][There is no separate post-increment]]
+ [[`operator--`][__decrementable`<T>`][There is no separate post-decrement]]
+ [[`operator*`][__dereferenceable`<R, T>`][`R` should usually be a reference]]
+ [[`operator~`][__complementable`<T, R = T>`][-]]
+ [[`operator-`][__negatable`<T, R = T>`][-]]
+]
+
+[table:binary Binary Operators
+ [[operator][concept][notes]]
+ [[`operator+`][__addable`<T, U = T, R = T>`][-]]
+ [[`operator-`][__subtractable`<T, U = T, R = T>`][-]]
+ [[`operator*`][__multipliable`<T, U = T, R = T>`][-]]
+ [[`operator/`][__dividable`<T, U = T, R = T>`][-]]
+ [[`operator%`][__modable`<T, U = T, R = T>`][-]]
+ [[`operator&`][__bitandable`<T, U = T, R = T>`][-]]
+ [[`operator|`][__bitorable`<T, U = T, R = T>`][-]]
+ [[`operator^`][__bitxorable`<T, U = T, R = T>`][-]]
+ [[`operator<<`][__left_shiftable`<T, U = T, R = T>`][-]]
+ [[`operator>>`][__right_shiftable`<T, U = T, R = T>`][-]]
+ [[`operator==` and `!=`][__equality_comparable`<T, U = T>`][`!=` is implemented in terms of `==`]]
+ [[`operator<`, `>`, `<=`, and `>=`][__less_than_comparable`<T, U = T>`][All are implemented in terms of `<`]]
+ [[`operator+=`][__add_assignable`<T, U = T>`][-]]
+ [[`operator-=`][__subtract_assignable`<T, U = T>`][-]]
+ [[`operator*=`][__multiply_assignable`<T, U = T>`][-]]
+ [[`operator/=`][__divide_assignable`<T, U = T>`][-]]
+ [[`operator%=`][__mod_assignable`<T, U = T>`][-]]
+ [[`operator&=`][__bitand_assignable`<T, U = T>`][-]]
+ [[`operator|=`][__bitor_assignable`<T, U = T>`][-]]
+ [[`operator^=`][__bitxor_assignable`<T, U = T>`][-]]
+ [[`operator<<=`][__left_shift_assignable`<T, U = T>`][-]]
+ [[`operator>>=`][__right_shift_assignable`<T, U = T>`][-]]
+ [[`operator<<`][__ostreamable`<Os = std::ostream, T = _self>`][-]]
+ [[`operator>>`][__istreamable`<Is = std::istream, T = _self>`][-]]
+]
+
+[table:misc Miscellaneous Operators
+ [[operator][concept][notes]]
+ [[`operator()`][__callable`<Sig, T>`][`Sig` should be a function type. T may be const qualified.]]
+ [[`operator[]`][__subscriptable`<R, T, N = std::ptrdiff_t>`][`R` should usually be a reference. `T` can be optionally const qualified.]]
+]
+
+[endsect]
+
+[xinclude reference.xml]
+
+[section:rationale Rationale]
+
+[section Why do I have to specify the presence of a destructor explicitly?]
+When using references the destructor isn't needed.
+By not assuming it implicitly, we allow capturing
+types with private or protected destructors by reference.
+For the sake of consistency, it must be specified
+when capturing by value as well.
+[endsect]
+
+[section Why non-member functions?]
+The members of __any can be customized. By using
+free functions, we guarantee that we don't interfere
+with anything that a user might want.
+[endsect]
+
+[endsect]
+
+[section:feedback Feedback Wanted]
+
+There are a number of things that I'm not entirely
+happy about. Any thoughts about them would be
+greatly appreciated.
+
+* The name `_self`. Basically, I need some placeholder
+ to act as a default. Since placeholders act as a
+ substitute for template parameters, I'd really like
+ to use `_T`. Alack-a-day, `_T` is a reserved identifier.
+ `_self` was the best I could think of.
+* Implicit conversions. Implicit conversion from the
+ contained type to a reference any is not allowed.
+ The reason for this is that I found that such
+ conversions were interefering with overload resolution.
+ Getting overload resolution to work correctly in
+ the following would be a lot more difficult if
+ implicit conversion were allowed:
+ ``
+ typedef mpl::vector<
+ copy_constructible<>,
+ constructible<_self(const std::string&)>
+ > concept;
+ any<concept> x = ...;
+ any<concept> y(binding_of(x), "hello");
+ ``
+ Without great care we end up with an ambiguity
+ between the `std::string` constructor and the
+ copy constructor. User-defined overloaded
+ functions would also need to handle this somehow.
+ I decided that it was better to avoid the whole
+ problem by disabling implicit conversions.
+* __relaxed_match. I considered a lot of names
+ for this, `strict_match<false>`, `enable_mixed`,
+ `nonstrict_match`, `loose_match`, `best_effort`,
+ and probably more that I've forgotten. I'm not
+ really happy with any of them. I'm not really
+ happy about having it in `Concept` either, but
+ I'm not sure where else it could go. It's presence
+ can affect the contents of the vtable, so if it
+ we're a separate template argument, it would have
+ to be passed to __binding as well. It would generally
+ add complication.
+
+[endsect]
+
+[section:future Future Work]
+
+These are just some ideas. There is absolutely no
+guarantee that any of them will ever be implemented.
+
+* Use SBO.
+* Allow more control over vtable layout.
+* Attempt to reuse sub-tables in conversions.
+* Allow "dynamic_cast".
+* Allow deduction of placeholder bindings.
+* Use C++0x features. (Rvalue references and
+ variadic templates in particular.)
+* Optimize the compile-time cost.
+
+[endsect]
+
+
+[section:acknowledgements Acknowledgements]
+
+* The name `any` was taken from Alexander Nasonov's
+ DynamicAny library.
+
+[endsect]

Added: sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/Jamfile.jam 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,20 @@
+# Boost.TypeErasure library
+#
+# Copyright 2011 Steven Watanabe
+#
+# Distributed under the Boost Software License version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+compile basic.cpp ;
+compile multi.cpp ;
+compile references.cpp ;
+compile custom.cpp ;
+compile construction.cpp ;
+compile concept_map.cpp ;
+compile compose.cpp ;
+compile overload.cpp ;
+
+run print_sequence.cpp ;

Added: sandbox/type_erasure/libs/type_erasure/example/basic.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/basic.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,63 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/mpl/vector.hpp>
+#include <iostream>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+void basic1() {
+ //[basic1
+ /*`
+ The main class in the library is __any. We can just pass
+ it an MPL sequence containing all the concepts that we
+ wish to use.
+ */
+ any<mpl::vector<copy_constructible<>, typeid_<> > > x(10);
+ int i = any_cast<int>(x); // i == 10
+ /*`
+ __copy_constructible allows us to copy and destroy the
+ object. __typeid_ provides run-time type information
+ so that we can use __any_cast.
+ */
+ //]
+}
+
+void basic2() {
+ //[basic2
+ /*`
+ Now, this example doesn't do very much. `x` is approximately
+ equivalent to a [@boost:/libs/any/index.html boost::any].
+ Let's add a few more features.
+ */
+ any<
+ mpl::vector<
+ copy_constructible<>,
+ typeid_<>,
+ incrementable<>,
+ ostreamable<>
+ >
+ > x(10);
+ ++x;
+ std::cout << x << std::endl; // prints 11
+ //]
+}
+
+//[basic
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/basic.cpp basic.cpp])
+//` [basic1]
+//` [basic2]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/compose.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/compose.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,49 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/mpl/vector.hpp>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+//[compose1
+/*`
+ The basic concepts, like __copy_constructible and
+ __incrementable, are useful, but dealing with many
+ such concepts quickly gets cumbersome. Fortunately,
+ the library allows us to combine several concepts into
+ a single concept using an MPL sequence.
+*/
+template<class T = _self>
+struct arithmetic :
+ mpl::vector<
+ copy_constructible<T>,
+ addable<T>,
+ subtractable<T>,
+ multipliable<T>,
+ dividable<T>,
+ equality_comparable<T>,
+ less_than_comparable<T>
+ >
+{};
+/*`
+ Now, `arithmetic` can be used just like any
+ of the base concepts. We can even specialize
+ __concept_interface for it.
+*/
+//]
+
+//[compose
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/compose.cpp compose.cpp])
+//` [compose1]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/concept_map.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,42 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/operators.hpp>
+#include <typeinfo>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+//[concept_map1
+/*`
+ Sometimes it is useful to non-intrusively adapt a
+ type to model a concept. For example, suppose that
+ we want to make `std::type_info` model __less_than_comparable.
+ To do this, we simply specialize the concept definition.
+*/
+namespace boost {
+namespace type_erasure {
+
+template<>
+struct less_than_comparable<std::type_info>
+{
+ static bool apply(const std::type_info& lhs, const std::type_info& rhs)
+ { return lhs.before(rhs) != 0; }
+};
+
+}
+}
+//]
+
+//[concept_map
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/concept_map.cpp concept_map.cpp])
+//` [concept_map1]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/construction.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/construction.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,115 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/binding_of.hpp>
+#include <string>
+#include <vector>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+void construction1() {
+ //[construction1
+ /*`
+ The library provides the __constructible concept to
+ allow custom construction of __any. The single
+ template argument should be a function signature.
+ The return type must be a placeholder specifying
+ the type to be constructed. The arguments are
+ the arguments of the constructor.
+ */
+ typedef mpl::vector<
+ copy_constructible<_a>,
+ copy_constructible<_b>,
+ copy_constructible<_c>,
+ constructible<_a(const _b&, const _c&)>
+ > construct;
+
+ std::vector<double> vec;
+ int i = 10;
+ double d = 2.5;
+ tuple<construct, _a&, _b, _c> t(vec, i, d);
+ any<construct, _a> v(get<1>(t), get<2>(t));
+ //]
+}
+
+void construction2() {
+ typedef mpl::vector<
+ copy_constructible<_a>,
+ copy_constructible<_b>,
+ copy_constructible<_c>,
+ constructible<_a(const _b&, const _c&)>
+ > construct;
+ //[construction2
+ /*`
+ This requires us to create a vector to deduce
+ its type, even though the object is never used.
+ Instead, we can explicitly specify the types
+ that the placeholders should be bound to.
+ */
+ typedef mpl::map<
+ mpl::pair<_a, std::vector<double> >,
+ mpl::pair<_b, std::size_t>,
+ mpl::pair<_c, double>
+ > types;
+
+ any<construct, _b> size(10, make_binding<types>());
+ any<construct, _c> val(2.5, make_binding<types>());
+ any<construct, _a> v(size, val);
+ //]
+}
+
+void construction3() {
+ //[construction3
+ /*`
+ Now, suppose that we want a default constructor?
+ We can't have the default constructor of __any
+ call the default constructor of the contained type,
+ because it would have no way of knowing what the
+ contained type is. So, we'll need to pass
+ the placeholder binding information explicitly.
+ */
+ typedef mpl::vector<
+ copy_constructible<>,
+ constructible<_self()>
+ > construct;
+
+ any<construct> x(std::string("Test"));
+ any<construct> y(binding_of(x));
+ //]
+}
+
+void construction4() {
+ //[construction4
+ /*`
+ This method is not restricted to the default constructor. If
+ the constructor takes arguments, they can be passed after the
+ bindings.
+ */
+ typedef mpl::vector<
+ copy_constructible<>,
+ constructible<_self(std::size_t, char)>
+ > construct;
+
+ any<construct> x(std::string("Test"));
+ any<construct> y(binding_of(x), 5, 'A');
+ //]
+}
+
+//[construction
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/construction.cpp construction.cpp])
+//` [construction1]
+//` [construction2]
+//` [construction3]
+//` [construction4]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/custom.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/custom.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,90 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <vector>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+//[custom1
+/*`
+ Let's define a concept to allow push_back on a sequence.
+ To do this, we create a class template with a template
+ parameter for each argument, and a static member function
+ called `apply` that calls `push_back`.
+*/
+
+template<class C, class T>
+struct push_back
+{
+ static void apply(C& cont, const T& arg) { cont.push_back(arg); }
+};
+//]
+
+//[custom3
+/*`
+ This works, but we'd really like to call `c.push_back(10)`.
+ We can add members to __any by specializing __concept_interface.
+*/
+namespace boost {
+namespace type_erasure {
+template<class C, class T, class Base>
+struct concept_interface< ::push_back<C, T>, Base, C> : Base
+{
+ void push_back(typename rebind_any<Base, const T&>::type arg)
+ { call(::push_back<C, T>(), *this, arg); }
+};
+}
+}
+//]
+
+void custom2() {
+ //[custom2
+ /*`
+ Now, we can use this in an __any using
+ __call to dispatch the operation.
+ */
+ std::vector<int> vec;
+ any<push_back<_self, int>, _self&> c(vec);
+ int i = 10;
+ call(push_back<_self, int>(), c, i);
+ // vec is [10].
+ //]
+}
+
+void custom4() {
+ //[custom4
+ /*`
+ Note the use of __rebind_any to determine the argument
+ type. We could just use `T`, but that would fail when
+ `T` is a placeholder. __rebind_any does the work to
+ determine the correct type in that case. Our example
+ now becomes
+ */
+ std::vector<int> vec;
+ any<push_back<_self, int>, _self&> c(vec);
+ c.push_back(10);
+ /*`
+ which is what we want.
+ */
+ //]
+}
+
+//[custom
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/custom.cpp custom.cpp])
+//` [custom1]
+//` [custom2]
+//` [custom3]
+//` [custom4]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/multi.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/multi.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,79 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+#include <iostream>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+void multi1() {
+ //[multi1
+ /*`
+ Operations can have more than one __any argument.
+ Let's change the example from the previous section
+ to use binary addition, instead of increment.
+ */
+ typedef any<
+ mpl::vector<
+ copy_constructible<>,
+ typeid_<>,
+ addable<>,
+ ostreamable<>
+ >
+ > any_type;
+ any_type x(10);
+ any_type y(7);
+ any_type z(x + y);
+ std::cout << z << std::endl; // prints 17
+ /*`
+ The types of the arguments must match or the
+ behavior is undefined.
+ */
+ //]
+}
+
+void multi2() {
+ //[multi2
+ /*`
+ The operands do not all have to be the same type.
+ We can capture the relationships among several types.
+ To do this we'll need to identify each type with a
+ __placeholder. Also, we can no longer capture the
+ variables independently, since they are connected,
+ so we use __tuple to capture them all at once.
+ */
+ int array[5];
+
+ typedef mpl::vector<
+ copy_constructible<_a>,
+ copy_constructible<_b>,
+ typeid_<_a>,
+ addable<_a, _b, _a>
+ > requirements;
+
+ tuple<requirements, _a, _b> t(&array[0], 2);
+ any<requirements, _a> x(get<0>(t) + get<1>(t));
+ // x now holds array + 2
+ //]
+}
+
+
+//[multi
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/multi.cpp multi.cpp])
+//` [multi1]
+//` [multi2]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/overload.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/overload.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,161 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/concept_interface.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/derived.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+//[overload1
+/*`
+ Sometimes we want to use the same concept several times
+ with different parameters. Specializing __concept_interface
+ in a way that handles overloads correctly is a bit tricky.
+ Given a concept foo, we'd like the following to work:
+
+ ``
+ any<
+ mpl::vector<
+ foo<_self, int>,
+ foo<_self, double>,
+ copy_constructible<>
+ >
+ > x = ...;
+ x.foo(1); // calls foo(int)
+ x.foo(1.0); // calls foo(double)
+ ``
+
+ Because __concept_interface creates a linear
+ inheritance chain, without some extra work,
+ one overload of foo will hide the other.
+
+ Here are the techniques that I found work reliably.
+
+ For member functions I couldn't find a way to
+ avoid using two specializations.
+*/
+
+template<class T, class U>
+struct foo
+{
+ static void apply(T& t, const U& u) { t.foo(u); }
+};
+
+namespace boost {
+namespace type_erasure {
+
+template<class T, class U, class Base, class Enable>
+struct concept_interface< ::foo<T, U>, Base, T, Enable>
+{
+ typedef void _fun_defined;
+ void foo(typename rebind_any<Base, const U&>::type arg)
+ {
+ call(::foo<T, U>(), *this, arg);
+ }
+};
+
+template<class T, class U, class Base>
+struct concept_interface< ::foo<T, U>, Base, T, typename Base::_fun_defined>
+{
+ using Base::foo;
+ void foo(typename rebind_any<Base, const U&>::type arg)
+ {
+ call(::foo<T, U>(), *this, arg);
+ }
+};
+
+}
+}
+
+/*`
+ This uses SFINAE to detect whether a using declaration is
+ needed. Another solution to the problem that I've used
+ in the past is to inject a dummy declaration of `fun`
+ and always put in a using declaration. This is an
+ inferior solution for several reasons. It requires an
+ extra interface to add the dummy overload. It also
+ means that `fun` is always overloaded, even if the
+ user only asked for one overload. This makes it
+ harder to take the address of fun.
+
+ Note that while using SFINAE requires some code
+ to be duplicated, the amount of code that has to
+ be duplicated is relatively small, since the implementation
+ of __concept_interface is usually a one liner. It's
+ a bit annoying, but I believe it's an acceptable cost
+ in lieu of a better solution.
+*/
+
+//]
+//[overload2
+/*`
+ For free functions you can use inline friends.
+*/
+
+template<class T, class U>
+struct bar_concept
+{
+ static void apply(T& t, const U& u) { bar(t, u); }
+};
+
+namespace boost {
+namespace type_erasure {
+
+template<class T, class U, class Base>
+struct concept_interface< ::bar_concept<T, U>, Base, T>
+{
+ friend void bar(typename derived<Base>::type& t, typename rebind_any<Base, const U&>::type u)
+ {
+ call(::bar_concept<T, U>(), t, u);
+ }
+};
+
+template<class T, class U, class Base>
+struct concept_interface< ::bar_concept<T, U>, Base, U, typename boost::disable_if<is_placeholder<T> >::type>
+{
+ using Base::bar;
+ friend void bar(T& t, const typename derived<Base>::type& u)
+ {
+ call(::bar_concept<T, U>(), t, u);
+ }
+};
+
+}
+}
+
+/*`
+ Basically we have to specialize __concept_interface once for
+ each argument to make sure that an overload is injected into
+ the first argument that's a placeholder.
+ As you might have noticed, the argument types are a bit tricky.
+ In the first specialization, the first argument uses __derived
+ instead of __rebind_any. The reason for this is that if we used
+ __rebind_any, then we could end up violating the one definition
+ rule by defining the same function twice. Similarly, we use
+ SFINAE in the second specialization to make sure that bar is
+ only defined once when both arguments are placeholders.
+
+ At first I tried overloading `bar` at namespace scope. This
+ seems like a more obvious solution at first. Don't use it.
+ It doesn't work with overloads.
+*/
+
+//]
+
+//[overload
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/overload.cpp overload.cpp])
+//` [overload1]
+//` [overload2]
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/print_sequence.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/print_sequence.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,216 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+//[print_sequence
+
+/*`
+ (For the source of this example see
+ [@boost:/libs/type_erasure/example/print_sequence.cpp print_sequence.cpp])
+
+ This example demonstrates using Boost.TypeErasure to implement a
+ virtual "template" function.
+*/
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/iterator.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <iostream>
+#include <iomanip>
+#include <vector>
+
+using namespace boost::type_erasure;
+
+struct _t : placeholder<_t> {};
+struct _iter : placeholder<_iter> {};
+struct _os : placeholder<_os> {};
+
+template<class T, class U = _self>
+struct base_and_derived
+{
+ static T& apply(U& arg) { return arg; }
+};
+
+namespace boost {
+namespace type_erasure {
+
+template<class T, class U, class Base>
+struct concept_interface<base_and_derived<T, U>, Base, U> : Base
+{
+ operator typename rebind_any<Base, const T&>::type() const
+ {
+ return call(base_and_derived<T, U>(), const_cast<concept_interface&>(*this));
+ }
+ operator typename rebind_any<Base, T&>::type()
+ {
+ return call(base_and_derived<T, U>(), *this);
+ }
+};
+
+}
+}
+
+class abstract_printer {
+public:
+ // Range must be a Forward Range whose elements can be printed to os.
+ template<class CharT, class Traits, class Range>
+ void print(std::basic_ostream<CharT, Traits>& os, const Range& r) const {
+ // Capture the argument types
+ typedef typename boost::range_iterator<const Range>::type iter;
+ typedef typename boost::range_value<const Range>::type val;
+ typedef boost::mpl::map<
+ boost::mpl::pair<_os, std::basic_ostream<CharT, Traits> >,
+ boost::mpl::pair<_iter, iter>,
+ boost::mpl::pair<_t, val>
+ > types;
+ ostream_type any_os(os, make_binding<types>());
+ iterator_type first(boost::begin(r), make_binding<types>());
+ iterator_type last(boost::end(r), make_binding<types>());
+ // and forward to the real implementation
+ do_print(any_os, first, last);
+ }
+ virtual ~abstract_printer() {}
+protected:
+ typedef boost::mpl::vector<
+ base_and_derived<std::ios_base, _os>,
+ ostreamable<_os, _t>,
+ ostreamable<_os, const char*>,
+ forward_iterator<_iter, _t, std::ptrdiff_t, const _t*, const _t&>
+ > requirements;
+ typedef boost::type_erasure::any<requirements, _os&> ostream_type;
+ typedef boost::type_erasure::any<requirements, _iter> iterator_type;
+ virtual void do_print(
+ ostream_type os, iterator_type first, iterator_type last) const = 0;
+};
+
+class separator_printer : public abstract_printer {
+public:
+ explicit separator_printer(const std::string& sep) : separator(sep) {}
+protected:
+ virtual void do_print(
+ ostream_type os, iterator_type first, iterator_type last) const {
+ if(first != last) {
+ os << *first;
+ ++first;
+ for(; first != last; ++first) {
+ os << separator.c_str() << *first;
+ }
+ }
+ }
+private:
+ std::string separator;
+};
+
+class column_separator_printer : public abstract_printer {
+public:
+ column_separator_printer(const std::string& sep, std::size_t num_columns)
+ : separator(sep),
+ cols(num_columns)
+ {}
+protected:
+ virtual void do_print(
+ ostream_type os, iterator_type first, iterator_type last) const {
+ std::size_t count = 0;
+ for(; first != last; ++first) {
+ os << *first;
+ boost::type_erasure::any<requirements, _iter> temp = first;
+ ++temp;
+ if(temp != last) {
+ os << separator.c_str();
+ }
+ if(++count % cols == 0) {
+ os << "\n";
+ }
+ }
+ }
+private:
+ std::string separator;
+ std::size_t cols;
+};
+
+class aligned_column_printer : public abstract_printer {
+public:
+ aligned_column_printer(std::size_t column_width, std::size_t num_columns)
+ : width(column_width),
+ cols(num_columns)
+ {}
+protected:
+ virtual void do_print(
+ ostream_type os, iterator_type first, iterator_type last) const
+ {
+ if(first == last) return;
+ std::vector<iterator_type> column_iterators;
+
+ // find the tops of the columns
+ std::size_t count = 0;
+ for(iterator_type iter = first; iter != last; ++iter) {
+ ++count;
+ }
+ std::size_t rows = (count + cols - 1) / cols;
+ count = 0;
+ for(iterator_type iter = first; iter != last; ++iter) {
+ if(count % rows == 0) {
+ column_iterators.push_back(iter);
+ }
+ ++count;
+ }
+
+ iterator_type last_col = column_iterators.back();
+
+ // print the full rows
+ while(column_iterators.back() != last) {
+ for(std::vector<iterator_type>::iterator
+ iter = column_iterators.begin(),
+ end = column_iterators.end(); iter != end; ++iter)
+ {
+ static_cast<std::ios_base&>(os).width(width);
+ os << **iter;
+ ++*iter;
+ }
+ os << "\n";
+ }
+
+ // print the rows that are missing the last column
+ column_iterators.pop_back();
+ if(!column_iterators.empty()) {
+ while(column_iterators.back() != last_col) {
+ for(std::vector<iterator_type>::iterator
+ iter = column_iterators.begin(),
+ end = column_iterators.end(); iter != end; ++iter)
+ {
+ static_cast<std::ios_base&>(os).width(width);
+ os << **iter;
+ ++*iter;
+ }
+ os << "\n";
+ }
+ }
+ }
+private:
+ std::size_t width;
+ std::size_t cols;
+};
+
+int main() {
+ int test[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ separator_printer p1(",");
+ p1.print(std::cout, test);
+ std::cout << std::endl;
+ column_separator_printer p2(",", 4);
+ p2.print(std::cout, test);
+ std::cout << std::endl;
+ aligned_column_printer p3(16, 4);
+ p3.print(std::cout, test);
+}
+
+//]

Added: sandbox/type_erasure/libs/type_erasure/example/references.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/example/references.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,150 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iostream>
+
+namespace mpl = boost::mpl;
+using namespace boost::type_erasure;
+
+void references1() {
+ //[references1
+ /*`
+ To capture by reference, we simply add a reference
+ to the placeholder.
+ */
+ int i;
+ any<typeid_<>, _self&> x(i);
+ any_cast<int&>(x) = 5; // now i is 5
+ //]
+}
+
+void references2() {
+ //[references2
+ /*`
+ References are not assignable. Just like a built-in C++ reference,
+ once you've initialized it you can't change it to point to
+ something else.
+ ``
+ int i, j;
+ any<typeid_<>, _self&> x(i), y(j);
+ x = y; // error
+ ``
+ */
+ //]
+}
+
+void references3() {
+ //[references3
+ /*`
+ A reference can be bound to another __any.
+ */
+ typedef mpl::vector<
+ copy_constructible<>,
+ incrementable<>
+ > requirements;
+
+ any<requirements> x(10);
+ any<requirements, _self&> y(x);
+ ++y; // x is now 11
+ //]
+}
+
+void references4() {
+ //[references4
+ /*`
+ If a reference is used after the underlying object
+ goes out of scope or is reset, the behavior is undefined.
+ */
+ typedef mpl::vector<
+ copy_constructible<>,
+ incrementable<>,
+ relaxed_match
+ > requirements;
+ any<requirements> x(10);
+ any<requirements, _self&> y(x);
+ x = 1.0;
+ ++y; // undefined behavior.
+ //]
+}
+
+void references5() {
+ typedef mpl::vector<
+ copy_constructible<>,
+ incrementable<>
+ > requirements;
+ //[references5
+ /*`
+ This only applies when a reference is constructed
+ from a value. If a reference is constructed from another
+ reference, the new reference does not depend on the old one.
+ */
+ any<requirements> x(10);
+ boost::shared_ptr<any<requirements, _self&> > p(
+ new any<requirements, _self&>(x));
+ any<requirements, _self&> y(*p); // equivalent to y(x);
+ p.reset();
+ ++y; // okay
+ //]
+}
+
+void references6() {
+ //[references6
+ /*`
+ Both const and non-const references are supported.
+ */
+ int i = 0;
+ any<incrementable<>, _self&> x(i);
+ any<incrementable<>, const _self&> y(x);
+ /*`
+ A reference to non-const can be converted to a reference
+ to const, but not the other way around. Naturally,
+ we can't apply mutating operations to a const reference.
+
+ any<incrementable<>, _self&> z(y); // error
+ ++y; // error
+
+ There is one subtlety about this. The proxy reference
+ can have its own const qualifiers. In most cases,
+ the effect is cumulative.
+ */
+ const any<incrementable<>, _self&> z(x);
+ /*`
+ `z` is treated as a reference to const even though we
+ used `_self&` instead of `const _self&`.
+
+ ++z; // error
+
+ The one exception to this is the constructor. The
+ following is well-formed, even though `z` is const.
+ */
+ any<incrementable<>, _self&> w(z);
+ /*`
+ This behavior is not ideal, but anything else
+ is much too difficult to implement.
+ */
+ //]
+}
+
+//[references
+//` (For the source of the examples in this section see
+//` [@boost:/libs/type_erasure/example/references.cpp references.cpp])
+//` [references1]
+//` [references2]
+//` [references3]
+//` [references4]
+//` [references5]
+//` [references6]
+//]

Added: sandbox/type_erasure/libs/type_erasure/index.html
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/index.html 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,20 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+doc/html/index.html
+<hr>
+<tt>
+Boost.TypeErasure<br>
+<br>
+Copyright (C) 2011 Steven Watanabe <br>
+<br>
+Distributed under the Boost Software License, Version 1.0. (See
+accompanying file LICENSE_1_0.txt or copy at
+<a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt>) <br>
+<br>
+</tt>
+</body>
+</html>

Added: sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,49 @@
+# Boost.TypeErasure library
+#
+# Copyright 2011 Steven Watanabe
+#
+# Distributed under the Boost Software License version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+#
http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+run test_increment.cpp /boost//unit_test_framework ;
+run test_add.cpp /boost//unit_test_framework ;
+run test_add_assign.cpp /boost//unit_test_framework ;
+run test_callable.cpp /boost//unit_test_framework ;
+run test_reference.cpp /boost//unit_test_framework ;
+run test_construct.cpp /boost//unit_test_framework ;
+run test_relaxed_match.cpp /boost//unit_test_framework ;
+run test_assign.cpp /boost//unit_test_framework ;
+run test_construct_ref.cpp /boost//unit_test_framework ;
+run test_construct_cref.cpp /boost//unit_test_framework ;
+run test_any_cast.cpp /boost//unit_test_framework ;
+run test_binding_of.cpp /boost//unit_test_framework ;
+run test_typeid_of.cpp /boost//unit_test_framework ;
+run test_nested.cpp /boost//unit_test_framework ;
+run test_less.cpp /boost//unit_test_framework ;
+run test_equal.cpp /boost//unit_test_framework ;
+run test_negate.cpp /boost//unit_test_framework ;
+run test_dereference.cpp /boost//unit_test_framework ;
+run test_subscript.cpp /boost//unit_test_framework ;
+run test_forward_iterator.cpp /boost//unit_test_framework ;
+run test_tuple.cpp /boost//unit_test_framework ;
+run test_stream.cpp /boost//unit_test_framework ;
+
+compile-fail fail_increment_discard_const.cpp ;
+
+compile-fail fail_ref_discard_const.cpp ;
+compile-fail fail_ref_discard_const_convert.cpp ;
+compile-fail fail_ref_discard_const_convert_ref.cpp ;
+compile-fail fail_ref_discard_const_convert_cref.cpp ;
+compile-fail fail_ref_discard_const_init.cpp ;
+
+compile-fail fail_any_cast_discard_const1.cpp ;
+compile-fail fail_any_cast_discard_const2.cpp ;
+compile-fail fail_any_cast_discard_const3.cpp ;
+compile-fail fail_any_cast_discard_const4.cpp ;
+compile-fail fail_any_cast_discard_const5.cpp ;
+compile-fail fail_any_cast_discard_const6.cpp ;
+compile-fail fail_any_cast_pointer_to_ref.cpp ;
+compile-fail fail_any_cast_pointer_to_val.cpp ;

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const1.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const1.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const any< ::boost::mpl::vector<copy_constructible<>, typeid_<> > > y(2);
+ int i = any_cast<int&>(y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const2.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const2.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const any< ::boost::mpl::vector<copy_constructible<>, typeid_<> > > y(2);
+ int i = *any_cast<int*>(&y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const3.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const3.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,23 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 2;
+ any< ::boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> y(i);
+ int j = any_cast<int&>(y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const4.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const4.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,23 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 2;
+ const any< ::boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> y(i);
+ int j = any_cast<int&>(y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const5.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const5.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,23 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 2;
+ any< ::boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> y(i);
+ int j = *any_cast<int*>(&y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const6.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_discard_const6.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,23 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 2;
+ const any< ::boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> y(i);
+ int j = *any_cast<int*>(&y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_ref.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_ref.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ any< ::boost::mpl::vector<copy_constructible<>, typeid_<> > > y(2);
+ int i = any_cast<int&>(&y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_val.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_any_cast_pointer_to_val.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ any< ::boost::mpl::vector<copy_constructible<>, typeid_<> > > y(2);
+ int i = any_cast<int>(&y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_increment_discard_const.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_increment_discard_const.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,21 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/operators.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const int i = 0;
+ any<incrementable<>, const _self&> x(i);
+ ++x;
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,21 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const any<copy_constructible<> > x(1);
+ any<copy_constructible<>, _self&> y(x);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,21 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const any<boost::mpl::vector<copy_constructible<>, typeid_<> > > x(1);
+ any<copy_constructible<>, _self&> y(x);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_cref.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_cref.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 1;
+ const any<boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> x(i);
+ any<copy_constructible<>, _self&> y(x);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_ref.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_convert_ref.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,22 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ int i = 1;
+ any<boost::mpl::vector<copy_constructible<>, typeid_<> >, const _self&> x(i);
+ any<copy_constructible<>, _self&> y(x);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_init.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/fail_ref_discard_const_init.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,21 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/mpl/vector.hpp>
+
+using namespace boost::type_erasure;
+
+int main()
+{
+ const int i = 1;
+ any<copy_constructible<>, _self&> y(i);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_add.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_add.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,118 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ destructible<T>,
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_same)
+{
+ typedef ::boost::mpl::vector<common<>, addable<> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+ any<test_concept> z(x + y);
+ int i = any_cast<int>(z);
+ BOOST_CHECK_EQUAL(i, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_int1)
+{
+ typedef ::boost::mpl::vector<common<>, addable<_self, int> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> z(x + 2);
+ int i = any_cast<int>(z);
+ BOOST_CHECK_EQUAL(i, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_int2)
+{
+ typedef ::boost::mpl::vector<common<>, addable<int, _self, _self> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> z(2 + x);
+ int i = any_cast<int>(z);
+ BOOST_CHECK_EQUAL(i, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed)
+{
+ typedef ::boost::mpl::vector<common<_a>, common<_b>, addable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> x(1.0, 2);
+ any<test_concept, _a> z(get<0>(x) + get<1>(x));
+ double d = any_cast<double>(z);
+ BOOST_CHECK_EQUAL(d, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ common<_b>,
+ addable<_a>,
+ addable<_a, int>,
+ addable<int, _a, _a>,
+ addable<_b>,
+ addable<_b, int>,
+ addable<int, _b, _b>,
+ addable<_a, _b>
+ > test_concept;
+ tuple<test_concept, _a, _b> t(1.0, 2);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ {
+ any<test_concept, _a> z(x + x);
+ BOOST_CHECK_EQUAL(any_cast<double>(z), 2.0);
+ }
+
+ {
+ any<test_concept, _a> z(x + 3);
+ BOOST_CHECK_EQUAL(any_cast<double>(z), 4.0);
+ }
+
+ {
+ any<test_concept, _a> z(3 + x);
+ BOOST_CHECK_EQUAL(any_cast<double>(z), 4.0);
+ }
+
+ {
+ any<test_concept, _b> z(y + y);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ }
+
+ {
+ any<test_concept, _b> z(y + 3);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 5);
+ }
+
+ {
+ any<test_concept, _b> z(3 + y);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 5);
+ }
+
+ {
+ any<test_concept, _a> z(x + y);
+ BOOST_CHECK_EQUAL(any_cast<double>(z), 3);
+ }
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_add_assign.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_add_assign.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,140 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ destructible<T>,
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_same)
+{
+ typedef ::boost::mpl::vector<common<>, add_assignable<> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+ any<test_concept>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 3);
+ BOOST_CHECK_EQUAL(&x, &z);
+}
+
+BOOST_AUTO_TEST_CASE(test_int1)
+{
+ typedef ::boost::mpl::vector<common<>, add_assignable<_self, int> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept>& z(x += 2);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 3);
+ BOOST_CHECK_EQUAL(&x, &z);
+}
+
+BOOST_AUTO_TEST_CASE(test_int2)
+{
+ typedef ::boost::mpl::vector<common<>, add_assignable<int, _self> > test_concept;
+ int x = 1;
+ any<test_concept> y(2);
+ int& z(x += y);
+ BOOST_CHECK_EQUAL(x, 3);
+ BOOST_CHECK_EQUAL(&x, &z);
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed)
+{
+ typedef ::boost::mpl::vector<common<_a>, common<_b>, add_assignable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(1.0, 2);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+ any<test_concept, _a>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 3.0);
+ BOOST_CHECK_EQUAL(&x, &z);
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ common<_b>,
+ add_assignable<_a>,
+ add_assignable<_a, int>,
+ add_assignable<double, _a>,
+ add_assignable<_b>,
+ add_assignable<_b, int>,
+ add_assignable<double, _b>,
+ add_assignable<_a, _b>
+ > test_concept;
+ tuple<test_concept, _a, _b> t(1.0, 2);
+
+ {
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _a> y(get<0>(t));
+ any<test_concept, _a>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 2.0);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ any<test_concept, _a> x(get<0>(t));
+ int y = 5;
+ any<test_concept, _a>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 6.0);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ double x = 11;
+ any<test_concept, _a> y(get<0>(t));
+ double& z(x += y);
+ BOOST_CHECK_EQUAL(x, 12);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ any<test_concept, _b> x(get<1>(t));
+ any<test_concept, _b> y(get<1>(t));
+ any<test_concept, _b>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ any<test_concept, _b> x(get<1>(t));
+ int y = 5;
+ any<test_concept, _b>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 7);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ double x = 11;
+ any<test_concept, _b> y(get<1>(t));
+ double& z(x += y);
+ BOOST_CHECK_EQUAL(x, 13);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+
+ {
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+ any<test_concept, _a>& z(x += y);
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 3.0);
+ BOOST_CHECK_EQUAL(&x, &z);
+ }
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_any_cast.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_any_cast.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,168 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_value_to_value)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(2);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ BOOST_CHECK_THROW(any_cast<double>(x), bad_any_cast);
+ const any<test_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 2);
+ BOOST_CHECK_THROW(any_cast<double>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_value_to_ref)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(2);
+ BOOST_CHECK_EQUAL(any_cast<int&>(x), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(x), 2);
+ BOOST_CHECK_THROW(any_cast<double&>(x), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(x), bad_any_cast);
+ const any<test_concept> y(x);
+ // BOOST_CHECK_EQUAL(any_cast<int&>(y), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(y), 2);
+ // BOOST_CHECK_THROW(any_cast<double&>(y), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_value_to_pointer)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(2);
+ BOOST_CHECK_EQUAL(*any_cast<int*>(&x), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&x), 2);
+ BOOST_CHECK_EQUAL(any_cast<void*>(&x), any_cast<int*>(&x));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&x), any_cast<const int*>(&x));
+ BOOST_CHECK_EQUAL(any_cast<double*>(&x), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&x), (double*)0);
+ const any<test_concept> y(x);
+ // BOOST_CHECK_EQUAL(*any_cast<int*>(&y), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&y), 2);
+ // BOOST_CHECK_EQUAL(any_cast<void*>(&y), any_cast<int*>(&y));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&y), any_cast<const int*>(&y));
+ // BOOST_CHECK_EQUAL(any_cast<double*>(&y), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&y), (double*)0);
+}
+
+BOOST_AUTO_TEST_CASE(test_ref_to_value)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ BOOST_CHECK_THROW(any_cast<double>(x), bad_any_cast);
+ const any<test_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 2);
+ BOOST_CHECK_THROW(any_cast<double>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_ref_to_ref)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int&>(x), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(x), 2);
+ BOOST_CHECK_THROW(any_cast<double&>(x), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(x), bad_any_cast);
+ const any<test_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int&>(y), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(y), 2);
+ BOOST_CHECK_THROW(any_cast<double&>(y), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_ref_to_pointer)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(*any_cast<int*>(&x), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&x), 2);
+ BOOST_CHECK_EQUAL(any_cast<void*>(&x), any_cast<int*>(&x));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&x), any_cast<const int*>(&x));
+ BOOST_CHECK_EQUAL(any_cast<double*>(&x), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&x), (double*)0);
+ const any<test_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(*any_cast<int*>(&y), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&y), 2);
+ BOOST_CHECK_EQUAL(any_cast<void*>(&y), any_cast<int*>(&y));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&y), any_cast<const int*>(&y));
+ BOOST_CHECK_EQUAL(any_cast<double*>(&y), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&y), (double*)0);
+}
+
+BOOST_AUTO_TEST_CASE(test_cref_to_value)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ BOOST_CHECK_THROW(any_cast<double>(x), bad_any_cast);
+ const any<test_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 2);
+ BOOST_CHECK_THROW(any_cast<double>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_cref_to_ref)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, const _self&> x(i);
+ // BOOST_CHECK_EQUAL(any_cast<int&>(x), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(x), 2);
+ // BOOST_CHECK_THROW(any_cast<double&>(x), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(x), bad_any_cast);
+ const any<test_concept, const _self&> y(x);
+ // BOOST_CHECK_EQUAL(any_cast<int&>(y), 2);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(y), 2);
+ // BOOST_CHECK_THROW(any_cast<double&>(y), bad_any_cast);
+ BOOST_CHECK_THROW(any_cast<const double&>(y), bad_any_cast);
+}
+
+BOOST_AUTO_TEST_CASE(test_cref_to_pointer)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 2;
+ any<test_concept, const _self&> x(i);
+ // BOOST_CHECK_EQUAL(*any_cast<int*>(&x), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&x), 2);
+ // BOOST_CHECK_EQUAL(any_cast<void*>(&x), any_cast<int*>(&x));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&x), any_cast<const int*>(&x));
+ // BOOST_CHECK_EQUAL(any_cast<double*>(&x), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&x), (double*)0);
+ const any<test_concept, const _self&> y(x);
+ // BOOST_CHECK_EQUAL(*any_cast<int*>(&y), 2);
+ BOOST_CHECK_EQUAL(*any_cast<const int*>(&y), 2);
+ // BOOST_CHECK_EQUAL(any_cast<void*>(&y), any_cast<int*>(&y));
+ BOOST_CHECK_EQUAL(any_cast<const void*>(&y), any_cast<const int*>(&y));
+ // BOOST_CHECK_EQUAL(any_cast<double*>(&y), (double*)0);
+ BOOST_CHECK_EQUAL(any_cast<const double*>(&y), (double*)0);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_assign.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_assign.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,153 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef ::boost::mpl::vector<common<>, assignable<> > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ any<test_concept> y(2);
+ x = y;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_basic_relaxed)
+{
+ typedef ::boost::mpl::vector<common<>, assignable<>, relaxed_match > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ any<test_concept> y(2);
+ x = y;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed_no_copy)
+{
+ typedef ::boost::mpl::vector<
+ destructible<>,
+ typeid_<>,
+ assignable<>,
+ relaxed_match
+ > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ any<test_concept> y(2);
+ x = y;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed_no_assign)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ relaxed_match
+ > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+ x = y;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_dynamic_fallback)
+{
+ typedef ::boost::mpl::vector<common<>, assignable<>, relaxed_match> test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2.0);
+ x = y;
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 2.0);
+}
+
+BOOST_AUTO_TEST_CASE(test_dynamic_fail)
+{
+ typedef ::boost::mpl::vector<destructible<>, typeid_<>, assignable<>, relaxed_match> test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2.0);
+ BOOST_CHECK_THROW(x = y, bad_function_call);
+}
+
+BOOST_AUTO_TEST_CASE(test_basic_int)
+{
+ typedef ::boost::mpl::vector<common<>, assignable<_self, int> > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ x = 2;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_basic_relaxed_int)
+{
+ typedef ::boost::mpl::vector<common<>, assignable<_self, int>, relaxed_match > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ x = 2;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed_no_copy_int)
+{
+ typedef ::boost::mpl::vector<
+ destructible<>,
+ typeid_<>,
+ assignable<_self, int>,
+ relaxed_match
+ > test_concept;
+ any<test_concept> x(1);
+ int* ip = any_cast<int*>(&x);
+ x = 2;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ // make sure that we're actually using assignment
+ // of the underlying object, not copy and swap.
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed_no_assign_int)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ relaxed_match
+ > test_concept;
+ any<test_concept> x(1);
+ x = 2;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_binding_of.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_binding_of.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,40 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/binding_of.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_binding_of)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(2);
+ binding<test_concept> b = binding_of(x);
+ binding<test_concept> expected(
+ make_binding<
+ ::boost::mpl::map< ::boost::mpl::pair<_self, int> >
+ >());
+ BOOST_CHECK(b == expected);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,377 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/callable.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/result_of.hpp>
+#include <vector>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+int f1_val;
+void f1() { ++f1_val; }
+
+int f2_val;
+int f2() { return ++f2_val; }
+
+BOOST_AUTO_TEST_CASE(test_void)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<void()>
+ > test_concept;
+ any<test_concept> x1(&f1);
+ f1_val = 0;
+ x1();
+ BOOST_CHECK_EQUAL(f1_val, 1);
+
+ any<test_concept> x2(&f2);
+ f2_val = 0;
+ x2();
+ BOOST_CHECK_EQUAL(f2_val, 1);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int()>
+ > test_concept_int;
+ any<test_concept_int> x3(&f2);
+ f2_val = 0;
+ int i = x3();
+ BOOST_CHECK_EQUAL(i, 1);
+ BOOST_CHECK_EQUAL(f2_val, 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_void_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<void(), const _self>
+ > test_concept;
+ const any<test_concept> x1(&f1);
+ f1_val = 0;
+ x1();
+ BOOST_CHECK_EQUAL(f1_val, 1);
+
+ const any<test_concept> x2(&f2);
+ f2_val = 0;
+ x2();
+ BOOST_CHECK_EQUAL(f2_val, 1);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int(), const _self>
+ > test_concept_int;
+ const any<test_concept_int> x3(&f2);
+ f2_val = 0;
+ int i = x3();
+ BOOST_CHECK_EQUAL(i, 1);
+ BOOST_CHECK_EQUAL(f2_val, 1);
+}
+
+int f3_val;
+void f3(int i) { f3_val += i; }
+
+int f4_val;
+int f4(int i) { return f4_val += i; }
+
+BOOST_AUTO_TEST_CASE(test_int)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<void(int)>
+ > test_concept;
+ any<test_concept> x1(&f3);
+ f3_val = 1;
+ x1(3);
+ BOOST_CHECK_EQUAL(f3_val, 4);
+
+ any<test_concept> x2(&f4);
+ f4_val = 1;
+ x2(2);
+ BOOST_CHECK_EQUAL(f4_val, 3);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int(int)>
+ > test_concept_int;
+ any<test_concept_int> x3(&f4);
+ f4_val = 1;
+ int i = x3(4);
+ BOOST_CHECK_EQUAL(i, 5);
+ BOOST_CHECK_EQUAL(f4_val, 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_int_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<void(int), const _self>
+ > test_concept;
+ const any<test_concept> x1(&f3);
+ f3_val = 1;
+ x1(3);
+ BOOST_CHECK_EQUAL(f3_val, 4);
+
+ const any<test_concept> x2(&f4);
+ f4_val = 1;
+ x2(2);
+ BOOST_CHECK_EQUAL(f4_val, 3);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int(int), const _self>
+ > test_concept_int;
+ const any<test_concept_int> x3(&f4);
+ f4_val = 1;
+ int i = x3(4);
+ BOOST_CHECK_EQUAL(i, 5);
+ BOOST_CHECK_EQUAL(f4_val, 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_any)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void(_a)>
+ > test_concept;
+ tuple<test_concept, _self, _a> t1(&f3, 3);
+ any<test_concept> x1(get<0>(t1));
+ f3_val = 1;
+ x1(get<1>(t1));
+ BOOST_CHECK_EQUAL(f3_val, 4);
+
+ tuple<test_concept, _self, _a> t2(&f4, 2);
+ any<test_concept> x2(get<0>(t2));
+ f4_val = 1;
+ x2(get<1>(t2));
+ BOOST_CHECK_EQUAL(f4_val, 3);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<_a(_a)>
+ > test_concept_int;
+ tuple<test_concept_int, _self, _a> t3(&f4, 4);
+ any<test_concept_int> x3(get<0>(t3));
+ f4_val = 1;
+ int i = any_cast<int>(x3(get<1>(t3)));
+ BOOST_CHECK_EQUAL(i, 5);
+ BOOST_CHECK_EQUAL(f4_val, 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_any_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void(_a), const _self>
+ > test_concept;
+ tuple<test_concept, _self, _a> t1(&f3, 3);
+ const any<test_concept> x1(get<0>(t1));
+ f3_val = 1;
+ x1(get<1>(t1));
+ BOOST_CHECK_EQUAL(f3_val, 4);
+
+ tuple<test_concept, _self, _a> t2(&f4, 2);
+ const any<test_concept> x2(get<0>(t2));
+ f4_val = 1;
+ x2(get<1>(t2));
+ BOOST_CHECK_EQUAL(f4_val, 3);
+
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<_a(_a), const _self>
+ > test_concept_int;
+ tuple<test_concept_int, _self, _a> t3(&f4, 4);
+ const any<test_concept_int> x3(get<0>(t3));
+ f4_val = 1;
+ int i = any_cast<int>(x3(get<1>(t3)));
+ BOOST_CHECK_EQUAL(i, 5);
+ BOOST_CHECK_EQUAL(f4_val, 5);
+}
+
+int overload1;
+int overload2;
+int overload3;
+
+struct overloaded_function
+{
+ int operator()() const { return ++overload1; }
+ int operator()(int i) const { return overload2 += i; }
+ int operator()(short i) const { return overload3 += i; }
+};
+
+BOOST_AUTO_TEST_CASE(test_result_of)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void()>,
+ callable<int(int)>,
+ callable<long(_a)>
+ > test_concept;
+
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>()>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(int)>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(any<test_concept, _a>)>::type, long>));
+}
+
+BOOST_AUTO_TEST_CASE(test_result_of_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void(), const _self>,
+ callable<int(int), const _self>,
+ callable<long(_a), const _self>
+ > test_concept;
+
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>()>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(int)>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(any<test_concept, _a>)>::type, long>));
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void()>,
+ callable<void(int)>,
+ callable<void(_a)>
+ > test_concept;
+ tuple<test_concept, _self, _a> t(overloaded_function(), static_cast<short>(3));
+ any<test_concept> f(get<0>(t));
+ any<test_concept, _a> a(get<1>(t));
+
+ overload1 = 0;
+ f();
+ BOOST_CHECK_EQUAL(overload1, 1);
+
+ overload2 = 0;
+ f(2);
+ BOOST_CHECK_EQUAL(overload2, 2);
+
+ overload3 = 0;
+ f(a);
+ BOOST_CHECK_EQUAL(overload3, 3);
+
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>()>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(int)>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(any<test_concept, _a>)>::type, void>));
+}
+
+BOOST_AUTO_TEST_CASE(test_overload_return)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<int()>,
+ callable<int(int)>,
+ callable<int(_a)>
+ > test_concept;
+ tuple<test_concept, _self, _a> t(overloaded_function(), static_cast<short>(3));
+ any<test_concept> f(get<0>(t));
+ any<test_concept, _a> a(get<1>(t));
+
+ overload1 = 0;
+ BOOST_CHECK_EQUAL(f(), 1);
+ BOOST_CHECK_EQUAL(overload1, 1);
+
+ overload2 = 0;
+ BOOST_CHECK_EQUAL(f(2), 2);
+ BOOST_CHECK_EQUAL(overload2, 2);
+
+ overload3 = 0;
+ BOOST_CHECK_EQUAL(f(a), 3);
+ BOOST_CHECK_EQUAL(overload3, 3);
+
+ //BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>()>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(int)>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>(any<test_concept, _a>)>::type, int>));
+}
+
+
+BOOST_AUTO_TEST_CASE(test_overload_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<void(), const _self>,
+ callable<void(int), const _self>,
+ callable<void(_a), const _self>
+ > test_concept;
+ tuple<test_concept, _self, _a> t(overloaded_function(), static_cast<short>(3));
+ any<test_concept> f(get<0>(t));
+ any<test_concept, _a> a(get<1>(t));
+
+ overload1 = 0;
+ f();
+ BOOST_CHECK_EQUAL(overload1, 1);
+
+ overload2 = 0;
+ f(2);
+ BOOST_CHECK_EQUAL(overload2, 2);
+
+ overload3 = 0;
+ f(a);
+ BOOST_CHECK_EQUAL(overload3, 3);
+
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>()>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(int)>::type, void>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(any<test_concept, _a>)>::type, void>));
+}
+
+BOOST_AUTO_TEST_CASE(test_overload_return_const)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ common<_a>,
+ callable<int(), const _self>,
+ callable<int(int), const _self>,
+ callable<int(_a), const _self>
+ > test_concept;
+ tuple<test_concept, _self, _a> t(overloaded_function(), static_cast<short>(3));
+ any<test_concept> f(get<0>(t));
+ any<test_concept, _a> a(get<1>(t));
+
+ overload1 = 0;
+ BOOST_CHECK_EQUAL(f(), 1);
+ BOOST_CHECK_EQUAL(overload1, 1);
+
+ overload2 = 0;
+ BOOST_CHECK_EQUAL(f(2), 2);
+ BOOST_CHECK_EQUAL(overload2, 2);
+
+ overload3 = 0;
+ BOOST_CHECK_EQUAL(f(a), 3);
+ BOOST_CHECK_EQUAL(overload3, 3);
+
+ //BOOST_MPL_ASSERT((boost::is_same<boost::result_of<any<test_concept>()>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(int)>::type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(any<test_concept, _a>)>::type, int>));
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_construct.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_construct.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,374 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/binding_of.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <vector>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_unary)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ constructible<_b(_a)>,
+ destructible<_b>,
+ typeid_<_b>
+ > test_concept;
+ int i = 1;
+ double d = 10;
+ tuple<test_concept, _a, _b&> t(i, d);
+ any<test_concept, _b> x(get<0>(t));
+ BOOST_CHECK_EQUAL(any_cast<double>(x), 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_unary_no_const)
+{
+ typedef ::boost::mpl::vector<
+ constructible<_b(_a&)>,
+ destructible<_b>,
+ typeid_<_b>
+ > test_concept;
+ typedef boost::mpl::map<
+ boost::mpl::pair<_a, int>,
+ boost::mpl::pair<_b, boost::tuple<int&> >
+ > types;
+ int i = 1;
+ any<test_concept, _a&> x(i, make_binding<types>());
+ any<test_concept, _b> y(x);
+ BOOST_CHECK_EQUAL(&any_cast<boost::tuple<int&> >(y).get<0>(), &i);
+ any<test_concept, _b> z(binding_of(x), x);
+ BOOST_CHECK_EQUAL(&any_cast<boost::tuple<int&> >(z).get<0>(), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_from_int)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ constructible<_a(std::size_t)>
+ > test_concept;
+ binding<test_concept> types =
+ make_binding<
+ ::boost::mpl::map<
+ ::boost::mpl::pair<_a, std::vector<int> >
+ >
+ >();
+ any<test_concept, _a> x(types, 10);
+ std::vector<int> vec(any_cast<std::vector<int> >(x));
+ BOOST_CHECK_EQUAL(vec.size(), 10u);
+}
+
+BOOST_AUTO_TEST_CASE(test_default)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ constructible<_a()>
+ > test_concept;
+ binding<test_concept> types =
+ make_binding<
+ ::boost::mpl::map<
+ ::boost::mpl::pair<_a, std::vector<int> >
+ >
+ >();
+ any<test_concept, _a> x(types);
+ std::vector<int> vec(any_cast<std::vector<int> >(x));
+ BOOST_CHECK_EQUAL(vec.size(), 0u);
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef ::boost::mpl::vector<
+ common<_a>,
+ common<_b>,
+ constructible<_a(_b)>,
+ constructible<_a(std::size_t)>
+ > test_concept;
+ typedef ::boost::mpl::map<
+ ::boost::mpl::pair<_a, std::vector<int> >,
+ ::boost::mpl::pair<_b, std::size_t>
+ > types;
+ binding<test_concept> table = make_binding<types>();
+ any<test_concept, _b> x(static_cast<std::size_t>(10), make_binding<types>());
+ any<test_concept, _a> y(x);
+ any<test_concept, _a> z(table, 17);
+ std::vector<int> vec1(any_cast<std::vector<int> >(y));
+ BOOST_CHECK_EQUAL(vec1.size(), 10u);
+ std::vector<int> vec2(any_cast<std::vector<int> >(z));
+ BOOST_CHECK_EQUAL(vec2.size(), 17u);
+}
+
+
+template<class T>
+T as_rvalue(const T& arg) { return arg; }
+template<class T>
+const T& as_const(const T& arg) { return arg; }
+
+BOOST_AUTO_TEST_CASE(test_from_int_with_binding)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(4, make_binding<boost::mpl::map<boost::mpl::pair<_self, int> > >());
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ any<test_concept> x(4);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<test_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<test_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<test_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<> > dst_concept;
+ any<src_concept> x(4);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind)
+{
+ typedef ::boost::mpl::vector<common<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ any<src_concept> x(4);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ any<src_concept> x(4);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ any<src_concept> x(4);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+
+ any<dst_concept, _a> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(cy), 4);
+ any<dst_concept, _a> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<int>(cz), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy_from_ref)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 4;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<test_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<test_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<test_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_from_ref)
+{
+ typedef ::boost::mpl::vector<common<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+
+ any<dst_concept, _a> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(cy), 4);
+ any<dst_concept, _a> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<int>(cz), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy_from_cref)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 4;
+ any<test_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<test_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<test_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<test_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_from_cref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_from_cref)
+{
+ typedef ::boost::mpl::vector<common<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_cref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+ any<dst_concept, _a> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int>(w), 4);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_cref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 4);
+ any<dst_concept, _a> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 4);
+ any<dst_concept, _a> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<int>(z), 4);
+
+ any<dst_concept, _a> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int>(cy), 4);
+ any<dst_concept, _a> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<int>(cz), 4);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_construct_cref.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_construct_cref.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,277 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+template<class T>
+T as_rvalue(const T& arg) { return arg; }
+template<class T>
+const T& as_const(const T& arg) { return arg; }
+
+BOOST_AUTO_TEST_CASE(test_from_int_with_binding)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 4;
+ any<test_concept, const _self&> x(i, make_binding<boost::mpl::map<boost::mpl::pair<_self, int> > >());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy)
+{
+ typedef ::boost::mpl::vector<typeid_<> > test_concept;
+ int i = 4;
+ any<test_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<test_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<test_concept, const _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<test_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind)
+{
+ typedef ::boost::mpl::vector<typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ int i = 4;
+ any<src_concept, const _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+
+ any<dst_concept, const _a&> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), &i);
+ any<dst_concept, const _a&> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy_from_ref)
+{
+ typedef ::boost::mpl::vector<typeid_<> > test_concept;
+ int i = 4;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<test_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<test_concept, const _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<test_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_from_ref)
+{
+ typedef ::boost::mpl::vector<typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_ref)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i);
+ any<dst_concept, const _a&> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+ any<dst_concept, const _a&> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i);
+
+ any<dst_concept, const _a&> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), &i);
+ any<dst_concept, const _a&> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy_from_value)
+{
+ typedef ::boost::mpl::vector<copy_constructible<>, typeid_<> > test_concept;
+ any<test_concept> x(4);
+ const int* ip = any_cast<const int*>(&x);
+ any<test_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip);
+ BOOST_CHECK_EQUAL(any_cast<int>(any<test_concept, const _self&>(as_rvalue(x))), 4);
+ any<test_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<> > dst_concept;
+ any<src_concept> x(4);
+ const int* ip = any_cast<const int*>(&x);
+ any<dst_concept, const _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip);
+ BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _self&>(as_rvalue(x))), 4);
+ any<dst_concept, const _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_from_value)
+{
+ typedef ::boost::mpl::vector<copy_constructible<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<copy_constructible<_a>, typeid_<_a> > dst_concept;
+ any<src_concept> x(4);
+ const int* ip = any_cast<const int*>(&x);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip);
+ BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _a&>(as_rvalue(x))), 4);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ any<src_concept> x(4);
+ const int* ip = any_cast<const int*>(&x);
+ any<dst_concept, const _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip);
+ BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _a&>(as_rvalue(x))), 4);
+ any<dst_concept, const _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ any<src_concept> x(4);
+ const int* ip = any_cast<const int*>(&x);
+ any<dst_concept, const _a&> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip);
+ any<dst_concept, const _a&> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&z), ip);
+
+ any<dst_concept, const _a&> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), ip);
+ any<dst_concept, const _a&> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), ip);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_construct_ref.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_construct_ref.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,178 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+template<class T>
+T as_rvalue(const T& arg) { return arg; }
+template<class T>
+const T& as_const(const T& arg) { return arg; }
+
+BOOST_AUTO_TEST_CASE(test_from_int_with_binding)
+{
+ typedef ::boost::mpl::vector<common<> > test_concept;
+ int i = 4;
+ any<test_concept, _self&> x(i, make_binding<boost::mpl::map<boost::mpl::pair<_self, int> > >());
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy)
+{
+ typedef ::boost::mpl::vector<typeid_<> > test_concept;
+ int i = 4;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+ any<test_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+ any<test_concept, _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i);
+ any<test_concept, _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+ any<dst_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+ any<dst_concept, _self&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i);
+ any<dst_concept, _self&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind)
+{
+ typedef ::boost::mpl::vector<typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+ any<dst_concept, _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+ any<dst_concept, _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i);
+ any<dst_concept, _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+ any<dst_concept, _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+ any<dst_concept, _a&> z = as_rvalue(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i);
+ any<dst_concept, _a&> w = as_const(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&w), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ int i = 4;
+ any<src_concept, _self&> x(i);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i);
+ any<dst_concept, _a&> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+ any<dst_concept, _a&> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i);
+
+ any<dst_concept, _a&> cy(as_const(x), make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int*>(&cy), &i);
+ any<dst_concept, _a&> cz(as_const(x), table);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&cz), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy_from_value)
+{
+ typedef ::boost::mpl::vector<destructible<>, typeid_<> > test_concept;
+ any<test_concept> x(4);
+ int* ip = any_cast<int*>(&x);
+ any<test_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_convert_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<> > dst_concept;
+ any<src_concept> x(4);
+ int* ip = any_cast<int*>(&x);
+ any<dst_concept, _self&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_from_value)
+{
+ typedef ::boost::mpl::vector<destructible<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<destructible<_a>, typeid_<_a> > dst_concept;
+ any<src_concept> x(4);
+ int* ip = any_cast<int*>(&x);
+ any<dst_concept, _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept;
+ typedef ::boost::mpl::vector<typeid_<_a> > dst_concept;
+ any<src_concept> x(4);
+ int* ip = any_cast<int*>(&x);
+ any<dst_concept, _a&> y(x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip);
+}
+
+BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_value)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept;
+ typedef ::boost::mpl::vector<common<_a> > dst_concept;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map;
+ typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types;
+
+ binding<dst_concept> table(make_binding<types>());
+
+ any<src_concept> x(4);
+ int* ip = any_cast<int*>(&x);
+ any<dst_concept, _a&> y(x, make_binding<map>());
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip);
+ any<dst_concept, _a&> z(x, table);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&z), ip);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_dereference.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_dereference.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,60 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef ::boost::mpl::vector<common<>, dereferenceable<int&> > test_concept;
+ int i;
+ any<test_concept> x(&i);
+ BOOST_CHECK_EQUAL(&*x, &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_any_result)
+{
+ typedef ::boost::mpl::vector<common<>, common<_a>, dereferenceable<_a&> > test_concept;
+ typedef ::boost::mpl::map<
+ ::boost::mpl::pair<_self, int*>,
+ ::boost::mpl::pair<_a, int>
+ > types;
+ int i;
+ any<test_concept> x(&i, make_binding<types>());
+ any<test_concept, _a&> y(*x);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i);
+}
+
+BOOST_AUTO_TEST_CASE(test_any_result_const)
+{
+ typedef ::boost::mpl::vector<common<>, common<_a>, dereferenceable<const _a&> > test_concept;
+ typedef ::boost::mpl::map<
+ ::boost::mpl::pair<_self, const int*>,
+ ::boost::mpl::pair<_a, int>
+ > types;
+ const int i = 0;
+ any<test_concept> x(&i, make_binding<types>());
+ any<test_concept, const _a&> y(*x);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_equal.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_equal.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,147 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK((x == x));
+ BOOST_CHECK((x != y));
+ BOOST_CHECK(!(x != x));
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_unequal)
+{
+ typedef boost::mpl::vector<copy_constructible<_a>, copy_constructible<_b>, equality_comparable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(1, 2.0);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK((x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<_a>, copy_constructible<_b>, equality_comparable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(1, 1);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK((x == y));
+ BOOST_CHECK(!(x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_lhs_unequal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<int, _self> > test_concept;
+ int x(1);
+ any<test_concept> y(2.0);
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK((x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_lhs_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<int, _self> > test_concept;
+ int x(1);
+ any<test_concept> y(1);
+
+ BOOST_CHECK((x == y));
+ BOOST_CHECK(!(x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_rhs_unequal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<_self, int> > test_concept;
+ any<test_concept> x(2.0);
+ int y(1);
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK((x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_rhs_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<_self, int> > test_concept;
+ any<test_concept> x(1);
+ int y(1);
+
+ BOOST_CHECK((x == y));
+ BOOST_CHECK(!(x != y));
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed)
+{
+ typedef boost::mpl::vector<copy_constructible<>, equality_comparable<>, relaxed_match> test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+ any<test_concept> z(std::string("test"));
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK((x == x));
+ BOOST_CHECK((x != y));
+ BOOST_CHECK(!(x != x));
+
+ BOOST_CHECK(!(x == z));
+ BOOST_CHECK((x != z));
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef boost::mpl::vector<
+ copy_constructible<_a>,
+ copy_constructible<_b>,
+ equality_comparable<_a>,
+ equality_comparable<_a, int>,
+ equality_comparable<int, _a>,
+ equality_comparable<_b>,
+ equality_comparable<_b, int>,
+ equality_comparable<int, _b>,
+ equality_comparable<_a, _b>
+ > test_concept;
+
+ tuple<test_concept, _a, _b> t(1, 2.0);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK(x == x);
+ BOOST_CHECK(!(x != x));
+ BOOST_CHECK(x == 1);
+ BOOST_CHECK(x != 2);
+ BOOST_CHECK(1 == x);
+ BOOST_CHECK(2 != x);
+
+ BOOST_CHECK(y == y);
+ BOOST_CHECK(!(y != y));
+ BOOST_CHECK(y == 2);
+ BOOST_CHECK(y != 3);
+ BOOST_CHECK(2 == y);
+ BOOST_CHECK(3 != y);
+
+ BOOST_CHECK(!(x == y));
+ BOOST_CHECK(x != y);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_forward_iterator.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,65 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/iterator.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/concept_check.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef boost::mpl::vector<forward_iterator<_self, int> > test_concept;
+ std::vector<int> vec(10);
+ any<test_concept> x(vec.begin());
+ any<test_concept> y(vec.end());
+
+ for(int i = 0; x != y; ++x, ++i) {
+ *x = i;
+ }
+ int expected[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ BOOST_CHECK_EQUAL_COLLECTIONS(vec.begin(), vec.end(), &expected[0], &expected[0] + 10);
+
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::value_type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::reference, int&>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::pointer, int*>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::difference_type, std::ptrdiff_t>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::iterator_category, std::forward_iterator_tag>));
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed)
+{
+ typedef boost::mpl::vector<forward_iterator<_self, int>, relaxed_match> test_concept;
+ std::vector<int> vec(10);
+ any<test_concept> x(vec.begin());
+ any<test_concept> y(vec.end());
+
+ for(int i = 0; x != y; ++x, ++i) {
+ *x = i;
+ }
+ int expected[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ BOOST_CHECK_EQUAL_COLLECTIONS(vec.begin(), vec.end(), &expected[0], &expected[0] + 10);
+
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::value_type, int>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::reference, int&>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::pointer, int*>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::difference_type, std::ptrdiff_t>));
+ BOOST_MPL_ASSERT((boost::is_same<any<test_concept>::iterator_category, std::forward_iterator_tag>));
+
+ BOOST_CONCEPT_ASSERT((boost::ForwardIterator<any<test_concept> >));
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_increment.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_increment.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,51 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ destructible<T>,
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_value)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > test_concept;
+ any<test_concept> x(1);
+ ++x;
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 2);
+ any<test_concept> y(x++);
+ BOOST_CHECK_EQUAL(any_cast<int>(x), 3);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_reference)
+{
+ typedef ::boost::mpl::vector<common<>, incrementable<> > test_concept;
+ int i = 1;
+ any<test_concept, _self&> x(i);
+ ++x;
+ BOOST_CHECK_EQUAL(i, 2);
+ any<test_concept> y(x++);
+ BOOST_CHECK_EQUAL(i, 3);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), 2);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_less.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_less.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,260 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+
+ BOOST_CHECK((x < y));
+ BOOST_CHECK(!(y < x));
+ BOOST_CHECK(!(x < x));
+
+ BOOST_CHECK(!(x > y));
+ BOOST_CHECK((y > x));
+ BOOST_CHECK(!(x > x));
+
+ BOOST_CHECK((x <= y));
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK((x <= x));
+
+ BOOST_CHECK(!(x >= y));
+ BOOST_CHECK((y >= x));
+ BOOST_CHECK((x >= x));
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_less)
+{
+ typedef boost::mpl::vector<copy_constructible<_a>, copy_constructible<_b>, less_than_comparable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(1, 2.0);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK((x < y));
+ BOOST_CHECK((y > x));
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK(!(x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<_a>, copy_constructible<_b>, less_than_comparable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(1, 1);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_greater)
+{
+ typedef boost::mpl::vector<copy_constructible<_a>, copy_constructible<_b>, less_than_comparable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(2.0, 1);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_lhs_less)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<int, _self> > test_concept;
+ int x(1);
+ any<test_concept> y(2.0);
+
+ BOOST_CHECK((x < y));
+ BOOST_CHECK((y > x));
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK(!(x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_lhs_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<int, _self> > test_concept;
+ int x(1);
+ any<test_concept> y(1);
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+
+BOOST_AUTO_TEST_CASE(test_fixed_lhs_greater)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<int, _self> > test_concept;
+ int x(1);
+ any<test_concept> y(0.5);
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_rhs_less)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<_self, int> > test_concept;
+ any<test_concept> x(1.0);
+ int y(2);
+
+ BOOST_CHECK((x < y));
+ BOOST_CHECK((y > x));
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK(!(x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_fixed_rhs_equal)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<_self, int> > test_concept;
+ any<test_concept> x(1);
+ int y(1);
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+
+BOOST_AUTO_TEST_CASE(test_fixed_rhs_greater)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<_self, int> > test_concept;
+ any<test_concept> x(2.0);
+ int y(1);
+
+ BOOST_CHECK(!(x < y));
+ BOOST_CHECK(!(y > x));
+ BOOST_CHECK((y <= x));
+ BOOST_CHECK((x >= y));
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed)
+{
+ typedef boost::mpl::vector<copy_constructible<>, less_than_comparable<>, relaxed_match> test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(2);
+ any<test_concept> z(std::string("test"));
+
+ BOOST_CHECK((x < y));
+ BOOST_CHECK(!(y < x));
+ BOOST_CHECK(!(x < x));
+
+ BOOST_CHECK(!(x > y));
+ BOOST_CHECK((y > x));
+ BOOST_CHECK(!(x > x));
+
+ BOOST_CHECK((x <= y));
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK((x <= x));
+
+ BOOST_CHECK(!(x >= y));
+ BOOST_CHECK((y >= x));
+ BOOST_CHECK((x >= x));
+
+ bool expected = x < z;
+
+ BOOST_CHECK_EQUAL((x < z), expected);
+ BOOST_CHECK_EQUAL(!(z < x), expected);
+
+ BOOST_CHECK_EQUAL(!(x > z), expected);
+ BOOST_CHECK_EQUAL((z > x), expected);
+
+ BOOST_CHECK_EQUAL((x <= z), expected);
+ BOOST_CHECK_EQUAL(!(z <= x), expected);
+
+ BOOST_CHECK_EQUAL(!(x >= z), expected);
+ BOOST_CHECK_EQUAL((z >= x), expected);
+
+ BOOST_CHECK_EQUAL((y < z), expected);
+ BOOST_CHECK_EQUAL(!(z < y), expected);
+
+ BOOST_CHECK_EQUAL(!(y > z), expected);
+ BOOST_CHECK_EQUAL((z > y), expected);
+
+ BOOST_CHECK_EQUAL((y <= z), expected);
+ BOOST_CHECK_EQUAL(!(z <= y), expected);
+
+ BOOST_CHECK_EQUAL(!(y >= z), expected);
+ BOOST_CHECK_EQUAL((z >= y), expected);
+}
+
+BOOST_AUTO_TEST_CASE(test_overload)
+{
+ typedef boost::mpl::vector<
+ copy_constructible<_a>,
+ copy_constructible<_b>,
+ less_than_comparable<_a>,
+ less_than_comparable<_a, int>,
+ less_than_comparable<int, _a>,
+ less_than_comparable<_b>,
+ less_than_comparable<_b, int>,
+ less_than_comparable<int, _b>,
+ less_than_comparable<_a, _b>
+ > test_concept;
+ tuple<test_concept, _a, _b> t(1, 2);
+ any<test_concept, _a> x(get<0>(t));
+ any<test_concept, _b> y(get<1>(t));
+
+ BOOST_CHECK(!(x < x));
+ BOOST_CHECK(x <= x);
+ BOOST_CHECK(!(x > x));
+ BOOST_CHECK(x >= x);
+
+ BOOST_CHECK(!(x < 1));
+ BOOST_CHECK(x <= 1);
+ BOOST_CHECK(!(x > 1));
+ BOOST_CHECK(x >= 1);
+
+ BOOST_CHECK(!(1 < x));
+ BOOST_CHECK(1 <= x);
+ BOOST_CHECK(!(1 > x));
+ BOOST_CHECK(1 >= x);
+
+ BOOST_CHECK(!(y < y));
+ BOOST_CHECK(y <= y);
+ BOOST_CHECK(!(y > y));
+ BOOST_CHECK(y >= y);
+
+ BOOST_CHECK(!(y < 2));
+ BOOST_CHECK(y <= 2);
+ BOOST_CHECK(!(y > 2));
+ BOOST_CHECK(y >= 2);
+
+ BOOST_CHECK(!(2 < y));
+ BOOST_CHECK(2 <= y);
+ BOOST_CHECK(!(2 > y));
+ BOOST_CHECK(2 >= y);
+
+ BOOST_CHECK(x < y);
+ BOOST_CHECK(y > x);
+ BOOST_CHECK(!(y <= x));
+ BOOST_CHECK(!(x >= y));
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_negate.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_negate.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,34 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_negate)
+{
+ typedef ::boost::mpl::vector<common<>, negatable<> > test_concept;
+ any<test_concept> x(1);
+ any<test_concept> y(-x);
+ BOOST_CHECK_EQUAL(any_cast<int>(y), -1);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_nested.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_nested.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,62 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+typedef any<boost::mpl::vector<common<> > > any1_type;
+
+struct test_class
+{
+ int i;
+};
+
+test_class operator+(const test_class& lhs, const any1_type& rhs)
+{
+ test_class result = { lhs.i + any_cast<int>(rhs) };
+ return result;
+}
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef boost::mpl::vector<common<>, addable<_self, any1_type> > test_concept;
+ any1_type a1(1);
+ test_class v = { 2 };
+ any<test_concept> x(v);
+ any<test_concept> y(x + a1);
+ BOOST_CHECK_EQUAL(any_cast<test_class>(y).i, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_relaxed)
+{
+ typedef boost::mpl::vector<common<_a>, addable<_a, any1_type>, relaxed_match> test_concept;
+ typedef boost::mpl::vector<common<_b>, addable<_b, any1_type>, relaxed_match> dest_concept;
+ any1_type a1(1);
+ test_class v = { 2 };
+ any<test_concept, _a> x(v);
+ any<test_concept, _a> y(x + a1);
+ BOOST_CHECK_EQUAL(any_cast<test_class>(y).i, 3);
+
+ any<dest_concept, _b> z(x);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_reference.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_reference.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,82 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+class no_destroy
+{
+protected:
+ ~no_destroy() {}
+};
+
+class with_destroy : public no_destroy
+{
+public:
+ ~with_destroy() {}
+};
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ destructible<T>,
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef ::boost::mpl::vector<typeid_<> > test_concept;
+ with_destroy val;
+ any<test_concept, _self&> x(static_cast<no_destroy&>(val));
+ no_destroy& ref = any_cast<no_destroy&>(x);
+ BOOST_CHECK_EQUAL(&ref, &val);
+}
+
+BOOST_AUTO_TEST_CASE(test_increment)
+{
+ typedef ::boost::mpl::vector<incrementable<> > test_concept;
+ int i = 0;
+ any<test_concept, _self&> x(i);
+ ++x;
+ BOOST_CHECK_EQUAL(i, 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_add)
+{
+ typedef ::boost::mpl::vector<common<>, addable<> > test_concept;
+ int i = 1;
+ int j = 2;
+ any<test_concept, _self&> x(i);
+ any<test_concept, _self&> y(j);
+ any<test_concept, _self> z(x + y);
+ int k = any_cast<int>(z);
+ BOOST_CHECK_EQUAL(k, 3);
+}
+
+BOOST_AUTO_TEST_CASE(test_mixed_add)
+{
+ typedef ::boost::mpl::vector<common<>, addable<> > test_concept;
+ int i = 1;
+ int j = 2;
+ any<test_concept, _self&> x(i);
+ any<test_concept, _self> y(j);
+ any<test_concept, _self> z(x + y);
+ int k = any_cast<int>(z);
+ BOOST_CHECK_EQUAL(k, 3);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_relaxed_match.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_relaxed_match.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,36 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_simple)
+{
+ typedef ::boost::mpl::vector<copy_constructible<>, addable<>, relaxed_match> src_concept;
+ any<src_concept> x(1);
+ any<src_concept> y(2.0);
+ BOOST_CHECK_THROW(x + y, bad_function_call);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_stream.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_stream.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,245 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/mpl/vector.hpp>
+#include <sstream>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+BOOST_AUTO_TEST_CASE(test_output_int)
+{
+ typedef ostreamable<_a, int> test_concept;
+ std::ostringstream ss;
+ any<test_concept, _a&> x(ss);
+ x << 17;
+ BOOST_CHECK_EQUAL(ss.str(), "17");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_int_wide)
+{
+ typedef ostreamable<_a, int> test_concept;
+ std::wostringstream ss;
+ any<test_concept, _a&> x(ss);
+ x << 17;
+ BOOST_CHECK(ss.str() == L"17");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_int_any)
+{
+ typedef boost::mpl::vector<ostreamable<>, copy_constructible<> > test_concept;
+ std::ostringstream ss;
+ any<test_concept> x(10);
+ ss << x;
+ BOOST_CHECK_EQUAL(ss.str(), "10");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_int_any_wide)
+{
+ typedef boost::mpl::vector<ostreamable<std::wostream>, copy_constructible<> > test_concept;
+ std::wostringstream ss;
+ any<test_concept> x(10);
+ ss << x;
+ BOOST_CHECK(ss.str() == L"10");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_both_any)
+{
+ typedef boost::mpl::vector<ostreamable<_a>, copy_constructible<> > test_concept;
+ std::ostringstream ss;
+ int val = 19;
+ tuple<test_concept, _a&, _self> t(ss, val);
+ get<0>(t) << get<1>(t);
+ BOOST_CHECK_EQUAL(ss.str(), "19");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_both_any_wide)
+{
+ typedef boost::mpl::vector<ostreamable<_a>, copy_constructible<> > test_concept;
+ std::wostringstream ss;
+ int val = 19;
+ tuple<test_concept, _a&, _self> t(ss, val);
+ get<0>(t) << get<1>(t);
+ BOOST_CHECK(ss.str() == L"19");
+}
+
+BOOST_AUTO_TEST_CASE(test_output_overload_all)
+{
+ typedef boost::mpl::vector<
+ ostreamable<_a>,
+ ostreamable<_a, int>,
+ ostreamable<_b>,
+ ostreamable<_b, int>,
+ ostreamable<>,
+ ostreamable<std::wostream>,
+ copy_constructible<>
+ > test_concept;
+ {
+ std::ostringstream ss;
+ std::wostringstream wss;
+ int val = 2;
+ tuple<test_concept, _a&, _b&, _self> t(ss, wss, val);
+ get<0>(t) << get<2>(t);
+ get<1>(t) << get<2>(t);
+ BOOST_CHECK_EQUAL(ss.str(), "2");
+ BOOST_CHECK(wss.str() == L"2");
+ }
+ {
+ std::ostringstream ss;
+ std::wostringstream wss;
+ int val = 2;
+ tuple<test_concept, _a&, _b&, _self> t(ss, wss, val);
+ get<0>(t) << 3;
+ get<1>(t) << 3;
+ BOOST_CHECK_EQUAL(ss.str(), "3");
+ BOOST_CHECK(wss.str() == L"3");
+ }
+ {
+ std::ostringstream ss;
+ std::wostringstream wss;
+ int val = 5;
+ tuple<test_concept, _a&, _b&, _self> t(ss, wss, val);
+ ss << get<2>(t);
+ wss << get<2>(t);
+ BOOST_CHECK_EQUAL(ss.str(), "5");
+ BOOST_CHECK(wss.str() == L"5");
+ }
+ {
+ std::ostringstream ss;
+ std::wostringstream wss;
+ int val = 5;
+ tuple<test_concept, _a&, _b&, _self> t(ss, wss, val);
+ // we can't do anything with these, but it should
+ // still compile.
+ any<test_concept, const _a&> os(get<0>(t));
+ any<test_concept, const _b&> wos(get<1>(t));
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(test_input_int)
+{
+ typedef istreamable<_a, int> test_concept;
+ std::istringstream ss("17");
+ int i;
+ any<test_concept, _a&> x(ss);
+ x >> i;
+ BOOST_CHECK_EQUAL(i, 17);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_int_wide)
+{
+ typedef istreamable<_a, int> test_concept;
+ std::wistringstream ss(L"17");
+ int i;
+ any<test_concept, _a&> x(ss);
+ x >> i;
+ BOOST_CHECK_EQUAL(i, 17);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_int_any)
+{
+ typedef istreamable<> test_concept;
+ std::istringstream ss("10");
+ int i;
+ any<test_concept, _self&> x(i);
+ ss >> x;
+ BOOST_CHECK_EQUAL(i, 10);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_int_any_wide)
+{
+ typedef istreamable<std::wistream> test_concept;
+ std::wistringstream ss(L"10");
+ int i;
+ any<test_concept, _self&> x(i);
+ ss >> x;
+ BOOST_CHECK_EQUAL(i, 10);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_both_any)
+{
+ typedef istreamable<_a> test_concept;
+ std::istringstream ss("19");
+ int i;
+ tuple<test_concept, _a&, _self&> t(ss, i);
+ get<0>(t) >> get<1>(t);
+ BOOST_CHECK_EQUAL(i, 19);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_both_any_wide)
+{
+ typedef istreamable<_a> test_concept;
+ std::wistringstream ss(L"19");
+ int i;
+ tuple<test_concept, _a&, _self&> t(ss, i);
+ get<0>(t) >> get<1>(t);
+ BOOST_CHECK_EQUAL(i, 19);
+}
+
+BOOST_AUTO_TEST_CASE(test_input_overload_all)
+{
+ typedef boost::mpl::vector<
+ istreamable<_a>,
+ istreamable<_a, int>,
+ istreamable<_b>,
+ istreamable<_b, int>,
+ istreamable<>,
+ istreamable<std::wistream>
+ > test_concept;
+ {
+ std::istringstream ss("2");
+ std::wistringstream wss(L"3");
+ int i = 0;
+ tuple<test_concept, _a&, _b&, _self&> t(ss, wss, i);
+ get<0>(t) >> get<2>(t);
+ BOOST_CHECK_EQUAL(i, 2);
+ get<1>(t) >> get<2>(t);
+ BOOST_CHECK_EQUAL(i, 3);
+ }
+ {
+ std::istringstream ss("5");
+ std::wistringstream wss(L"7");
+ int i = 0;
+ tuple<test_concept, _a&, _b&, _self&> t(ss, wss, i);
+ get<0>(t) >> i;
+ BOOST_CHECK_EQUAL(i, 5);
+ get<1>(t) >> i;
+ BOOST_CHECK_EQUAL(i, 7);
+ }
+ {
+ std::istringstream ss("11");
+ std::wistringstream wss(L"13");
+ int i = 0;
+ tuple<test_concept, _a&, _b&, _self&> t(ss, wss, i);
+ ss >> get<2>(t);
+ BOOST_CHECK_EQUAL(i, 11);
+ wss >> get<2>(t);
+ BOOST_CHECK_EQUAL(i, 13);
+ }
+ {
+ std::istringstream ss;
+ std::wistringstream wss;
+ int val = 5;
+ tuple<test_concept, _a&, _b&, _self&> t(ss, wss, val);
+ // we can't do anything with these, but it should
+ // still compile.
+ any<test_concept, const _a&> is(get<0>(t));
+ any<test_concept, const _b&> wis(get<1>(t));
+ }
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_subscript.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_subscript.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,68 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_basic)
+{
+ typedef ::boost::mpl::vector<common<>, subscriptable<int&> > test_concept;
+ int i[5];
+ any<test_concept> x(&i[0]);
+ BOOST_CHECK_EQUAL(&x[0], &i[0]);
+}
+
+BOOST_AUTO_TEST_CASE(test_basic_const)
+{
+ typedef ::boost::mpl::vector<common<>, subscriptable<int&, const _self> > test_concept;
+ int i[5];
+ const any<test_concept> x(&i[0]);
+ BOOST_CHECK_EQUAL(&x[0], &i[0]);
+}
+
+BOOST_AUTO_TEST_CASE(test_any_result)
+{
+ typedef ::boost::mpl::vector<common<>, common<_a>, subscriptable<_a&, const _self> > test_concept;
+ typedef ::boost::mpl::map<
+ ::boost::mpl::pair<_self, int*>,
+ ::boost::mpl::pair<_a, int>
+ > types;
+ int i[5];
+ any<test_concept> x(&i[0], make_binding<types>());
+ any<test_concept, _a&> y(x[0]);
+ BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i[0]);
+}
+
+BOOST_AUTO_TEST_CASE(test_any_result_const)
+{
+ typedef ::boost::mpl::vector<common<>, common<_a>, subscriptable<const _a&, const _self> > test_concept;
+ typedef ::boost::mpl::map<
+ ::boost::mpl::pair<_self, int*>,
+ ::boost::mpl::pair<_a, int>
+ > types;
+ const int i[5] = { 0, 0, 0, 0, 0 };
+ any<test_concept> x(&i[0], make_binding<types>());
+ any<test_concept, const _a&> y(x[0]);
+ BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i[0]);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_tuple.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_tuple.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,92 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/fusion/include/at_c.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/back.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/empty.hpp>
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/distance.hpp>
+#include <boost/fusion/include/next.hpp>
+#include <boost/fusion/include/prior.hpp>
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/fusion/include/advance.hpp>
+#include <boost/fusion/include/deref.hpp>
+#include <boost/fusion/include/value_of.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_same)
+{
+ tuple<common<_a>, _a, _a> t(1, 2);
+ BOOST_CHECK_EQUAL(any_cast<int&>(get<0>(t)), 1);
+ BOOST_CHECK_EQUAL(any_cast<int&>(get<1>(t)), 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_degenerate)
+{
+ tuple<boost::mpl::vector<> > t;
+}
+
+template<class T>
+typename T::value_type get_static(T) { return T::value; }
+
+BOOST_AUTO_TEST_CASE(test_fusion)
+{
+ typedef boost::mpl::vector<common<_a>, common<_b>, addable<_a, _b> > test_concept;
+ tuple<test_concept, _a, _b> t(2.0, 1);
+ BOOST_CHECK_EQUAL(any_cast<double&>(boost::fusion::at_c<0>(t)), 2.0);
+ BOOST_CHECK_EQUAL(any_cast<int&>(boost::fusion::at_c<1>(t)), 1);
+ BOOST_CHECK_EQUAL(any_cast<double&>(boost::fusion::front(t)), 2.0);
+ BOOST_CHECK_EQUAL(any_cast<int&>(boost::fusion::back(t)), 1);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::empty(t)), false);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::size(t)), 2);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::begin(t), boost::fusion::end(t))), 2);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::next(boost::fusion::begin(t)), boost::fusion::end(t))), 1);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::begin(t), boost::fusion::prior(boost::fusion::end(t)))), 1);
+
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::advance_c<2>(boost::fusion::begin(t)), boost::fusion::end(t))), 0);
+ BOOST_CHECK_EQUAL(any_cast<double&>(boost::fusion::deref(boost::fusion::begin(t))), 2.0);
+}
+
+BOOST_AUTO_TEST_CASE(test_fusion_const)
+{
+ typedef boost::mpl::vector<common<_a>, common<_b>, addable<_a, _b> > test_concept;
+ const tuple<test_concept, _a, _b> t(2.0, 1);
+ BOOST_CHECK_EQUAL(any_cast<const double&>(boost::fusion::at_c<0>(t)), 2.0);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(boost::fusion::at_c<1>(t)), 1);
+ BOOST_CHECK_EQUAL(any_cast<const double&>(boost::fusion::front(t)), 2.0);
+ BOOST_CHECK_EQUAL(any_cast<const int&>(boost::fusion::back(t)), 1);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::empty(t)), false);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::size(t)), 2);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::begin(t), boost::fusion::end(t))), 2);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::next(boost::fusion::begin(t)), boost::fusion::end(t))), 1);
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::begin(t), boost::fusion::prior(boost::fusion::end(t)))), 1);
+
+ BOOST_CHECK_EQUAL(get_static(boost::fusion::distance(boost::fusion::advance_c<2>(boost::fusion::begin(t)), boost::fusion::end(t))), 0);
+ BOOST_CHECK_EQUAL(any_cast<const double&>(boost::fusion::deref(boost::fusion::begin(t))), 2.0);
+}

Added: sandbox/type_erasure/libs/type_erasure/test/test_typeid_of.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_typeid_of.cpp 2012-05-11 22:37:24 EDT (Fri, 11 May 2012)
@@ -0,0 +1,71 @@
+// Boost.TypeErasure library
+//
+// Copyright 2011 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <boost/type_erasure/typeid_of.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+template<class T = _self>
+struct common : ::boost::mpl::vector<
+ copy_constructible<T>,
+ typeid_<T>
+> {};
+
+BOOST_AUTO_TEST_CASE(test_val)
+{
+ typedef common<> test_concept;
+ any<test_concept> x(2);
+ BOOST_CHECK(typeid_of(x) == typeid(int));
+ const any<test_concept> y(2);
+ BOOST_CHECK(typeid_of(y) == typeid(int));
+}
+
+BOOST_AUTO_TEST_CASE(test_ref)
+{
+ typedef common<> test_concept;
+ int i;
+ any<test_concept, _self&> x(i);
+ BOOST_CHECK(typeid_of(x) == typeid(int));
+ const any<test_concept, _self&> y(i);
+ BOOST_CHECK(typeid_of(y) == typeid(int));
+}
+
+BOOST_AUTO_TEST_CASE(test_cref)
+{
+ typedef common<> test_concept;
+ int i;
+ any<test_concept, const _self&> x(i);
+ BOOST_CHECK(typeid_of(x) == typeid(int));
+ const any<test_concept, const _self&> y(i);
+ BOOST_CHECK(typeid_of(y) == typeid(int));
+}
+
+BOOST_AUTO_TEST_CASE(test_binding)
+{
+ typedef boost::mpl::vector<common<_a>, common<_b> > test_concept;
+ binding<test_concept> b =
+ make_binding<
+ boost::mpl::map<
+ boost::mpl::pair<_a, int>,
+ boost::mpl::pair<_b, double>
+ >
+ >();
+ BOOST_CHECK(typeid_of<_a>(b) == typeid(int));
+ BOOST_CHECK(typeid_of<_b>(b) == typeid(double));
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk