Author: mpark Date: Thu May 11 02:17:12 2017 New Revision: 302773 URL: http://llvm.org/viewvc/llvm-project?rev=302773&view=rev Log: Fix `std::visit` for the zero variants case.
Summary: The following code is broken: ``` std::visit([]{}); ``` Reviewers: EricWF Reviewed By: EricWF Differential Revision: https://reviews.llvm.org/D33090 Modified: libcxx/trunk/include/variant libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp Modified: libcxx/trunk/include/variant URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/variant?rev=302773&r1=302772&r2=302773&view=diff ============================================================================== --- libcxx/trunk/include/variant (original) +++ libcxx/trunk/include/variant Thu May 11 02:17:12 2017 @@ -425,30 +425,21 @@ struct __base { constexpr auto __fmatrix = __make_fmatrix<_Visitor&&, decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); - const size_t __indices[] = {__vs.index()...}; - return __at(__fmatrix, __indices)(_VSTD::forward<_Visitor>(__visitor), - _VSTD::forward<_Vs>(__vs).__as_base()...); + return __at(__fmatrix, __vs.index()...)( + _VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs).__as_base()...); } private: template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY - static constexpr const _Tp& __at_impl(const _Tp& __elem, const size_t*) { - return __elem; - } - - template <class _Tp, size_t _Np> - inline _LIBCPP_INLINE_VISIBILITY - static constexpr auto&& __at_impl(const array<_Tp, _Np>& __elems, - const size_t* __index) { - return __at_impl(__elems[*__index], __index + 1); - } + static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; } - template <class _Tp, size_t _Np, size_t _Ip> + template <class _Tp, size_t _Np, typename... _Indices> inline _LIBCPP_INLINE_VISIBILITY static constexpr auto&& __at(const array<_Tp, _Np>& __elems, - const size_t (&__indices)[_Ip]) { - return __at_impl(__elems, begin(__indices)); + size_t __index, _Indices... __indices) { + return __at(__elems[__index], __indices...); } template <class _Fp, class... _Fs> Modified: libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp?rev=302773&r1=302772&r2=302773&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/variant/variant.visit/visit.pass.cpp Thu May 11 02:17:12 2017 @@ -94,6 +94,16 @@ void test_call_operator_forwarding() { using Fn = ForwardingCallObject; Fn obj{}; const Fn &cobj = obj; + { // test call operator forwarding - no variant + std::visit(obj); + assert(Fn::check_call<>(CT_NonConst | CT_LValue)); + std::visit(cobj); + assert(Fn::check_call<>(CT_Const | CT_LValue)); + std::visit(std::move(obj)); + assert(Fn::check_call<>(CT_NonConst | CT_RValue)); + std::visit(std::move(cobj)); + assert(Fn::check_call<>(CT_Const | CT_RValue)); + } { // test call operator forwarding - single variant, single arg using V = std::variant<int>; V v(42); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits