From 491db1599769b6f64702c302e363d6513ca94396 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 2 May 2004 19:55:02 +0000 Subject: [PATCH] boost/utility/result_of.hpp, boost/utility/detail/result_of_iterate.hpp: - result_of implementation libs/utility/test/result_of_test.cpp: - result_of tests libs/utility/test/Jamfile, libs/utility/test/Jamfile.v2: - run result_of tests libs/utility/utility.htm: - document result_of libs/libraries.htm: - list result_of index.htm: - announce result_of [SVN r22720] --- .../utility/detail/result_of_iterate.hpp | 78 +++++++++++++++++++ include/boost/utility/result_of.hpp | 63 +++++++++++++++ test/Jamfile | 3 +- test/Jamfile.v2 | 1 + test/result_of_test.cpp | 45 +++++++++++ utility.htm | 43 +++++++++- 6 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 include/boost/utility/detail/result_of_iterate.hpp create mode 100644 include/boost/utility/result_of.hpp create mode 100644 test/result_of_test.cpp diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp new file mode 100644 index 0000000..c48410c --- /dev/null +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -0,0 +1,78 @@ +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost result_of - do not include this file! +#endif + +// CWPro8 requires an argument in a function type specialization +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 +# define BOOST_RESULT_OF_ARGS void +#else +# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T) +#endif + +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +template +struct result_of + : detail::result_of {}; +#endif + +namespace detail { + +template +struct result_of +{ + typedef R type; +}; + +template +struct result_of +{ + typedef R type; +}; + +#undef BOOST_RESULT_OF_ARGS + +#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) +template +struct result_of +{ + typedef R type; +}; + +template +struct result_of +{ + typedef R type; +}; + +template +struct result_of +{ + typedef R type; +}; + +template +struct result_of +{ + typedef R type; +}; +#endif + +} diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp new file mode 100644 index 0000000..9d2185e --- /dev/null +++ b/include/boost/utility/result_of.hpp @@ -0,0 +1,63 @@ +// Boost result_of library + +// Copyright Doug Gregor 2004. Use, modification and +// distribution is subject to 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) + +// For more information, see http://www.boost.org/libs/utility +#ifndef BOOST_RESULT_OF_HPP +#define BOOST_RESULT_OF_HPP + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_RESULT_OF_NUM_ARGS +# define BOOST_RESULT_OF_NUM_ARGS 10 +#endif + +namespace boost { + +template struct result_of; + +#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +namespace detail { + +BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) + +template struct get_result_of; + +template +struct get_result_of +{ + typedef typename F::result_type type; +}; + +template +struct get_result_of +{ + typedef typename F::template result::type type; +}; + +template +struct get_result_of +{ + typedef void type; +}; + +template +struct result_of : get_result_of::value)> {}; + +} // end namespace detail + +#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,)) +#include BOOST_PP_ITERATE() + +} +#endif // can't use result_of + +#endif // BOOST_RESULT_OF_HPP diff --git a/test/Jamfile b/test/Jamfile index 27465ef..9e114a0 100755 --- a/test/Jamfile +++ b/test/Jamfile @@ -39,5 +39,6 @@ test-suite utility [ run ../enable_if_namespace_disambiguation.cpp $(test_monitor) ] [ run ../enable_if_no_disambiguation.cpp $(test_monitor) ] [ run ../enable_if_partial_specializations.cpp $(test_monitor) ] - [ run next_prior_test.cpp $(test_monitor) ] + [ run next_prior_test.cpp $(test_monitor) ] + [ compile result_of_test.cpp ] ; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 224b426..17d087b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -30,4 +30,5 @@ test-suite utility [ run ../enable_if_namespace_disambiguation.cpp ../../test/build//boost_test_exec_monitor ] [ run ../enable_if_no_disambiguation.cpp ../../test/build//boost_test_exec_monitor ] [ run ../enable_if_partial_specializations.cpp ../../test/build//boost_test_exec_monitor ] + [ compile result_of_test.cpp ] ; diff --git a/test/result_of_test.cpp b/test/result_of_test.cpp new file mode 100644 index 0000000..be732af --- /dev/null +++ b/test/result_of_test.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +struct int_result_type { typedef int result_type; }; + +struct int_result_of +{ + template struct result { typedef int type; }; +}; + +struct int_result_type_and_float_result_of +{ + typedef int result_type; + template struct result { typedef float type; }; +}; + +struct X {}; + +int main() +{ + using namespace boost; + + typedef int (*func_ptr)(float, double); + typedef int (&func_ref)(float, double); + typedef int (X::*mem_func_ptr)(float); + typedef int (X::*mem_func_ptr_c)(float) const; + typedef int (X::*mem_func_ptr_v)(float) volatile; + typedef int (X::*mem_func_ptr_cv)(float) const volatile; + + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + return 0; +} diff --git a/utility.htm b/utility.htm index 1766d15..f953385 100644 --- a/utility.htm +++ b/utility.htm @@ -22,6 +22,7 @@ Class noncopyable
  • Function template addressof()
  • +
  • Class template result_of
  • Function templates checked_delete() and @@ -136,11 +137,51 @@ void f() { // nonaddressable* xpe = &x; /* error */ } +

    Class template + result_of

    The class template + result_of helps determine the type of a + call expression. Given an lvalue f of + type F and lvalues t1, + t2, ..., tN of + types T1, T2, ..., + TN, respectively, the type + result_of<F(T1, T2, ..., + TN)>::type defines the result type + of the expression f(t1, t2, + ...,tN). The implementation permits + the type F to be a function pointer, + function reference, member function pointer, or class + type. When F is a class type with a + member type result_type, + result_of<F(T1, T2, ..., + TN)> is + F::result_type. Otherwise, + result_of<F(T1, T2, ..., + TN)> is F::result<F(T1, + T2, ..., TN)>::type when + N > 0 or void + when N = 0. For additional + information about result_of, see the + current draft of the C++ Library TR, N1647, + or the result_of proposal.

    + +

    Class template result_of resides in + the header <boost/utility/result_of.hpp>. By + default, N may be any value between 0 and + 10. To change the upper limit, define the macro + BOOST_RESULT_OF_NUM_ARGS to the maximum + value for N.

    + +

    This implementation of result_of requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. Contributed by Doug Gregor.

    +

    Class templates for the Base-from-Member Idiom

    See separate documentation.


    Revised  23 December, 200302 May, 2004

    © Copyright boost.org 1999-2003. Permission to copy, use, modify, sell and distribute