Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80886 - in sandbox/type_erasure/boost/type_erasure: . detail
From: steven_at_[hidden]
Date: 2012-10-06 13:19:08


Author: steven_watanabe
Date: 2012-10-06 13:19:08 EDT (Sat, 06 Oct 2012)
New Revision: 80886
URL: http://svn.boost.org/trac/boost/changeset/80886

Log:
Check the arguments for call with SFINAE.
Added:
   sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp (contents, props changed)
Text files modified:
   sandbox/type_erasure/boost/type_erasure/call.hpp | 14 ++++++++------
   sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp | 1 +
   2 files changed, 9 insertions(+), 6 deletions(-)

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-06 13:19:08 EDT (Sat, 06 Oct 2012)
@@ -32,6 +32,7 @@
 #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/detail/check_call.hpp>
 #include <boost/type_erasure/is_placeholder.hpp>
 #include <boost/type_erasure/concept_of.hpp>
 #include <boost/type_erasure/config.hpp>
@@ -148,8 +149,9 @@
 
 namespace detail {
     
-template<class Sig, class Args, class Concept = void>
-struct call_impl;
+template<class Sig, class Args, class Concept = void,
+ bool Check = ::boost::type_erasure::detail::check_call<Sig, Args>::type::value>
+struct call_impl {};
 
 template<class Op, class Args, class Concept = void>
 struct call_result :
@@ -227,7 +229,7 @@
 };
 
 template<class R, class... T, class... U, class Concept>
-struct call_impl<R(T...), void(U...), Concept> :
+struct call_impl<R(T...), void(U...), Concept, true> :
     ::boost::type_erasure::detail::call_impl_dispatch<
         R(T...),
         void(U...),
@@ -238,7 +240,7 @@
 };
 
 template<class R, class... T, class... U>
-struct call_impl<R(T...), void(U&...), void> :
+struct call_impl<R(T...), void(U&...), void, true> :
     ::boost::type_erasure::detail::call_impl_dispatch<
         R(T...),
         void(U&...),
@@ -449,7 +451,7 @@
     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>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)), Concept, true>
   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U), Concept>
 {};
 
@@ -460,7 +462,7 @@
     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))>
+struct call_impl<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)), void, true>
   : BOOST_PP_CAT(call_impl, N)<R BOOST_PP_ENUM_TRAILING_PARAMS(N, T) BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
 {};
 

Modified: sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp (original)
+++ sandbox/type_erasure/boost/type_erasure/detail/any_base.hpp 2012-10-06 13:19:08 EDT (Sat, 06 Oct 2012)
@@ -17,6 +17,7 @@
 template<class Derived>
 struct any_base
 {
+ typedef void _boost_type_erasure_is_any;
     typedef Derived _boost_type_erasure_derived_type;
     void* _boost_type_erasure_deduce_constructor(...) { return 0; }
     void* _boost_type_erasure_deduce_assign(...) { return 0; }

Added: sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/check_call.hpp 2012-10-06 13:19:08 EDT (Sat, 06 Oct 2012)
@@ -0,0 +1,137 @@
+// 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$
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+#ifndef BOOST_TYPE_ERASURE_DETAIL_CHECK_CALL_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_DETAIL_CHECK_CALL_HPP_INCLUDED
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/type_erasure/placeholder_of.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<class Sig, class Args>
+struct check_call : ::boost::mpl::false_ {};
+
+template<class T, class Enable = void>
+struct qualified_placeholder
+{
+ typedef void type;
+};
+
+template<class T>
+struct qualified_placeholder<T, typename T::_boost_type_erasure_is_any>
+{
+ typedef typename ::boost::type_erasure::placeholder_of<T>::type placeholder;
+ typedef typename ::boost::remove_reference<placeholder>::type unref;
+ typedef typename ::boost::mpl::if_< ::boost::is_const<T>,
+ const unref,
+ unref
+ >::type add_const;
+ typedef typename ::boost::mpl::if_< ::boost::is_reference<placeholder>,
+ unref,
+ add_const
+ >::type type;
+};
+
+template<class P, class A>
+struct check_placeholder_arg_impl : ::boost::mpl::false_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<P, P> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<P, const P> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<P&, P> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<const P&, P> : ::boost::mpl::true_ {};
+
+template<class P>
+struct check_placeholder_arg_impl<const P&, const P> : ::boost::mpl::true_ {};
+
+template<class P, class Arg>
+struct check_placeholder_arg :
+ check_placeholder_arg_impl<
+ P,
+ typename ::boost::type_erasure::detail::qualified_placeholder<Arg>::type
+ >::type
+{};
+
+template<class FormalArg, class ActualArg>
+struct check_arg
+{
+ typedef typename ::boost::mpl::eval_if<
+ is_placeholder<
+ typename ::boost::remove_cv<
+ typename ::boost::remove_reference<FormalArg>::type
+ >::type
+ >,
+ ::boost::type_erasure::detail::check_placeholder_arg<FormalArg, ActualArg>,
+ ::boost::is_convertible<ActualArg&, FormalArg>
+ >::type type;
+};
+
+#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/check_call.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
+#include BOOST_PP_ITERATE()
+
+}
+}
+}
+
+#endif
+
+#else
+
+#define N BOOST_PP_ITERATION()
+
+#define BOOST_TYPE_ERASURE_CHECK_ARG(z, n, data) \
+ typedef typename ::boost::type_erasure::detail::check_arg< \
+ BOOST_PP_CAT(T, n), \
+ BOOST_PP_CAT(U, n) \
+ >::type BOOST_PP_CAT(check, n); \
+ typedef typename ::boost::mpl::and_< \
+ BOOST_PP_CAT(type, n), \
+ BOOST_PP_CAT(check, n) \
+ >::type BOOST_PP_CAT(type, BOOST_PP_INC(n));
+
+template<
+ class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
+>
+struct check_call<R(BOOST_PP_ENUM_PARAMS(N, T)), void(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u))> {
+ typedef ::boost::mpl::true_ type0;
+ BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CHECK_ARG, ~)
+ typedef BOOST_PP_CAT(type, N) type;
+};
+
+#undef N
+
+#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