mp_plus.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
  2. #define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
  3. // Copyright 2015 Peter Dimov.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. //
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. #include <boost/mp11/detail/config.hpp>
  10. #include <type_traits>
  11. namespace boost
  12. {
  13. namespace mp11
  14. {
  15. // mp_plus
  16. namespace detail
  17. {
  18. #if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 )
  19. // msvc fails with parser stack overflow for large sizeof...(T)
  20. // clang exceeds -fbracket-depth, which defaults to 256
  21. template<class... T> struct mp_plus_impl
  22. {
  23. static const auto _v = (T::value + ... + 0);
  24. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  25. };
  26. #else
  27. template<class... T> struct mp_plus_impl;
  28. template<> struct mp_plus_impl<>
  29. {
  30. using type = std::integral_constant<int, 0>;
  31. };
  32. #if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
  33. template<class T1, class... T> struct mp_plus_impl<T1, T...>
  34. {
  35. static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
  36. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  37. };
  38. template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
  39. {
  40. static const
  41. decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
  42. _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
  43. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  44. };
  45. #else
  46. template<class T1, class... T> struct mp_plus_impl<T1, T...>
  47. {
  48. static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
  49. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  50. };
  51. template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
  52. {
  53. static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
  54. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  55. };
  56. #endif
  57. #endif
  58. } // namespace detail
  59. template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
  60. } // namespace mp11
  61. } // namespace boost
  62. #endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED