constexpr_deduce.hpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. #ifndef BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H
  8. #define BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H
  9. #include <boost/hof/config.hpp>
  10. #define BOOST_HOF_CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x))
  11. #ifndef BOOST_HOF_HAS_CONST_FOLD
  12. #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
  13. #define BOOST_HOF_HAS_CONST_FOLD 0
  14. #elif defined(__clang__) || defined (__GNUC__)
  15. #define BOOST_HOF_HAS_CONST_FOLD 1
  16. #else
  17. #define BOOST_HOF_HAS_CONST_FOLD 0
  18. #endif
  19. #endif
  20. namespace boost { namespace hof {
  21. namespace detail {
  22. struct constexpr_deduce
  23. {
  24. constexpr constexpr_deduce()
  25. {}
  26. template<class F>
  27. constexpr operator F() const
  28. {
  29. return F();
  30. }
  31. };
  32. template<class T>
  33. struct constexpr_deduce_unique
  34. {
  35. constexpr constexpr_deduce_unique()
  36. {}
  37. #if BOOST_HOF_HAS_CONST_FOLD
  38. template<class F>
  39. constexpr operator const F&() const
  40. {
  41. static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty");
  42. return BOOST_HOF_CONST_FOLD(reinterpret_cast<const F&>(static_const_var<T>()));
  43. }
  44. #else
  45. template<class F>
  46. constexpr operator F() const
  47. {
  48. // static_assert(std::is_default_constructible<F>::value, "Function not default constructible");
  49. return F();
  50. }
  51. #endif
  52. };
  53. }}} // namespace boost::hof
  54. #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE true ? boost::hof::detail::constexpr_deduce() :
  55. #define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) true ? boost::hof::detail::constexpr_deduce_unique<T>() :
  56. #ifdef _MSC_VER
  57. #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE
  58. #else
  59. #define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE
  60. #endif
  61. #endif