Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80909 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-10-08 17:59:51


Author: steven_watanabe
Date: 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
New Revision: 80909
URL: http://svn.boost.org/trac/boost/changeset/80909

Log:
Initial implementation of param.
Added:
   sandbox/type_erasure/boost/type_erasure/param.hpp (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_param.cpp (contents, props changed)
Text files modified:
   sandbox/type_erasure/boost/type_erasure/any.hpp | 20 ++++++++++++++++++--
   sandbox/type_erasure/boost/type_erasure/call.hpp | 21 +++++++++++++++++++++
   sandbox/type_erasure/boost/type_erasure/concept_of.hpp | 10 ++++++++++
   sandbox/type_erasure/boost/type_erasure/detail/access.hpp | 27 +++++++++++++++++++++++++++
   sandbox/type_erasure/boost/type_erasure/free.hpp | 3 ++-
   sandbox/type_erasure/boost/type_erasure/member.hpp | 2 +-
   sandbox/type_erasure/boost/type_erasure/operators.hpp | 35 ++++++++++++++++++-----------------
   sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp | 10 ++++++++++
   sandbox/type_erasure/boost/type_erasure/typeid_of.hpp | 14 ++++++++++++++
   sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam | 1 +
   10 files changed, 122 insertions(+), 21 deletions(-)

Modified: sandbox/type_erasure/boost/type_erasure/any.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/any.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/any.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -42,6 +42,7 @@
 #include <boost/type_erasure/concept_interface.hpp>
 #include <boost/type_erasure/call.hpp>
 #include <boost/type_erasure/relaxed_match.hpp>
+#include <boost/type_erasure/param.hpp>
 
 namespace boost {
 namespace type_erasure {
@@ -661,6 +662,13 @@
     {
         table.template find<destructible<T> >()(data);
     }
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+ /** INTERNAL ONLY */
+ operator param<Concept, T&>() & { return param<Concept, T&>(data, table); }
+ /** INTERNAL ONLY */
+ operator param<Concept, T&&>() && { return param<Concept, T&&>(data, table); }
+#endif
 private:
     /** INTERNAL ONLY */
     void _boost_type_erasure_swap(any& other)
@@ -1135,7 +1143,11 @@
         _boost_type_erasure_resolve_assign(other);
         return *this;
     }
-
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+ /** INTERNAL ONLY */
+ operator param<Concept, T&>() const { return param<Concept, T&>(data, table); }
+#endif
 private:
 
     /** INTERNAL ONLY */
@@ -1404,7 +1416,11 @@
         _boost_type_erasure_swap(temp);
         return *this;
     }
-
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+ /** INTERNAL ONLY */
+ operator param<Concept, const T&>() const { return param<Concept, const T&>(data, table); }
+#endif
 private:
     /** INTERNAL ONLY */
     void _boost_type_erasure_swap(any& other)

Modified: sandbox/type_erasure/boost/type_erasure/call.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/call.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/call.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -90,6 +90,27 @@
     return ::boost::type_erasure::detail::access::data(arg);
 }
 
+template<class Concept, class T>
+::boost::type_erasure::detail::storage&
+convert_arg(param<Concept, 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(param<Concept, const 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(const param<Concept, 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; }
 

Modified: sandbox/type_erasure/boost/type_erasure/concept_of.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/concept_of.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/concept_of.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -17,6 +17,9 @@
 template<class Concept, class T>
 class any;
 
+template<class Concept, class T>
+class param;
+
 /**
  * A metafunction returning the concept corresponding
  * to an @ref any. It will also work for all bases
@@ -42,6 +45,13 @@
     typedef Concept type;
 };
 
+/** INTERNAL ONLY */
+template<class Concept, class T>
+struct concept_of< ::boost::type_erasure::param<Concept, T> >
+{
+ typedef Concept type;
+};
+
 }
 }
 

