mp_plus.hpp 2.7 KB

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