1 #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED 2 #define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED 3 4 // Copyright 2015 Peter Dimov. 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // 8 // See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt 10 11 #include <boost/mp11/detail/config.hpp> 12 #include <type_traits> 13 14 namespace boost 15 { 16 namespace mp11 17 { 18 19 // mp_plus 20 namespace detail 21 { 22 23 #if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) 24 25 template<class... T> struct mp_plus_impl 26 { 27 static const auto _v = (T::value + ... + 0); 28 using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; 29 }; 30 31 #else 32 33 template<class... T> struct mp_plus_impl; 34 35 template<> struct mp_plus_impl<> 36 { 37 using type = std::integral_constant<int, 0>; 38 }; 39 40 #if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) 41 42 template<class T1, class... T> struct mp_plus_impl<T1, T...> 43 { 44 static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value; 45 using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; 46 }; 47 48 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...> 49 { 50 static const 51 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) 52 _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 56 #else 57 58 template<class T1, class... T> struct mp_plus_impl<T1, T...> 59 { 60 static const auto _v = T1::value + mp_plus_impl<T...>::type::value; 61 using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; 62 }; 63 64 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...> 65 { 66 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; 67 using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; 68 }; 69 70 #endif 71 72 #endif 73 74 } // namespace detail 75 76 template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type; 77 78 } // namespace mp11 79 } // namespace boost 80 81 #endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED 82