diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 9a1de15..6315832 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -26,6 +26,7 @@ #include #include #include +#include // @@ -845,6 +846,10 @@ template using resolve_overload_type = typename decltype( o template using resolve_overload_index = mp11::mp_find, resolve_overload_type>; +// index_type + +template using get_index_type = unsigned; + // variant_base template struct variant_base_impl; @@ -855,8 +860,10 @@ struct none {}; // trivially destructible, single buffered template struct variant_base_impl { + using index_type = get_index_type; + variant_storage st_; - unsigned ix_; + index_type ix_; constexpr variant_base_impl(): st_( mp11::mp_size_t<0>() ), ix_( 0 ) { @@ -870,6 +877,8 @@ template struct variant_base_impl template void _replace( I, A&&... a ) { ::new( &st_ ) variant_storage( mp11::mp_size_t(), std::forward(a)... ); + + static_assert( I::value + 1 <= (std::numeric_limits::max)(), "" ); ix_ = I::value + 1; } @@ -901,6 +910,8 @@ template struct variant_base_impl static_assert( std::is_nothrow_constructible::value, "Logic error: U must be nothrow constructible from A&&..." ); st_.emplace( mp11::mp_size_t(), std::forward(a)... ); + + static_assert( J <= (std::numeric_limits::max)(), "" ); ix_ = J; } @@ -911,6 +922,8 @@ template struct variant_base_impl U tmp( std::forward(a)... ); st_.emplace( mp11::mp_size_t(), std::move(tmp) ); + + static_assert( J <= (std::numeric_limits::max)(), "" ); ix_ = J; } @@ -931,8 +944,10 @@ template struct variant_base_impl // trivially destructible, double buffered template struct variant_base_impl { + using index_type = get_index_type; + variant_storage st_[ 2 ]; - unsigned ix_; + index_type ix_; constexpr variant_base_impl(): st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }, ix_( 0 ) { @@ -946,6 +961,8 @@ template struct variant_base_impl template void _replace( I, A&&... a ) { ::new( &st_[ 0 ] ) variant_storage( mp11::mp_size_t(), std::forward(a)... ); + + static_assert( ( I::value + 1 ) * 2 <= (std::numeric_limits::max)(), "" ); ix_ = ( I::value + 1 ) * 2; } @@ -982,6 +999,7 @@ template struct variant_base_impl st_[ i2 ].emplace( mp11::mp_size_t(), std::forward(a)... ); + static_assert( J * 2 + 1 <= (std::numeric_limits::max)(), "" ); ix_ = J * 2 + i2; } @@ -994,8 +1012,10 @@ template struct variant_base_impl // not trivially destructible, single buffered template struct variant_base_impl { + using index_type = get_index_type; + variant_storage st_; - unsigned ix_; + index_type ix_; constexpr variant_base_impl(): st_( mp11::mp_size_t<0>() ), ix_( 0 ) { @@ -1009,6 +1029,8 @@ template struct variant_base_impl template void _replace( I, A&&... a ) { ::new( &st_ ) variant_storage( mp11::mp_size_t(), std::forward(a)... ); + + static_assert( I::value + 1 <= (std::numeric_limits::max)(), "" ); ix_ = I::value + 1; } @@ -1077,6 +1099,8 @@ template struct variant_base_impl _destroy(); st_.emplace( mp11::mp_size_t(), std::move(tmp) ); + + static_assert( J <= (std::numeric_limits::max)(), "" ); ix_ = J; } @@ -1089,12 +1113,14 @@ template struct variant_base_impl // not trivially destructible, double buffered template struct variant_base_impl { + using index_type = get_index_type; + #if defined(__GNUC__) && __GNUC__ < 11 && !defined(__clang__) && !defined(__INTEL_COMPILER) // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63707 :-( variant_storage st1_, st2_; - unsigned ix_; + index_type ix_; constexpr variant_base_impl(): st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() ), ix_( 0 ) { @@ -1117,7 +1143,7 @@ template struct variant_base_impl #else variant_storage st_[ 2 ]; - unsigned ix_; + index_type ix_; constexpr variant_base_impl(): st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }, ix_( 0 ) { @@ -1143,6 +1169,8 @@ template struct variant_base_impl template void _replace( I, A&&... a ) { ::new( &storage( 0 ) ) variant_storage( mp11::mp_size_t(), std::forward(a)... ); + + static_assert( ( I::value + 1 ) * 2 <= (std::numeric_limits::max)(), "" ); ix_ = ( I::value + 1 ) * 2; } @@ -1207,6 +1235,7 @@ template struct variant_base_impl storage( i2 ).emplace( mp11::mp_size_t(), std::forward(a)... ); _destroy(); + static_assert( J * 2 + 1 <= (std::numeric_limits::max)(), "" ); ix_ = J * 2 + i2; }