Modified: sandbox/type_erasure/boost/type_erasure/detail/access.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/access.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/access.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -20,6 +20,9 @@
 template<class Concept, class T>
 class any;
 
+template<class Concept, class T>
+class param;
+
 namespace detail {
 
 struct access
@@ -30,6 +33,12 @@
     {
         return static_cast<const Derived&>(arg).table;
     }
+ template<class Concept, class T>
+ static const typename any<Concept, T>::table_type&
+ table(const ::boost::type_erasure::param<Concept, T>& arg)
+ {
+ return arg._impl.table;
+ }
     template<class Derived>
     static ::boost::type_erasure::detail::storage&
     data(::boost::type_erasure::any_base<Derived>& arg)
@@ -48,6 +57,24 @@
     {
         return static_cast<const Derived&>(arg).data;
     }
+ template<class Concept, class T>
+ static ::boost::type_erasure::detail::storage&
+ data(::boost::type_erasure::param<Concept, T>& arg)
+ {
+ return arg._impl.data;
+ }
+ template<class Concept, class T>
+ static const ::boost::type_erasure::detail::storage&
+ data(::boost::type_erasure::param<Concept, const T&>& arg)
+ {
+ return arg._impl.data;
+ }
+ template<class Concept, class T>
+ static const ::boost::type_erasure::detail::storage&
+ data(const ::boost::type_erasure::param<Concept, T>& arg)
+ {
+ return arg._impl.data;
+ }
 };
 
 }

Modified: sandbox/type_erasure/boost/type_erasure/free.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/free.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/free.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -27,6 +27,7 @@
 #include <boost/type_erasure/config.hpp>
 #include <boost/type_erasure/derived.hpp>
 #include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/param.hpp>
 #include <boost/type_erasure/is_placeholder.hpp>
 #include <boost/type_erasure/call.hpp>
 #include <boost/type_erasure/concept_interface.hpp>
@@ -70,7 +71,7 @@
 #define BOOST_TYPE_ERASURE_FREE_PARAM_TYPE(z, n, data) \
     typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
         ::boost::type_erasure::derived<Base>, \
- ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(T, n)> \
+ ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)> \
>::type BOOST_PP_CAT(t, n)
 
 /** INTERNAL ONLY */

Modified: sandbox/type_erasure/boost/type_erasure/member.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/member.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/member.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -28,7 +28,7 @@
 
 /** INTERNAL ONLY */
 #define BOOST_TYPE_ERASURE_MEMBER_ARG(z, n, data) \
- typename ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(A, n)>::type BOOST_PP_CAT(a, n)
+ typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(A, n)>::type BOOST_PP_CAT(a, n)
 
 /** INTERNAL ONLY */
 #define BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(seq, N) \

Modified: sandbox/type_erasure/boost/type_erasure/operators.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/operators.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/operators.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -19,6 +19,7 @@
 #include <boost/type_erasure/concept_of.hpp>
 #include <boost/type_erasure/derived.hpp>
 #include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/param.hpp>
 #include <boost/type_erasure/relaxed_match.hpp>
 #include <boost/type_erasure/check_match.hpp>
 #include <boost/type_erasure/relaxed_match.hpp>
@@ -133,7 +134,7 @@
     { \
         friend typename rebind_any<Base, R>::type \
         operator op(const typename derived<Base>::type& lhs, \
- typename rebind_any<Base, const U&>::type rhs) \
+ typename as_param<Base, const U&>::type rhs) \
         { \
             return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs); \
         } \
@@ -150,7 +151,7 @@
     { \
         friend typename rebind_any<Base, R>::type \
         operator op(const T& lhs, \
- const typename derived<Base>::type& rhs) \
+ const typename derived<Base>::type& rhs) \
         { \
             return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs); \
         } \
@@ -182,7 +183,7 @@
     { \
         friend typename derived<Base>::type& \
         operator op(typename derived<Base>::type& lhs, \
- typename rebind_any<Base, const U&>::type rhs) \
+ typename as_param<Base, const U&>::type rhs) \
         { \
             ::boost::type_erasure::call(name<T, U>(),lhs, rhs); \
             return lhs; \
@@ -231,7 +232,7 @@
 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)
+ typename as_param<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);
@@ -240,7 +241,7 @@
         }
     }
     friend bool operator!=(const typename derived<Base>::type& lhs,
- typename rebind_any<Base, const U&>::type rhs)
+ typename as_param<Base, const U&>::type rhs)
     {
         return !(lhs == rhs);
     }
@@ -304,7 +305,7 @@
 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)
+ typename as_param<Base, const T&>::type rhs)
     {
         return ::boost::type_erasure::detail::less_impl(
             less_than_comparable<T, T>(),
@@ -313,16 +314,16 @@
                 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)
+ typename as_param<Base, const T&>::type rhs)
     {
         return !(lhs < rhs);
     }
- friend bool operator>(typename rebind_any<Base, const T&>::type lhs,
+ friend bool operator>(typename as_param<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,
+ friend bool operator<=(typename as_param<Base, const T&>::type lhs,
                           const typename derived<Base>::type& rhs)
     {
         return !(rhs < lhs);
@@ -333,21 +334,21 @@
 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)
+ typename as_param<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)
+ typename as_param<Base, const U&>::type rhs)
     {
         return !(lhs < rhs);
     }
- friend bool operator>(typename rebind_any<Base, const U&>::type lhs,
+ friend bool operator>(typename as_param<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,
+ friend bool operator<=(typename as_param<Base, const U&>::type lhs,
                           const typename derived<Base>::type& rhs)
     {
         return !(rhs < lhs);
@@ -394,7 +395,7 @@
 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)
+ typename ::boost::type_erasure::as_param<Base, const N&>::type index)
     {
         return ::boost::type_erasure::call(subscriptable<R, T, N>(), *this, index);
     }
@@ -404,7 +405,7 @@
 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
+ typename ::boost::type_erasure::as_param<Base, const N&>::type index) const
     {
         return ::boost::type_erasure::call(subscriptable<R, const T, N>(), *this, index);
     }
@@ -429,7 +430,7 @@
 {
     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)
+ typename ::boost::type_erasure::as_param<Base, const T&>::type rhs)
     {
         ::boost::type_erasure::call(ostreamable<Os, T>(), lhs, rhs);
         return lhs;
@@ -473,7 +474,7 @@
 {
     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)
+ typename ::boost::type_erasure::as_param<Base, T&>::type rhs)
     {
         ::boost::type_erasure::call(istreamable<Is, T>(), lhs, rhs);
         return lhs;

Added: sandbox/type_erasure/boost/type_erasure/param.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/param.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -0,0 +1,206 @@
+// 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_PARAM_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_PARAM_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.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;
+
+namespace detail {
+
+template<class From, class To>
+struct placeholder_conversion : boost::mpl::false_ {};
+template<class T>
+struct placeholder_conversion<T, T> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<T, T&> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<T, const T&> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<const T, T> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<const T, const T&> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<T&, T> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<T&, T&> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<T&, const T&> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<const T&, T> : boost::mpl::true_ {};
+template<class T>
+struct placeholder_conversion<const T&, const T&> : boost::mpl::true_ {};
+
+}
+
+/** INTERNAL ONLY */
+#define BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+
+/**
+ * \brief A proxy to help with overload resolution for functions
+ * operating on an @ref any.
+ *
+ * The template arguments are interpreted in
+ * the same way as @ref any.
+ *
+ * A parameter of type @ref param can be initialized
+ * with an @ref any that has the same @c Concept
+ * and base placeholder when there exists a corresponding
+ * standard conversion for the placeholder.
+ * A conversion sequence from @ref any<C, P> to @ref param<C, P1> is
+ * a better conversion sequence than @ref any<C, P> to @ref param<C, C2>
+ * iff the corresponding placeholder standard conversion
+ * sequence from P to P1 is a better conversion sequence than
+ * P to P2.
+ *
+ * \note Overloading based on cv-qualifiers and rvalue-ness is
+ * only supported in C++11. In C++03, all conversion sequences
+ * from @ref any to @ref param have the same rank.
+ *
+ * Example:
+ *
+ * \code
+ * void f(param<C, _a&>);
+ * void f(param<C, const _a&>);
+ * void g(param<C, const _a&>);
+ * void g(param<C, _a&&>);
+ *
+ * any<C, _a> a;
+ * f(any<C, _a>()); // calls void f(param<C, const _a&>);
+ * f(a); // calls void f(param<C, _a&>); (ambiguous in C++03)
+ * g(any<C, _a>()); // calls void g(param<C, _a&&>); (ambiguous in C++03)
+ * g(a); // calls void g(param<C, const _a&>);
+ * \endcode
+ *
+ */
+template<class Concept, class T>
+class param {
+public:
+
+ friend struct boost::type_erasure::detail::access;
+
+ /** INTERNAL ONLY */
+ typedef void _boost_type_erasure_is_any;
+ /** INTERNAL ONLY */
+ typedef param _boost_type_erasure_derived_type;
+
+#ifdef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+
+ template<class U>
+ param(any<Concept, U>& a
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename boost::enable_if<
+ ::boost::type_erasure::detail::placeholder_conversion<U, T>
+ >::type* = 0
+#endif
+ )
+ : _impl(a)
+ {}
+ template<class U>
+ param(const any<Concept, U>& a
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename boost::enable_if<
+ ::boost::type_erasure::detail::placeholder_conversion<
+ typename ::boost::add_const<U>::type,
+ T
+ >
+ >::type* = 0
+#endif
+ )
+ : _impl(a)
+ {}
+
+#endif
+
+ /** Returns the stored @ref any. */
+ any<Concept, T> get() const { return _impl; }
+private:
+ any<Concept, T> _impl;
+};
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+
+template<class Concept, class T>
+class param<Concept, const T&> {
+public:
+ template<class U>
+ param(U& u, typename boost::enable_if< ::boost::is_same<U, const any<Concept, T> > >::type* = 0) : _impl(u) {}
+ any<Concept, const T&> get() const { return _impl; }
+protected:
+ any<Concept, const T&> _impl;
+};
+
+template<class Concept, class T>
+class param<Concept, T&> : public param<Concept, const T&> {
+public:
+ any<Concept, T&> get() const
+ {
+ return any<Concept, T&>(
+ ::boost::type_erasure::detail::access::data(this->_impl),
+ ::boost::type_erasure::detail::access::table(this->_impl));
+ }
+};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class Concept, class T>
+class param<Concept, T&&> : public param<Concept, const T&> {
+public:
+ any<Concept, T&&> get() const
+ {
+ return any<Concept, T&&>(
+ ::boost::type_erasure::detail::access::data(this->_impl),
+ ::boost::type_erasure::detail::access::table(this->_impl));
+ }
+};
+
+#endif
+
+#endif
+
+/** \brief Metafunction that creates a @ref param.
+ *
+ * If @c T is a (cv/reference qualifed) placeholder,
+ * returns @ref param<@ref concept_of "concept_of"&lt;Any&gt;::type, T>, otherwise, returns T.
+ */
+template<class Any, class T>
+struct as_param {
+#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>,
+ param<typename ::boost::type_erasure::concept_of<Any>::type, T>,
+ T
+ >::type type;
+#endif
+};
+
+}
+}
+
+#endif

Modified: sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/placeholder_of.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -17,6 +17,9 @@
 template<class Concept, class T>
 class any;
 
