mp_plus.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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, < 1920 )
  19. template<class... T> struct mp_plus_impl
  20. {
  21. static const auto _v = (T::value + ... + 0);
  22. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  23. };
  24. #else
  25. template<class... T> struct mp_plus_impl;
  26. template<> struct mp_plus_impl<>
  27. {
  28. using type = std::integral_constant<int, 0>;
  29. };
  30. #if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
  31. template<class T1, class... T> struct mp_plus_impl<T1, T...>
  32. {
  33. static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
  34. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  35. };
  36. 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...>
  37. {
  38. static const
  39. 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)
  40. _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;
  41. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  42. };
  43. #else
  44. template<class T1, class... T> struct mp_plus_impl<T1, T...>
  45. {
  46. static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
  47. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  48. };
  49. 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...>
  50. {
  51. 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;
  52. using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
  53. };
  54. #endif
  55. #endif
  56. } // namespace detail
  57. template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
  58. } // namespace mp11
  59. } // namespace boost
  60. #endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED