Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80914 - in sandbox/type_erasure: boost/type_erasure libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-10-09 17:39:19


Author: steven_watanabe
Date: 2012-10-09 17:39:19 EDT (Tue, 09 Oct 2012)
New Revision: 80914
URL: http://svn.boost.org/trac/boost/changeset/80914

Log:
Handle conversion sequence rank for param.
Text files modified:
   sandbox/type_erasure/boost/type_erasure/any.hpp | 402 ++++++++++++++++++++++++++++++++++++++++
   sandbox/type_erasure/boost/type_erasure/param.hpp | 45 ++++
   sandbox/type_erasure/libs/type_erasure/test/test_param.cpp | 129 ++++++++++++
   3 files changed, 570 insertions(+), 6 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-09 17:39:19 EDT (Tue, 09 Oct 2012)
@@ -1433,6 +1433,408 @@
     table_type table;
 };
 
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+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_reference<U>,
+ ::boost::is_const<U>,
+ ::boost::type_erasure::detail::is_any<U>
+ >
+ >::type* = 0
+#endif
+ )
+ : table((
+ BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
+ ::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((
+ BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
+ binding_arg
+ ))
+ {
+ BOOST_MPL_ASSERT((::boost::is_same<
+ typename ::boost::mpl::at<Map, T>::type, U>));
+ data.data = ::boost::addressof(arg);
+ }
+ /**
+ * Constructs an @ref any from another rvalue reference.
+ *
+ * \param other The reference to copy.
+ *
+ * \throws Nothing.
+ */
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ any(any&& other)
+ : data(other.data),
+ table(std::move(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(std::move(::boost::type_erasure::detail::access::table(other)))
+ {}
+ /**
+ * Constructs an @ref any from another rvalue 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(any<Concept2, Tag2&&>&& other
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+ , typename ::boost::disable_if<
+ ::boost::mpl::or_<
+ ::boost::is_reference<Tag2>,
+ ::boost::is_same<Concept, Concept2>,
+ ::boost::is_const<Tag2>
+ >
+ >::type* = 0
+#endif
+ )
+ : data(::boost::type_erasure::detail::access::data(other)),
+ table(
+ std::move(::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(
+ std::move(::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(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(std::move(::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 rvalue 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)
+ {}
+
+ /**
+ * 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. 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. 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.
+ */
+ template<class U>
+ any& operator=(U& 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. 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.
+ */
+ template<class U>
+ any& operator=(const U& other)
+ {
+ _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 */
+ 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(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(
+ 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(
+ Other& other,
+ const assignable<T, U>*,
+ ::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);
+ }
+ }
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_assign_impl(
+ Other& other,
+ const void*,
+ ::boost::mpl::true_)
+ {
+ any temp(other);
+ _boost_type_erasure_swap(temp);
+ }
+
+ friend struct ::boost::type_erasure::detail::access;
+ ::boost::type_erasure::detail::storage data;
+ table_type table;
+};
+
+#endif
+
 }
 }
 

Modified: sandbox/type_erasure/boost/type_erasure/param.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/param.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/param.hpp 2012-10-09 17:39:19 EDT (Tue, 09 Oct 2012)
@@ -53,10 +53,26 @@
 template<class T>
 struct placeholder_conversion<const T&, const T&> : boost::mpl::true_ {};
 
+#ifndef BOOST_NO_RVALUE_REFERENCES
+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<T&&, T&&> : boost::mpl::true_ {};
+#endif
+
 }
 
+#ifdef __clang__
+#if !__has_feature(cxx_reference_qualified_functions)
+/** INTERNAL ONLY */
+#define BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#endif
+#else
 /** INTERNAL ONLY */
 #define BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#endif
 
 /**
  * \brief A proxy to help with overload resolution for functions
@@ -106,8 +122,6 @@
     /** 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
@@ -131,7 +145,20 @@
         )
       : _impl(a)
     {}
-
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ 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(std::move(a))
+ {}
 #endif
 
     /** Returns the stored @ref any. */
@@ -145,6 +172,10 @@
 template<class Concept, class T>
 class param<Concept, const T&> {
 public:
+ param(const ::boost::type_erasure::detail::storage& data,
+ const ::boost::type_erasure::binding<Concept>& table)
+ : _impl(data, table)
+ {}
     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; }
@@ -155,6 +186,10 @@
 template<class Concept, class T>
 class param<Concept, T&> : public param<Concept, const T&> {
 public:
+ param(const ::boost::type_erasure::detail::storage& data,
+ const ::boost::type_erasure::binding<Concept>& table)
+ : param<Concept, const T&>(data, table)
+ {}
     any<Concept, T&> get() const
     {
         return any<Concept, T&>(
@@ -168,6 +203,10 @@
 template<class Concept, class T>
 class param<Concept, T&&> : public param<Concept, const T&> {
 public:
+ param(const ::boost::type_erasure::detail::storage& data,
+ const ::boost::type_erasure::binding<Concept>& table)
+ : param<Concept, const T&>(data, table)
+ {}
     any<Concept, T&&> get() const
     {
         return any<Concept, T&&>(

Modified: sandbox/type_erasure/libs/type_erasure/test/test_param.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/test_param.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/test/test_param.cpp 2012-10-09 17:39:19 EDT (Tue, 09 Oct 2012)
@@ -1,6 +1,6 @@
 // Boost.TypeErasure library
 //
-// Copyright 2011 Steven Watanabe
+// Copyright 2012 Steven Watanabe
 //
 // Distributed under the Boost Software License Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -55,6 +55,21 @@
 
     BOOST_STATIC_ASSERT(sizeof(f1(i)) == 2);
     BOOST_STATIC_ASSERT(sizeof(f1(1)) == 2);
+
+ // Make sure that the constructors are actually instantiated
+ param<copy_constructible<>, _self&> c1 = a1;
+ // param<copy_constructible<>, _self&> c2 = a2;
+ param<copy_constructible<>, _self&> c3 = a3;
+ param<copy_constructible<>, _self&> c4 = a4;
+ // param<copy_constructible<>, _self&> c5 = a5;
+ // param<copy_constructible<>, _self&> c6 = a6;
+
+ // param<copy_constructible<>, _self&> c7 = a7();
+ // param<copy_constructible<>, _self&> c8 = a8();
+ param<copy_constructible<>, _self&> c9 = a9();
+ param<copy_constructible<>, _self&> c10 = a10();
+ // param<copy_constructible<>, _self&> c11 = a11();
+ // param<copy_constructible<>, _self&> c12 = a12();
 }
 
 size<1>::type f2(param<copy_constructible<>, const _self&>);
@@ -77,6 +92,21 @@
 
     BOOST_STATIC_ASSERT(sizeof(f2(i)) == 2);
     BOOST_STATIC_ASSERT(sizeof(f2(1)) == 2);
+
+ // Make sure that the constructors are actually instantiated
+ param<copy_constructible<>, const _self&> c1 = a1;
+ param<copy_constructible<>, const _self&> c2 = a2;
+ param<copy_constructible<>, const _self&> c3 = a3;
+ param<copy_constructible<>, const _self&> c4 = a4;
+ param<copy_constructible<>, const _self&> c5 = a5;
+ param<copy_constructible<>, const _self&> c6 = a6;
+
+ param<copy_constructible<>, const _self&> c7 = a7();
+ param<copy_constructible<>, const _self&> c8 = a8();
+ param<copy_constructible<>, const _self&> c9 = a9();
+ param<copy_constructible<>, const _self&> c10 = a10();
+ param<copy_constructible<>, const _self&> c11 = a11();
+ param<copy_constructible<>, const _self&> c12 = a12();
 }
 
 size<1>::type f3(param<copy_constructible<>, _self>);
@@ -99,9 +129,24 @@
 
     BOOST_STATIC_ASSERT(sizeof(f3(i)) == 2);
     BOOST_STATIC_ASSERT(sizeof(f3(1)) == 2);
+
+ // Make sure that the constructors are actually instantiated
+ param<copy_constructible<>, _self> c1 = a1;
+ param<copy_constructible<>, _self> c2 = a2;
+ param<copy_constructible<>, _self> c3 = a3;
+ param<copy_constructible<>, _self> c4 = a4;
+ param<copy_constructible<>, _self> c5 = a5;
+ param<copy_constructible<>, _self> c6 = a6;
+
+ param<copy_constructible<>, _self> c7 = a7();
+ param<copy_constructible<>, _self> c8 = a8();
+ param<copy_constructible<>, _self> c9 = a9();
+ param<copy_constructible<>, _self> c10 = a10();
+ param<copy_constructible<>, _self> c11 = a11();
+ param<copy_constructible<>, _self> c12 = a12();
 }
 
-#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#ifndef BOOST_NO_RVALUE_REFERENCES
 
 size<1>::type f4(param<copy_constructible<>, _self&&>);
 size<2>::type f4(...);
@@ -115,7 +160,7 @@
     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(a8())) == 2);
     BOOST_STATIC_ASSERT(sizeof(f4(a9())) == 2);
     BOOST_STATIC_ASSERT(sizeof(f4(a10())) == 2);
     BOOST_STATIC_ASSERT(sizeof(f4(a11())) == 2);
@@ -123,6 +168,84 @@
 
     BOOST_STATIC_ASSERT(sizeof(f4(i)) == 2);
     BOOST_STATIC_ASSERT(sizeof(f4(1)) == 2);
+
+ // Make sure that the constructors are actually instantiated
+ // param<copy_constructible<>, _self&&> c1 = a1;
+ // param<copy_constructible<>, _self&&> c2 = a2;
+ // param<copy_constructible<>, _self&&> c3 = a3;
+ // param<copy_constructible<>, _self&&> c4 = a4;
+ // param<copy_constructible<>, _self&&> c5 = a5;
+ // param<copy_constructible<>, _self&&> c6 = a6;
+
+ param<copy_constructible<>, _self&&> c7 = a7();
+ // param<copy_constructible<>, _self&&> c8 = a8();
+ // param<copy_constructible<>, _self&&> c9 = a9();
+ // param<copy_constructible<>, _self&&> c10 = a10();
+ // param<copy_constructible<>, _self&&> c11 = a11();
+ // param<copy_constructible<>, _self&&> c12 = a12();
+}
+
+#endif
+
+#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+
+// Test conversion sequence rank
+
+size<1>::type f5(param<copy_constructible<>, _self&>);
+size<2>::type f5(param<copy_constructible<>, const _self&>);
+
+void test_ref_cref() {
+ BOOST_STATIC_ASSERT(sizeof(f5(a1)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f5(a2)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f5(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f5(a4)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f5(a5)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f5(a6)) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f5(a7())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f5(a8())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f5(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f5(a10())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f5(a11())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f5(a12())) == 2);
+}
+
+size<1>::type f6(param<copy_constructible<>, _self&>);
+size<2>::type f6(param<copy_constructible<>, _self&&>);
+
+void test_ref_rref() {
+ BOOST_STATIC_ASSERT(sizeof(f6(a1)) == 1);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a2)) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f6(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f6(a4)) == 1);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a5)) == 2);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a6)) == 2);
+
+ BOOST_STATIC_ASSERT(sizeof(f6(a7())) == 2);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a8())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f6(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f6(a10())) == 1);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a11())) == 2);
+ // BOOST_STATIC_ASSERT(sizeof(f6(a12())) == 2);
+}
+
+size<1>::type f7(param<copy_constructible<>, const _self&>);
+size<2>::type f7(param<copy_constructible<>, _self&&>);
+
+void test_cref_rref() {
+ BOOST_STATIC_ASSERT(sizeof(f7(a1)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a2)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a3)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a4)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a5)) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a6)) == 1);
+
+ BOOST_STATIC_ASSERT(sizeof(f7(a7())) == 2);
+ BOOST_STATIC_ASSERT(sizeof(f7(a8())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a9())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a10())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a11())) == 1);
+ BOOST_STATIC_ASSERT(sizeof(f7(a12())) == 1);
 }
 
 #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