+template<class Concept, class T>
+class param;
+
 /**
  * A metafunction returning the (const/reference qualified) placeholder
  * corresponding to an @ref any. It will also work for all bases
@@ -42,6 +45,13 @@
     typedef T type;
 };
 
+/** INTERNAL ONLY */
+template<class Concept, class T>
+struct placeholder_of< ::boost::type_erasure::param<Concept, T> >
+{
+ typedef T type;
+};
+
 }
 }
 

Modified: sandbox/type_erasure/boost/type_erasure/typeid_of.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/typeid_of.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/typeid_of.hpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -41,6 +41,20 @@
>()();
 }
 
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+template<class Concept, class T>
+const std::type_info& typeid_of(const param<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
+ >
+ >()();
+}
+#endif
+
 /**
  * \overload
  */

Modified: sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam (original)
+++ sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -37,6 +37,7 @@
 run test_null.cpp /boost//unit_test_framework ;
 run test_free.cpp /boost//unit_test_framework ;
 
+compile test_param.cpp ;
 compile test_is_subconcept.cpp ;
 
 compile-fail fail_default_construct.cpp ;

Added: sandbox/type_erasure/libs/type_erasure/test/test_param.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_param.cpp 2012-10-08 17:59:50 EDT (Mon, 08 Oct 2012)
@@ -0,0 +1,128 @@
+// 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/param.hpp>
+#include <boost/type_erasure/builtin.hpp>
+
+using namespace boost::type_erasure;
+
+template<int N>
+struct size { typedef char (&type)[N]; };
+
+// lvalues
+extern any<copy_constructible<>, _self> a1;
+extern const any<copy_constructible<>, _self> a2;
+extern any<copy_constructible<>, _self&> a3;
+extern const any<copy_constructible<>, _self&> a4;
+extern any<copy_constructible<>, const _self&> a5;
+extern const any<copy_constructible<>, const _self&> a6;
+
+// rvalues
+any<copy_constructible<>, _self> a7();
+const any<copy_constructible<>, _self> a8();
+any<copy_constructible<>, _self&> a9();
+const any<copy_constructible<>, _self&> a10();
+any<copy_constructible<>, const _self&> a11();
+const any<copy_constructible<>, const _self&> a12();
+
+extern int i;
+
+size<1>::type f1(param<copy_constructible<>, _self&>);
+size<2>::type f1(...);
+
+void test_ref() {
+ BOOST_STATIC_ASSERT(sizeof(f1(a1)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f1(a2)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f1(a4)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f1(a5)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(a6)) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f1(a7())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(a8())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f1(a10())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f1(a11())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(a12())) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f1(i)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f1(1)) == 2);
+}
+
+size<1>::type f2(param<copy_constructible<>, const _self&>);
+size<2>::type f2(...);
+
+void test_cref() {
+ BOOST_STATIC_ASSERT(sizeof(f2(a1)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a2)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a4)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a5)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a6)) == 1);
+
+ BOOST_STATIC_ASSERT(sizeof(f2(a7())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a8())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a10())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a11())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f2(a12())) == 1);
+
+ BOOST_STATIC_ASSERT(sizeof(f2(i)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f2(1)) == 2);
+}
+
+size<1>::type f3(param<copy_constructible<>, _self>);
+size<2>::type f3(...);
+
+void test_val() {
+ BOOST_STATIC_ASSERT(sizeof(f3(a1)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a2)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a4)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a5)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a6)) == 1);
+
+ BOOST_STATIC_ASSERT(sizeof(f3(a7())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a8())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a10())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a11())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f3(a12())) == 1);
+
+ BOOST_STATIC_ASSERT(sizeof(f3(i)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f3(1)) == 2);
+}
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+
+size<1>::type f4(param<copy_constructible<>, _self&&>);
+size<2>::type f4(...);
+
+void test_rref() {
+ BOOST_STATIC_ASSERT(sizeof(f4(a1)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a2)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a3)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a4)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a5)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a6)) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f4(a7())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f4(a8())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f4(a9())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a10())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a11())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(a12())) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f4(i)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f4(1)) == 2);
+}
+
+#endif


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