Commit 469218a3 by Jonathan Wakely Committed by Jonathan Wakely

Avoid redundant runtime checks in std::visit

Calling std::get will check some static assertions and also do a runtime
check for a valid index before calling __detail::__variant::__get. The
std::visit function already handles the case where any variant has an
invalid index, so __get can be used directly in __visit_invoke.

	* include/std/variant (__gen_vtable_impl::__visit_invoke): Call __get
	directly instead of get, as caller ensures correct index is used.
	(holds_alternative, get, get_if): Remove redundant inline specifiers.
	(_VARIANT_RELATION_FUNCTION_TEMPLATE): Likewise.

From-SVN: r264786
parent f512bf3e
2018-10-02 Jonathan Wakely <jwakely@redhat.com>
* include/std/variant (__gen_vtable_impl::__visit_invoke): Call __get
directly instead of get, as caller ensures correct index is used.
(holds_alternative, get, get_if): Remove redundant inline specifiers.
(_VARIANT_RELATION_FUNCTION_TEMPLATE): Likewise.
2018-10-02 Joseph Myers <joseph@codesourcery.com>
* testsuite/lib/libstdc++.exp (libstdc++_init): Use
......
......@@ -811,9 +811,8 @@ namespace __variant
{
using _Alternative = variant_alternative_t<__index, _Next>;
__element = __gen_vtable_impl<
remove_reference_t<
decltype(__element)>, tuple<_Variants...>,
std::index_sequence<__indices..., __index>>::_S_apply();
remove_reference_t<decltype(__element)>, tuple<_Variants...>,
std::index_sequence<__indices..., __index>>::_S_apply();
}
};
......@@ -826,11 +825,11 @@ namespace __variant
using _Array_type =
_Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>;
decltype(auto)
static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
static constexpr decltype(auto)
__visit_invoke(_Visitor&& __visitor, _Variants... __vars)
{
return std::__invoke(std::forward<_Visitor>(__visitor),
std::get<__indices>(std::forward<_Variants>(__vars))...);
__variant::__get<__indices>(std::forward<_Variants>(__vars))...);
}
static constexpr auto
......@@ -871,8 +870,8 @@ namespace __variant
} // namespace __detail
template<typename _Tp, typename... _Types>
inline constexpr bool holds_alternative(const variant<_Types...>& __v)
noexcept
constexpr bool
holds_alternative(const variant<_Types...>& __v) noexcept
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
"T should occur for exactly once in alternatives");
......@@ -880,7 +879,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline _Tp& get(variant<_Types...>& __v)
constexpr _Tp& get(variant<_Types...>& __v)
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
"T should occur for exactly once in alternatives");
......@@ -889,7 +888,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline _Tp&& get(variant<_Types...>&& __v)
constexpr _Tp&& get(variant<_Types...>&& __v)
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
"T should occur for exactly once in alternatives");
......@@ -899,7 +898,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline const _Tp& get(const variant<_Types...>& __v)
constexpr const _Tp& get(const variant<_Types...>& __v)
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
"T should occur for exactly once in alternatives");
......@@ -908,7 +907,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline const _Tp&& get(const variant<_Types...>&& __v)
constexpr const _Tp&& get(const variant<_Types...>&& __v)
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
"T should occur for exactly once in alternatives");
......@@ -918,8 +917,7 @@ namespace __variant
}
template<size_t _Np, typename... _Types>
constexpr inline
add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
get_if(variant<_Types...>* __ptr) noexcept
{
using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
......@@ -932,7 +930,7 @@ namespace __variant
}
template<size_t _Np, typename... _Types>
constexpr inline
constexpr
add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
get_if(const variant<_Types...>* __ptr) noexcept
{
......@@ -946,7 +944,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline add_pointer_t<_Tp>
constexpr add_pointer_t<_Tp>
get_if(variant<_Types...>* __ptr) noexcept
{
static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
......@@ -957,7 +955,7 @@ namespace __variant
}
template<typename _Tp, typename... _Types>
constexpr inline add_pointer_t<const _Tp>
constexpr add_pointer_t<const _Tp>
get_if(const variant<_Types...>* __ptr)
noexcept
{
......@@ -1277,7 +1275,7 @@ namespace __variant
{ &__detail::__variant::__erased_##__NAME< \
const variant&, __indices>... }; \
template<size_t... __indices> \
constexpr inline bool \
constexpr bool \
_M_##__NAME(const variant& __rhs, \
std::index_sequence<__indices...>) const \
{ \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment