Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:51

0001 #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
0002 #define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
0003 
0004 //  Copyright 2017 Peter Dimov.
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0.
0007 //
0008 //  See accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt
0010 
0011 #include <boost/mp11/integral.hpp>
0012 #include <boost/mp11/detail/config.hpp>
0013 #include <type_traits>
0014 #include <utility>
0015 #include <cassert>
0016 
0017 #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
0018 # define BOOST_MP11_CONSTEXPR14 constexpr
0019 #else
0020 # define BOOST_MP11_CONSTEXPR14
0021 #endif
0022 
0023 #if defined( __GNUC__ ) || defined( __clang__ )
0024 # define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable();
0025 #elif defined( _MSC_VER )
0026 # define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false);
0027 #else
0028 # define BOOST_MP11_UNREACHABLE_DEFAULT
0029 #endif
0030 
0031 namespace boost
0032 {
0033 namespace mp11
0034 {
0035 
0036 namespace detail
0037 {
0038 
0039 template<std::size_t N> struct mp_with_index_impl_
0040 {
0041     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0042     {
0043         if( i < N / 2 )
0044         {
0045             return mp_with_index_impl_<N/2>::template call<K>( i, std::forward<F>(f) );
0046         }
0047         else
0048         {
0049             return mp_with_index_impl_<N-N/2>::template call<K+N/2>( i - N/2, std::forward<F>(f) );
0050         }
0051     }
0052 };
0053 
0054 template<> struct mp_with_index_impl_<0>
0055 {
0056 };
0057 
0058 template<> struct mp_with_index_impl_<1>
0059 {
0060     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t /*i*/, F && f )
0061     {
0062         return std::forward<F>(f)( mp_size_t<K+0>() );
0063     }
0064 };
0065 
0066 template<> struct mp_with_index_impl_<2>
0067 {
0068     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0069     {
0070         switch( i )
0071         {
0072         BOOST_MP11_UNREACHABLE_DEFAULT
0073         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0074         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0075         }
0076     }
0077 };
0078 
0079 template<> struct mp_with_index_impl_<3>
0080 {
0081     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0082     {
0083         switch( i )
0084         {
0085         BOOST_MP11_UNREACHABLE_DEFAULT
0086         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0087         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0088         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0089         }
0090     }
0091 };
0092 
0093 template<> struct mp_with_index_impl_<4>
0094 {
0095     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0096     {
0097         switch( i )
0098         {
0099         BOOST_MP11_UNREACHABLE_DEFAULT
0100         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0101         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0102         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0103         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0104         }
0105     }
0106 };
0107 
0108 template<> struct mp_with_index_impl_<5>
0109 {
0110     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0111     {
0112         switch( i )
0113         {
0114         BOOST_MP11_UNREACHABLE_DEFAULT
0115         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0116         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0117         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0118         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0119         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0120         }
0121     }
0122 };
0123 
0124 template<> struct mp_with_index_impl_<6>
0125 {
0126     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0127     {
0128         switch( i )
0129         {
0130         BOOST_MP11_UNREACHABLE_DEFAULT
0131         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0132         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0133         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0134         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0135         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0136         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0137         }
0138     }
0139 };
0140 
0141 template<> struct mp_with_index_impl_<7>
0142 {
0143     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0144     {
0145         switch( i )
0146         {
0147         BOOST_MP11_UNREACHABLE_DEFAULT
0148         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0149         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0150         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0151         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0152         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0153         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0154         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0155         }
0156     }
0157 };
0158 
0159 template<> struct mp_with_index_impl_<8>
0160 {
0161     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0162     {
0163         switch( i )
0164         {
0165         BOOST_MP11_UNREACHABLE_DEFAULT
0166         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0167         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0168         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0169         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0170         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0171         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0172         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0173         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0174         }
0175     }
0176 };
0177 
0178 template<> struct mp_with_index_impl_<9>
0179 {
0180     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0181     {
0182         switch( i )
0183         {
0184         BOOST_MP11_UNREACHABLE_DEFAULT
0185         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0186         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0187         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0188         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0189         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0190         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0191         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0192         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0193         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0194         }
0195     }
0196 };
0197 
0198 template<> struct mp_with_index_impl_<10>
0199 {
0200     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0201     {
0202         switch( i )
0203         {
0204         BOOST_MP11_UNREACHABLE_DEFAULT
0205         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0206         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0207         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0208         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0209         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0210         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0211         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0212         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0213         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0214         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0215         }
0216     }
0217 };
0218 
0219 template<> struct mp_with_index_impl_<11>
0220 {
0221     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0222     {
0223         switch( i )
0224         {
0225         BOOST_MP11_UNREACHABLE_DEFAULT
0226         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0227         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0228         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0229         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0230         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0231         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0232         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0233         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0234         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0235         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0236         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0237         }
0238     }
0239 };
0240 
0241 template<> struct mp_with_index_impl_<12>
0242 {
0243     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0244     {
0245         switch( i )
0246         {
0247         BOOST_MP11_UNREACHABLE_DEFAULT
0248         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0249         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0250         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0251         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0252         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0253         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0254         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0255         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0256         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0257         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0258         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0259         case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
0260         }
0261     }
0262 };
0263 
0264 template<> struct mp_with_index_impl_<13>
0265 {
0266     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0267     {
0268         switch( i )
0269         {
0270         BOOST_MP11_UNREACHABLE_DEFAULT
0271         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0272         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0273         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0274         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0275         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0276         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0277         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0278         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0279         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0280         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0281         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0282         case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
0283         case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
0284         }
0285     }
0286 };
0287 
0288 template<> struct mp_with_index_impl_<14>
0289 {
0290     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0291     {
0292         switch( i )
0293         {
0294         BOOST_MP11_UNREACHABLE_DEFAULT
0295         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0296         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0297         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0298         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0299         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0300         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0301         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0302         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0303         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0304         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0305         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0306         case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
0307         case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
0308         case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
0309         }
0310     }
0311 };
0312 
0313 template<> struct mp_with_index_impl_<15>
0314 {
0315     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0316     {
0317         switch( i )
0318         {
0319         BOOST_MP11_UNREACHABLE_DEFAULT
0320         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0321         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0322         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0323         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0324         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0325         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0326         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0327         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0328         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0329         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0330         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0331         case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
0332         case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
0333         case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
0334         case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
0335         }
0336     }
0337 };
0338 
0339 template<> struct mp_with_index_impl_<16>
0340 {
0341     template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
0342     {
0343         switch( i )
0344         {
0345         BOOST_MP11_UNREACHABLE_DEFAULT
0346         case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
0347         case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
0348         case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
0349         case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
0350         case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
0351         case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
0352         case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
0353         case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
0354         case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
0355         case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
0356         case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
0357         case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
0358         case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
0359         case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
0360         case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
0361         case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
0362         }
0363     }
0364 };
0365 
0366 } // namespace detail
0367 
0368 template<std::size_t N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
0369 {
0370     assert( i < N );
0371     return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
0372 }
0373 
0374 template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
0375 {
0376     return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
0377 }
0378 
0379 #undef BOOST_MP11_CONSTEXPR14
0380 #undef BOOST_MP11_UNREACHABLE_DEFAULT
0381 
0382 } // namespace mp11
0383 } // namespace boost
0384 
0385 #endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED