On 08/04/19 17:02 +0100, Jonathan Wakely wrote:
+ template<typename _Result_type, typename _Visitor, typename... _Variants,
+ size_t... __indices>
+ struct __gen_vtable_r_impl<
+ _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
+ tuple<_Variants...>, std::index_sequence<__indices...>>
+ {
+ using _Array_type =
+ _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
+
+ template<size_t __index, typename _Variant>
+ static constexpr decltype(auto)
+ __element_by_index_or_cookie(_Variant&& __var)
+ {
+ if constexpr (__index != variant_npos)
+ return __variant::__get<__index>(std::forward<_Variant>(__var));
+ else
+ return __variant_cookie{};
+ }
I don't think we need __element_by_index_or_cookie for the visit<R>
case, so the function above can go, and ...
+ static constexpr _Result_type
+ __visit_r_invoke(_Visitor&& __visitor, _Variants... __vars)
+ {
+ if constexpr (is_void_v<_Result_type>)
+ return (void) std::__invoke(std::forward<_Visitor>(__visitor),
+ __element_by_index_or_cookie<__indices>(
this just becomes __variant::__get<__indices>(
+ std::forward<_Variants>(__vars))...);
+ else
+ return std::__invoke(std::forward<_Visitor>(__visitor),
+ __element_by_index_or_cookie<__indices>(
and here too.
+ std::forward<_Variants>(__vars))...);
+ }
+
+ static constexpr _Array_type
+ _S_apply()
+ { return _Array_type{&__visit_r_invoke}; }
+ };
With the above simplification the visit<R> code is a lot simpler than
the existing __gen_vtable code, let alone the version that adds
visit<R> support to it.
I'll spend some more time thinking about it.
+ template<typename _Result_type, typename _Visitor, typename... _Variants>
+ struct __gen_vtable_r
+ {
+ using _Array_type =
+ _Multi_array<_Result_type (*)(_Visitor&&, _Variants...),
+ variant_size_v<remove_reference_t<_Variants>>...>;
+
+ static constexpr _Array_type _S_vtable
+ = __gen_vtable_r_impl<_Array_type, tuple<_Variants...>,
+ std::index_sequence<>>::_S_apply();
N.B. here I just declare a variable and its default initializer. I
don't see any benefit to how the original in __gen_vtable does it:
static constexpr _Array_type
_S_apply()
{
return __gen_vtable_impl<_Array_type, tuple<_Variants...>,
std::index_sequence<>>::_S_apply();
}
static constexpr auto _S_vtable = _S_apply();
We only ever use that function in the default initializer, so might as
well get rid of it.