1 /*=============================================================================
2     Copyright (c) 2015 Paul Fultz II
3     callable_base.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_CALLABLE_BASE_H
9 #define BOOST_HOF_GUARD_CALLABLE_BASE_H
10 
11 #include <boost/hof/detail/delegate.hpp>
12 #include <boost/hof/detail/result_of.hpp>
13 #include <boost/hof/apply.hpp>
14 
15 #ifndef BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS
16 #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
17 #define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 0
18 #else
19 #define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 1
20 #endif
21 #endif
22 
23 namespace boost { namespace hof { namespace detail {
24 
25 template<class F>
26 struct non_class_function
27 {
28     F f;
29     BOOST_HOF_DELEGATE_CONSTRUCTOR(non_class_function, F, f)
30 
31     template<class... Ts>
32     constexpr BOOST_HOF_SFINAE_RESULT(apply_f, id_<F>, id_<Ts>...)
33     operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
34     (
35         boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...)
36     );
37 };
38 
39 template<class F>
40 struct callable_base_type
41 : std::conditional<(BOOST_HOF_IS_CLASS(F) && !BOOST_HOF_IS_FINAL(F) && !BOOST_HOF_IS_POLYMORPHIC(F)), F, non_class_function<F>>
42 {};
43 
44 #if BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS
45 template<class F>
46 using callable_base = typename callable_base_type<F>::type;
47 #else
48 template<class F>
49 struct callable_base
50 : callable_base_type<F>::type
51 {
52     typedef typename callable_base_type<F>::type base;
53     BOOST_HOF_INHERIT_CONSTRUCTOR(callable_base, base)
54 };
55 
56 template<class F>
57 struct callable_base_type<callable_base<F>>
58 : callable_base_type<F>
59 {};
60 
61 #endif
62 
63 }}} // namespace boost::hof
64 
65 #endif
66