diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index e5e9eb9..b0f759f 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -312,6 +312,37 @@ template constexpr variant_alternative_t constexpr variant_alternative_t>& unsafe_get(variant& v) +{ + static_assert( I < sizeof...(T), "Index out of bounds" ); + return v._get_impl( mp11::mp_size_t() ); +} + +template constexpr variant_alternative_t>&& unsafe_get(variant&& v) +{ + static_assert( I < sizeof...(T), "Index out of bounds" ); + return std::move( v._get_impl( mp11::mp_size_t() ) ); +} + +template constexpr variant_alternative_t> const& unsafe_get(variant const& v) +{ + static_assert( I < sizeof...(T), "Index out of bounds" ); + return v._get_impl( mp11::mp_size_t() ); +} + +template constexpr variant_alternative_t> const&& unsafe_get(variant const&& v) +{ + static_assert( I < sizeof...(T), "Index out of bounds" ); + return std::move( v._get_impl( mp11::mp_size_t() ) ); +} + +} // namespace detail + // get (type) template constexpr U& get(variant& v) @@ -1589,32 +1620,32 @@ template using remove_cv_ref_t = typename std::remove_cv struct copy_cv_ref { - using type = T; + using type = T; }; template struct copy_cv_ref { - using type = T const; + using type = T const; }; template struct copy_cv_ref { - using type = T volatile; + using type = T volatile; }; template struct copy_cv_ref { - using type = T const volatile; + using type = T const volatile; }; template struct copy_cv_ref { - using type = typename copy_cv_ref::type&; + using type = typename copy_cv_ref::type&; }; template struct copy_cv_ref { - using type = typename copy_cv_ref::type&&; + using type = typename copy_cv_ref::type&&; }; template using copy_cv_ref_t = typename copy_cv_ref::type; @@ -1647,7 +1678,7 @@ template struct visit_L1 template auto operator()( I ) const -> Vret { - return std::forward(f)( get( std::forward(v1) ) ); + return std::forward(f)( unsafe_get( std::forward(v1) ) ); } }; @@ -1688,7 +1719,7 @@ template struct visit_L2 template auto operator()( I ) const -> Vret { - auto f2 = bind_front( std::forward(f), get( std::forward(v1) ) ); + auto f2 = bind_front( std::forward(f), unsafe_get( std::forward(v1) ) ); return visit( f2, std::forward(v2) ); } }; @@ -1713,7 +1744,7 @@ template struct visit_L3 template auto operator()( I ) const -> Vret { - auto f2 = bind_front( std::forward(f), get( std::forward(v1) ) ); + auto f2 = bind_front( std::forward(f), unsafe_get( std::forward(v1) ) ); return visit( f2, std::forward(v2), std::forward(v3) ); } }; @@ -1739,7 +1770,7 @@ template struct visit_L4 template auto operator()( I ) const -> Vret { - auto f2 = bind_front( std::forward(f), get( std::forward(v1) ) ); + auto f2 = bind_front( std::forward(f), unsafe_get( std::forward(v1) ) ); return visit( f2, std::forward(v2), std::forward(v3), std::forward(v4) ); } }; @@ -1757,7 +1788,7 @@ template constexpr auto visit( F&& f, V { return mp11::mp_with_index>( v1.index(), [&]( auto I ){ - auto f2 = [&]( auto&&... a ){ return std::forward(f)( get( std::forward(v1) ), std::forward(a)... ); }; + auto f2 = [&]( auto&&... a ){ return std::forward(f)( detail::unsafe_get( std::forward(v1) ), std::forward(a)... ); }; return visit( f2, std::forward(v2), std::forward(v)... ); });