1 /*============================================================================= 2 Copyright (c) 2015 Paul Fultz II 3 constexpr_deduce.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_FUNCTION_CONSTEXPR_DEDUCE_H 9 #define BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H 10 11 #include <boost/hof/config.hpp> 12 13 #define BOOST_HOF_CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x)) 14 15 #ifndef BOOST_HOF_HAS_CONST_FOLD 16 #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 17 #define BOOST_HOF_HAS_CONST_FOLD 0 18 #elif defined(__clang__) || defined (__GNUC__) 19 #define BOOST_HOF_HAS_CONST_FOLD 1 20 #else 21 #define BOOST_HOF_HAS_CONST_FOLD 0 22 #endif 23 #endif 24 25 26 namespace boost { namespace hof { 27 28 namespace detail { 29 30 struct constexpr_deduce 31 { constexpr_deduceboost::hof::detail::constexpr_deduce32 constexpr constexpr_deduce() 33 {} 34 template<class F> operator Fboost::hof::detail::constexpr_deduce35 constexpr operator F() const 36 { 37 return F(); 38 } 39 }; 40 41 template<class T> 42 struct constexpr_deduce_unique 43 { constexpr_deduce_uniqueboost::hof::detail::constexpr_deduce_unique44 constexpr constexpr_deduce_unique() 45 {} 46 #if BOOST_HOF_HAS_CONST_FOLD 47 template<class F> operator const F&boost::hof::detail::constexpr_deduce_unique48 constexpr operator const F&() const 49 { 50 static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty"); 51 return BOOST_HOF_CONST_FOLD(reinterpret_cast<const F&>(static_const_var<T>())); 52 } 53 #else 54 template<class F> operator Fboost::hof::detail::constexpr_deduce_unique55 constexpr operator F() const 56 { 57 // static_assert(std::is_default_constructible<F>::value, "Function not default constructible"); 58 return F(); 59 } 60 #endif 61 }; 62 63 }}} // namespace boost::hof 64 65 #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE true ? boost::hof::detail::constexpr_deduce() : 66 #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) true ? boost::hof::detail::constexpr_deduce_unique<T>() : 67 68 #ifdef _MSC_VER 69 #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE 70 #else 71 #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE 72 #endif 73 74 #endif 75