Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83325 - in sandbox/type_erasure: boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2013-03-05 17:24:26


Author: steven_watanabe
Date: 2013-03-05 17:24:25 EST (Tue, 05 Mar 2013)
New Revision: 83325
URL: http://svn.boost.org/trac/boost/changeset/83325

Log:
Tests for returning references. Fix for returning rv refs.
Text files modified:
   sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp | 42 +++++++++++++++++
   sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp | 96 ++++++++++++++++++++++++++++++++++++++++
   2 files changed, 137 insertions(+), 1 deletions(-)

Modified: sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/adapt_to_vtable.hpp 2013-03-05 17:24:25 EST (Tue, 05 Mar 2013)
@@ -174,7 +174,7 @@
>::type type;
 };
 
-#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
 
 template<class PrimitiveConcept, class Sig, class ConceptSig>
 struct vtable_adapter_impl;
@@ -205,6 +205,20 @@
     }
 };
 
+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;
+ R2 tmp = PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...);
+ typename ::boost::remove_reference<R2>::type* p = ::boost::addressof(tmp);
+ result.data = const_cast<void*>(static_cast<const void*>(p));
+ return result;
+ }
+};
+
 template<class PrimitiveConcept, class Sig>
 struct vtable_adapter
     : vtable_adapter_impl<
@@ -302,6 +316,32 @@
     }
 };
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+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 traits::result_type tmp =
+ PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
+ typename ::boost::remove_reference<typename traits::result_type>::type* p =
+ ::boost::addressof(tmp);
+ result.data = const_cast<void*>(static_cast<const void*>(p));
+ return result;
+ }
+};
+
+#endif
+
 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
 struct get_vtable_signature<R(BOOST_PP_ENUM_PARAMS(N, T))>
 {

Modified: sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp (original)
+++ sandbox/type_erasure/libs/type_erasure/test/test_callable.cpp 2013-03-05 17:24:25 EST (Tue, 05 Mar 2013)
@@ -376,6 +376,70 @@
     BOOST_MPL_ASSERT((boost::is_same<boost::result_of<const any<test_concept>(any<test_concept, _a>)>::type, int>));
 }
 
+struct model_ret_ref
+{
+ model_ret_ref& operator()() { return *this; }
+};
+
+BOOST_AUTO_TEST_CASE(test_ref_any_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<_self&()>
+ > test_concept;
+
+ any<test_concept> x1 = model_ret_ref();
+ any<test_concept, _self&> x2(x1());
+ BOOST_CHECK_EQUAL(any_cast<model_ret_ref*>(&x1), any_cast<model_ret_ref*>(&x2));
+}
+
+int f_ret_ref_val;
+int& f_ret_ref() { return f_ret_ref_val; }
+
+BOOST_AUTO_TEST_CASE(test_ref_int_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int&()>
+ > test_concept;
+
+ any<test_concept> x1 = f_ret_ref;
+ int& result = x1();
+ BOOST_CHECK_EQUAL(&result, &f_ret_ref_val);
+}
+
+struct model_ret_cref
+{
+ const model_ret_cref& operator()() { return *this; }
+};
+
+BOOST_AUTO_TEST_CASE(test_cref_any_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<const _self&()>
+ > test_concept;
+
+ any<test_concept> x1 = model_ret_ref();
+ any<test_concept, const _self&> x2(x1());
+ BOOST_CHECK_EQUAL(any_cast<const model_ret_cref*>(&x1), any_cast<const model_ret_cref*>(&x2));
+}
+
+int f_ret_cref_val;
+const int& f_ret_cref() { return f_ret_cref_val; }
+
+BOOST_AUTO_TEST_CASE(test_cref_int_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<const int&()>
+ > test_concept;
+
+ any<test_concept> x1 = f_ret_cref;
+ const int& result = x1();
+ BOOST_CHECK_EQUAL(&result, &f_ret_cref_val);
+}
+
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
 
 int f_rv_value = 0;
@@ -437,4 +501,36 @@
     BOOST_CHECK_EQUAL(f_rv_value, 4);
 }
 
+struct model_ret_rref
+{
+ model_ret_rref&& operator()() { return std::move(*this); }
+};
+
+BOOST_AUTO_TEST_CASE(test_rvalue_any_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<_self&&()>
+ > test_concept;
+
+ any<test_concept> x1 = model_ret_rref();
+ any<test_concept, _self&&> x2(x1());
+ BOOST_CHECK_EQUAL(any_cast<model_ret_rref*>(&x1), any_cast<model_ret_rref*>(&x2));
+}
+
+int f_ret_rv_val;
+int&& f_ret_rv() { return std::move(f_ret_rv_val); }
+
+BOOST_AUTO_TEST_CASE(test_rvalue_int_result)
+{
+ typedef ::boost::mpl::vector<
+ common<>,
+ callable<int&&()>
+ > test_concept;
+
+ any<test_concept> x1 = f_ret_rv;
+ int&& result = x1();
+ BOOST_CHECK_EQUAL(&result, &f_ret_rv_val);
+}
+
 #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