mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2025-01-03 14:55:40 +00:00
397 lines
16 KiB
C++
397 lines
16 KiB
C++
#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 <boost/mp11/integral.hpp>
|
|
#include <boost/mp11/detail/config.hpp>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <cassert>
|
|
|
|
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
|
# define BOOST_MP11_CONSTEXPR14 constexpr
|
|
#else
|
|
# define BOOST_MP11_CONSTEXPR14
|
|
#endif
|
|
|
|
#if defined( _MSC_VER ) && !defined( __clang__ )
|
|
# define BOOST_MP11_UNREACHABLE() __assume(false)
|
|
#else
|
|
# define BOOST_MP11_UNREACHABLE() __builtin_unreachable()
|
|
#endif
|
|
|
|
namespace boost
|
|
{
|
|
namespace mp11
|
|
{
|
|
|
|
namespace detail
|
|
{
|
|
|
|
template<std::size_t N> struct mp_with_index_impl_
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
|
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
|
}
|
|
|
|
return mp_with_index_impl_<N-16>::template call<K+16>( i-16, std::forward<F>(f) );
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<0>
|
|
{
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<1>
|
|
{
|
|
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 )
|
|
{
|
|
return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<2>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<3>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<4>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<5>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<6>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<7>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<8>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<9>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<10>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<11>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<12>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<13>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<14>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<15>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
template<> struct mp_with_index_impl_<16>
|
|
{
|
|
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 )
|
|
{
|
|
switch( i )
|
|
{
|
|
default: BOOST_MP11_UNREACHABLE();
|
|
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
|
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
|
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
|
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
|
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
|
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
|
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
|
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
|
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
|
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
|
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
|
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
|
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
|
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
|
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
|
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
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 )
|
|
{
|
|
assert( i < N );
|
|
return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
|
|
}
|
|
|
|
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 )
|
|
{
|
|
return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
|
|
}
|
|
|
|
#undef BOOST_MP11_CONSTEXPR14
|
|
#undef BOOST_MP11_UNREACHABLE
|
|
|
|
} // namespace mp11
|
|
} // namespace boost
|
|
|
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|