result_of.hpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*=============================================================================
  2. Copyright (c) 2015 Paul Fultz II
  3. result_of.h
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef BOOST_HOF_GUARD_DETAIL_RESULT_OF_H
  8. #define BOOST_HOF_GUARD_DETAIL_RESULT_OF_H
  9. #include <boost/hof/returns.hpp>
  10. #include <boost/hof/config.hpp>
  11. #if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
  12. #include <boost/hof/detail/and.hpp>
  13. #include <boost/hof/detail/holder.hpp>
  14. #include <boost/hof/detail/can_be_called.hpp>
  15. namespace boost { namespace hof { namespace detail {
  16. template<class F, class Args, class=void>
  17. struct result_of_impl {};
  18. template<class F, class... Ts>
  19. struct result_of_impl<
  20. F,
  21. holder<Ts...>,
  22. typename std::enable_if<can_be_called<F, typename Ts::type...>::value>::type
  23. >
  24. {
  25. typedef decltype(std::declval<F>()(std::declval<typename Ts::type>()...)) type;
  26. };
  27. }
  28. template<class T>
  29. struct id_
  30. {
  31. typedef T type;
  32. };
  33. template<class F, class... Ts>
  34. struct result_of
  35. : detail::result_of_impl<F, detail::holder<Ts...>>
  36. {};
  37. // template<class F, class... Ts>
  38. // using result_of = detail::result_of_impl<F, detail::holder<Ts...>>;
  39. // using result_of = id_<decltype(std::declval<F>()(std::declval<typename Ts::type>()...))>;
  40. }} // namespace boost::hof
  41. #endif
  42. #if BOOST_HOF_NO_EXPRESSION_SFINAE
  43. #define BOOST_HOF_SFINAE_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type
  44. #define BOOST_HOF_SFINAE_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return __VA_ARGS__; }
  45. #else
  46. #define BOOST_HOF_SFINAE_RESULT(...) auto
  47. #define BOOST_HOF_SFINAE_RETURNS BOOST_HOF_RETURNS
  48. #endif
  49. #if BOOST_HOF_HAS_MANUAL_DEDUCTION
  50. #define BOOST_HOF_SFINAE_MANUAL_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type
  51. #if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD
  52. #define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return (__VA_ARGS__); }
  53. #else
  54. #define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); }
  55. #endif
  56. #else
  57. #define BOOST_HOF_SFINAE_MANUAL_RESULT BOOST_HOF_SFINAE_RESULT
  58. #define BOOST_HOF_SFINAE_MANUAL_RETURNS BOOST_HOF_SFINAE_RETURNS
  59. #endif
  60. #endif