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 8 #ifndef BOOST_HOF_GUARD_DETAIL_RESULT_OF_H 9 #define BOOST_HOF_GUARD_DETAIL_RESULT_OF_H 10 11 #include <boost/hof/returns.hpp> 12 #include <boost/hof/config.hpp> 13 14 #if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE 15 16 #include <boost/hof/detail/and.hpp> 17 #include <boost/hof/detail/holder.hpp> 18 #include <boost/hof/detail/can_be_called.hpp> 19 20 namespace boost { namespace hof { namespace detail { 21 22 template<class F, class Args, class=void> 23 struct result_of_impl {}; 24 25 template<class F, class... Ts> 26 struct result_of_impl< 27 F, 28 holder<Ts...>, 29 typename std::enable_if<can_be_called<F, typename Ts::type...>::value>::type 30 > 31 { 32 typedef decltype(std::declval<F>()(std::declval<typename Ts::type>()...)) type; 33 }; 34 } 35 36 template<class T> 37 struct id_ 38 { 39 typedef T type; 40 }; 41 42 template<class F, class... Ts> 43 struct result_of 44 : detail::result_of_impl<F, detail::holder<Ts...>> 45 {}; 46 47 // template<class F, class... Ts> 48 // using result_of = detail::result_of_impl<F, detail::holder<Ts...>>; 49 // using result_of = id_<decltype(std::declval<F>()(std::declval<typename Ts::type>()...))>; 50 51 }} // namespace boost::hof 52 #endif 53 54 #if BOOST_HOF_NO_EXPRESSION_SFINAE 55 56 #define BOOST_HOF_SFINAE_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type 57 #define BOOST_HOF_SFINAE_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return __VA_ARGS__; } 58 59 #else 60 61 #define BOOST_HOF_SFINAE_RESULT(...) auto 62 #define BOOST_HOF_SFINAE_RETURNS BOOST_HOF_RETURNS 63 64 #endif 65 66 #if BOOST_HOF_HAS_MANUAL_DEDUCTION 67 68 #define BOOST_HOF_SFINAE_MANUAL_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type 69 #if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD 70 #define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return (__VA_ARGS__); } 71 #else 72 #define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); } 73 #endif 74 75 #else 76 77 #define BOOST_HOF_SFINAE_MANUAL_RESULT BOOST_HOF_SFINAE_RESULT 78 #define BOOST_HOF_SFINAE_MANUAL_RETURNS BOOST_HOF_SFINAE_RETURNS 79 80 #endif 81 82 #endif 83