File indexing completed on 2025-01-18 09:40:54
0001 #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
0002 #define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <boost/mp11/integral.hpp>
0012 #include <boost/mp11/detail/mp_plus.hpp>
0013 #include <boost/mp11/detail/config.hpp>
0014
0015 namespace boost
0016 {
0017 namespace mp11
0018 {
0019
0020
0021 namespace detail
0022 {
0023
0024 #if !defined( BOOST_MP11_NO_CONSTEXPR )
0025
0026 constexpr std::size_t cx_plus()
0027 {
0028 return 0;
0029 }
0030
0031 template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
0032 {
0033 return static_cast<std::size_t>(t1) + cx_plus(t...);
0034 }
0035
0036 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
0037 constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
0038 {
0039 return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
0040 }
0041
0042 #endif
0043
0044 template<class L, class V> struct mp_count_impl;
0045
0046 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
0047
0048 template<class V, class... T> constexpr std::size_t cx_count()
0049 {
0050 constexpr bool a[] = { false, std::is_same<T, V>::value... };
0051
0052 std::size_t r = 0;
0053
0054 for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
0055 {
0056 r += a[ i ];
0057 }
0058
0059 return r;
0060 }
0061
0062 template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
0063 {
0064 using type = mp_size_t<cx_count<V, T...>()>;
0065 };
0066
0067 #elif !defined( BOOST_MP11_NO_CONSTEXPR )
0068
0069 template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
0070 {
0071 using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
0072 };
0073
0074 #else
0075
0076 template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
0077 {
0078 using type = mp_size_t<mp_plus<std::is_same<T, V>...>::value>;
0079 };
0080
0081 #endif
0082
0083 }
0084
0085 template<class L, class V> using mp_count = typename detail::mp_count_impl<L, V>::type;
0086
0087
0088 namespace detail
0089 {
0090
0091 template<class L, template<class...> class P> struct mp_count_if_impl;
0092
0093 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
0094
0095 template<template<class...> class P, class... T> constexpr std::size_t cx_count_if()
0096 {
0097 constexpr bool a[] = { false, static_cast<bool>( P<T>::value )... };
0098
0099 std::size_t r = 0;
0100
0101 for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
0102 {
0103 r += a[ i ];
0104 }
0105
0106 return r;
0107 }
0108
0109 template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
0110 {
0111 using type = mp_size_t<cx_count_if<P, T...>()>;
0112 };
0113
0114 #elif !defined( BOOST_MP11_NO_CONSTEXPR )
0115
0116 template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
0117 {
0118 using type = mp_size_t<cx_plus(mp_to_bool<P<T>>::value...)>;
0119 };
0120
0121 #else
0122
0123 template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
0124 {
0125 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
0126
0127 template<class T> struct _f { using type = mp_to_bool<P<T>>; };
0128 using type = mp_size_t<mp_plus<typename _f<T>::type...>::value>;
0129
0130 #else
0131
0132 using type = mp_size_t<mp_plus<mp_to_bool<P<T>>...>::value>;
0133
0134 #endif
0135 };
0136
0137 #endif
0138
0139 }
0140
0141 template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
0142 template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>;
0143
0144 }
0145 }
0146
0147 #endif