#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED #define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED // Copyright 2017 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include #if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) # define BOOST_MP11_CONSTEXPR14 constexpr #else # define BOOST_MP11_CONSTEXPR14 #endif #if defined( __GNUC__ ) || defined( __clang__ ) # define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable(); #elif defined( _MSC_VER ) # define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false); #else # define BOOST_MP11_UNREACHABLE_DEFAULT #endif namespace boost { namespace mp11 { namespace detail { template struct mp_with_index_impl_ { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { if( i < N / 2 ) { return mp_with_index_impl_::template call( i, std::forward(f) ); } else { return mp_with_index_impl_::template call( i - N/2, std::forward(f) ); } } }; template<> struct mp_with_index_impl_<0> { }; template<> struct mp_with_index_impl_<1> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t /*i*/, F && f ) { return std::forward(f)( mp_size_t() ); } }; template<> struct mp_with_index_impl_<2> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<3> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<4> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<5> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<6> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<7> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<8> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<9> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<10> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<11> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<12> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<13> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<14> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); case 13: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<15> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); case 13: return std::forward(f)( mp_size_t() ); case 14: return std::forward(f)( mp_size_t() ); } } }; template<> struct mp_with_index_impl_<16> { template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { BOOST_MP11_UNREACHABLE_DEFAULT case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); case 13: return std::forward(f)( mp_size_t() ); case 14: return std::forward(f)( mp_size_t() ); case 15: return std::forward(f)( mp_size_t() ); } } }; } // namespace detail template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) { assert( i < N ); return detail::mp_with_index_impl_::template call<0>( i, std::forward(f) ); } template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) { return mp_with_index( i, std::forward(f) ); } #undef BOOST_MP11_CONSTEXPR14 #undef BOOST_MP11_UNREACHABLE_DEFAULT } // namespace mp11 } // namespace boost #endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED