result_of.hpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // (C) Copyright Tobias Schwinger
  2. //
  3. // Use modification and distribution are subject to the boost Software License,
  4. // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
  5. //------------------------------------------------------------------------------
  6. //
  7. // Reimplementation of the Boost result_of utility (see [Gregor01] and
  8. // [Gregor02]).
  9. //
  10. //
  11. // Detailed description
  12. // ====================
  13. //
  14. // This example implements the functionality of the Boost result_of utility.
  15. // Because of FunctionTypes we get away without repetitive code and the Boost
  16. // Preprocessor library.
  17. //
  18. //
  19. // Bibliography
  20. // ============
  21. //
  22. // [Gregor01] Gregor, D. The Boost result_of utility
  23. // http://www.boost.org/libs/utility
  24. //
  25. // [Gregor02] Gregor, D. A uniform method for computing function object return
  26. // types (revision 1)
  27. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html
  28. #include <boost/function_types/result_type.hpp>
  29. #include <boost/function_types/is_callable_builtin.hpp>
  30. #include <boost/mpl/eval_if.hpp>
  31. #include <boost/mpl/has_xxx.hpp>
  32. namespace example
  33. {
  34. namespace ft = boost::function_types;
  35. namespace mpl = boost::mpl;
  36. template<typename F> struct result_of;
  37. namespace detail
  38. {
  39. BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
  40. template<typename F>
  41. struct result_type_member
  42. {
  43. typedef typename F::result_type type;
  44. };
  45. template<typename F, typename Desc>
  46. struct result_member_template
  47. {
  48. typedef typename F::template result<Desc>::type type;
  49. };
  50. #if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
  51. template<typename F>
  52. struct result_member_template< F, F(void) >
  53. {
  54. typedef void type;
  55. };
  56. #endif
  57. template<typename F, typename Desc>
  58. struct result_of_impl
  59. : mpl::eval_if
  60. < ft::is_callable_builtin<F>
  61. , ft::result_type<F>
  62. , mpl::eval_if
  63. < has_result_type<F>
  64. , result_type_member<F>
  65. , result_member_template<F,Desc>
  66. > >
  67. { };
  68. }
  69. template<typename Desc>
  70. struct result_of
  71. : detail::result_of_impl< typename ft::result_type<Desc>::type, Desc >
  72. { };
  73. }