summaryrefslogtreecommitdiff
path: root/boost/type_erasure/callable.hpp
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
committerChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/type_erasure/callable.hpp
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/type_erasure/callable.hpp')
-rw-r--r--boost/type_erasure/callable.hpp386
1 files changed, 386 insertions, 0 deletions
diff --git a/boost/type_erasure/callable.hpp b/boost/type_erasure/callable.hpp
new file mode 100644
index 0000000000..9de4e222e9
--- /dev/null
+++ b/boost/type_erasure/callable.hpp
@@ -0,0 +1,386 @@
+// 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>
+#include <boost/type_erasure/param.hpp>
+
+namespace boost {
+namespace type_erasure {
+
+template<class Sig, class F = _self>
+struct callable;
+
+namespace detail {
+
+template<class Sig>
+struct result_of_callable;
+
+}
+
+#if defined(BOOST_TYPE_ERASURE_DOXYGEN)
+
+/**
+ * The @ref callable concept allows an @ref any to hold function objects.
+ * @c Sig is interpreted in the same way as for Boost.Function, except
+ * that the arguments and return type are allowed to be placeholders.
+ * @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
+{
+ /**
+ * @c R is the result type of @c Sig and @c T is the argument
+ * types of @c Sig.
+ */
+ static R apply(F& f, T... arg);
+};
+
+#elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template<class R, class... T, class F>
+struct callable<R(T...), F>
+{
+ static R apply(F& f, T... arg)
+ {
+ return f(std::forward<T>(arg)...);
+ }
+};
+
+template<class... T, class F>
+struct callable<void(T...), F>
+{
+ static void apply(F& f, T... arg)
+ {
+ f(std::forward<T>(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::as_param<Base, T>::type...);
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
+ {
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(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::as_param<Base, T>::type...) const;
+ typename ::boost::type_erasure::rebind_any<Base, R>::type operator()(
+ typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
+ {
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(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::as_param<Base, T>::type...);
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg)
+ {
+ return ::boost::type_erasure::call(callable<R(T...), F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(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::as_param<Base, T>::type...) const;
+ using Base::operator();
+ typename ::boost::type_erasure::rebind_any<Base, R>::type
+ operator()(typename ::boost::type_erasure::as_param<Base, T>::type... arg) const
+ {
+ return ::boost::type_erasure::call(callable<R(T...), const F>(), *this,
+ ::std::forward<typename ::boost::type_erasure::as_param<Base, T>::type>(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::as_param<Base, BOOST_PP_CAT(T, n)>::type BOOST_PP_CAT(arg, n)
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+#define BOOST_TYPE_ERASURE_FORWARD(z, n, data) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n)
+#define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) BOOST_PP_CAT(arg, n)
+#else
+#define BOOST_TYPE_ERASURE_FORWARD(z, n, data) ::std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
+#define BOOST_TYPE_ERASURE_FORWARD_REBIND(z, n, data) ::std::forward<typename ::boost::type_erasure::as_param<Base, BOOST_PP_CAT(T, n)>::type>(BOOST_PP_CAT(arg, n))
+#endif
+
+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(N, BOOST_TYPE_ERASURE_FORWARD, (T, 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(N, BOOST_TYPE_ERASURE_FORWARD, (T, 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(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
+ }
+};
+
+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(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
+ }
+};
+
+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(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
+ }
+};
+
+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(N, BOOST_TYPE_ERASURE_FORWARD_REBIND, ~));
+ }
+};
+
+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