-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc++] Make constexpr std::variant
. Implement P2231R1
#83335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) ChangesPatch is 128.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83335.diff 12 Files Affected:
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 6063739e52c86b..2a583f6dbd2006 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -42,26 +42,27 @@ namespace std {
in_place_index_t<I>, initializer_list<U>, Args&&...);
// 20.7.2.2, destructor
- ~variant();
+ constexpr ~variant(); // constexpr since c++20
// 20.7.2.3, assignment
constexpr variant& operator=(const variant&);
constexpr variant& operator=(variant&&) noexcept(see below);
- template <class T> variant& operator=(T&&) noexcept(see below);
+ template <class T>
+ constexpr variant& operator=(T&&) noexcept(see below); // constexpr since c++20
// 20.7.2.4, modifiers
template <class T, class... Args>
- T& emplace(Args&&...);
+ constexpr T& emplace(Args&&...); // constexpr since c++20
template <class T, class U, class... Args>
- T& emplace(initializer_list<U>, Args&&...);
+ constexpr T& emplace(initializer_list<U>, Args&&...); // constexpr since c++20
template <size_t I, class... Args>
- variant_alternative_t<I, variant>& emplace(Args&&...);
+ constexpr variant_alternative_t<I, variant>& emplace(Args&&...); // constexpr since c++20
template <size_t I, class U, class... Args>
- variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...);
+ constexpr variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...); // constexpr since c++20
// 20.7.2.5, value status
constexpr bool valueless_by_exception() const noexcept;
@@ -222,6 +223,7 @@ namespace std {
#include <__functional/operations.h>
#include <__functional/unary_function.h>
#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
#include <__type_traits/add_const.h>
#include <__type_traits/add_cv.h>
#include <__type_traits/add_pointer.h>
@@ -655,7 +657,8 @@ private:
template <size_t _Index, class _Tp>
struct _LIBCPP_TEMPLATE_VIS __alt {
- using __value_type = _Tp;
+ using __value_type = _Tp;
+ static constexpr size_t __index = _Index;
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args)
@@ -687,7 +690,7 @@ union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
__union(const __union&) = default; \
__union(__union&&) = default; \
\
- destructor \
+ _LIBCPP_HIDE_FROM_ABI destructor \
\
__union& \
operator=(const __union&) = default; \
@@ -701,9 +704,9 @@ union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
friend struct __access::__union; \
}
-_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
-_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union(){});
-_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
+_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = default;);
+_LIBCPP_VARIANT_UNION(_Trait::_Available, _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union(){});
+_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = delete;);
# undef _LIBCPP_VARIANT_UNION
@@ -757,23 +760,23 @@ class _LIBCPP_TEMPLATE_VIS __dtor;
using __base_type::__base_type; \
using __base_type::operator=; \
\
- __dtor(const __dtor&) = default; \
- __dtor(__dtor&&) = default; \
- destructor __dtor& operator=(const __dtor&) = default; \
- __dtor& operator=(__dtor&&) = default; \
+ __dtor(const __dtor&) = default; \
+ __dtor(__dtor&&) = default; \
+ _LIBCPP_HIDE_FROM_ABI destructor __dtor& operator=(const __dtor&) = default; \
+ __dtor& operator=(__dtor&&) = default; \
\
protected: \
inline _LIBCPP_HIDE_FROM_ABI destroy \
}
_LIBCPP_VARIANT_DESTRUCTOR(
- _Trait::_TriviallyAvailable, ~__dtor() = default;
- , void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
+ _Trait::_TriviallyAvailable, _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default;
+ , _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
_LIBCPP_VARIANT_DESTRUCTOR(
_Trait::_Available,
- ~__dtor() { __destroy(); },
- void __destroy() noexcept {
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() { __destroy(); },
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
if (!this->valueless_by_exception()) {
__visitation::__base::__visit_alt(
[](auto& __alt) noexcept {
@@ -785,7 +788,8 @@ _LIBCPP_VARIANT_DESTRUCTOR(
this->__index = __variant_npos<__index_t>;
});
-_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, ~__dtor() = delete;, void __destroy() noexcept = delete;);
+_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = delete;
+ , _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept = delete;);
# undef _LIBCPP_VARIANT_DESTRUCTOR
@@ -798,23 +802,22 @@ public:
using __base_type::operator=;
protected:
- template <size_t _Ip, class _Tp, class... _Args>
- _LIBCPP_HIDE_FROM_ABI static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
- ::new ((void*)std::addressof(__a)) __alt<_Ip, _Tp>(in_place, std::forward<_Args>(__args)...);
- return __a.__value;
- }
-
template <class _Rhs>
- _LIBCPP_HIDE_FROM_ABI static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
__lhs.__destroy();
if (!__rhs.valueless_by_exception()) {
+ // We cannot directly construct at the target __alt because its direct enclosing union is not activated yet.
+ // We will get error if we did:
+ // construction of subobject of member '__tail' of union with active member '__dummy' is not allowed in a constant
+ // expression
auto __rhs_index = __rhs.index();
__visitation::__base::__visit_alt_at(
__rhs_index,
- [](auto& __lhs_alt, auto&& __rhs_alt) {
- __construct_alt(__lhs_alt, std::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
+ [&__lhs](auto&& __rhs_alt) {
+ std::__construct_at(std::addressof(__lhs.__data),
+ in_place_index<__decay_t<decltype(__rhs_alt)>::__index>,
+ std::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
},
- __lhs,
std::forward<_Rhs>(__rhs));
__lhs.__index = __rhs_index;
}
@@ -834,21 +837,24 @@ class _LIBCPP_TEMPLATE_VIS __move_constructor;
using __base_type::__base_type; \
using __base_type::operator=; \
\
- __move_constructor(const __move_constructor&) = default; \
- move_constructor ~__move_constructor() = default; \
- __move_constructor& operator=(const __move_constructor&) = default; \
- __move_constructor& operator=(__move_constructor&&) = default; \
+ __move_constructor(const __move_constructor&) = default; \
+ _LIBCPP_HIDE_FROM_ABI move_constructor ~__move_constructor() = default; \
+ __move_constructor& operator=(const __move_constructor&) = default; \
+ __move_constructor& operator=(__move_constructor&&) = default; \
}
-_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_TriviallyAvailable,
- __move_constructor(__move_constructor&& __that) = default;);
+_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
+ _Trait::_TriviallyAvailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) = default;);
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
_Trait::_Available,
- __move_constructor(__move_constructor&& __that) noexcept(__all<is_nothrow_move_constructible_v<_Types>...>::value)
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept(
+ __all<is_nothrow_move_constructible_v<_Types>...>::value)
: __move_constructor(__valueless_t{}) { this->__generic_construct(*this, std::move(__that)); });
-_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_Unavailable, __move_constructor(__move_constructor&&) = delete;);
+_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_Unavailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&&) = delete;);
# undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
@@ -865,20 +871,22 @@ class _LIBCPP_TEMPLATE_VIS __copy_constructor;
using __base_type::__base_type; \
using __base_type::operator=; \
\
- copy_constructor __copy_constructor(__copy_constructor&&) = default; \
- ~__copy_constructor() = default; \
- __copy_constructor& operator=(const __copy_constructor&) = default; \
- __copy_constructor& operator=(__copy_constructor&&) = default; \
+ _LIBCPP_HIDE_FROM_ABI copy_constructor __copy_constructor(__copy_constructor&&) = default; \
+ ~__copy_constructor() = default; \
+ __copy_constructor& operator=(const __copy_constructor&) = default; \
+ __copy_constructor& operator=(__copy_constructor&&) = default; \
}
-_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_TriviallyAvailable,
- __copy_constructor(const __copy_constructor& __that) = default;);
+_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
+ _Trait::_TriviallyAvailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) = default;);
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
- _Trait::_Available, __copy_constructor(const __copy_constructor& __that)
+ _Trait::_Available, _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that)
: __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); });
-_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_Unavailable, __copy_constructor(const __copy_constructor&) = delete;);
+_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_Unavailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor&) = delete;);
# undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
@@ -891,22 +899,24 @@ public:
using __base_type::operator=;
template <size_t _Ip, class... _Args>
- _LIBCPP_HIDE_FROM_ABI auto& __emplace(_Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto& __emplace(_Args&&... __args) {
this->__destroy();
- auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Args>(__args)...);
+ std::__construct_at(std::addressof(this->__data), in_place_index<_Ip>, std::forward<_Args>(__args)...);
this->__index = _Ip;
- return __res;
+ return __access::__base::__get_alt<_Ip>(*this).__value;
}
protected:
template <size_t _Ip, class _Tp, class _Arg>
- _LIBCPP_HIDE_FROM_ABI void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
if (this->index() == _Ip) {
__a.__value = std::forward<_Arg>(__arg);
} else {
struct {
- _LIBCPP_HIDE_FROM_ABI void operator()(true_type) const { __this->__emplace<_Ip>(std::forward<_Arg>(__arg)); }
- _LIBCPP_HIDE_FROM_ABI void operator()(false_type) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const {
+ __this->__emplace<_Ip>(std::forward<_Arg>(__arg));
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const {
__this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg)));
}
__assignment* __this;
@@ -917,7 +927,7 @@ protected:
}
template <class _That>
- _LIBCPP_HIDE_FROM_ABI void __generic_assign(_That&& __that) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_assign(_That&& __that) {
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
// do nothing.
} else if (__that.valueless_by_exception()) {
@@ -951,22 +961,24 @@ class _LIBCPP_TEMPLATE_VIS __move_assignment;
__move_assignment(__move_assignment&&) = default; \
~__move_assignment() = default; \
__move_assignment& operator=(const __move_assignment&) = default; \
- move_assignment \
+ _LIBCPP_HIDE_FROM_ABI move_assignment \
}
-_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable,
- __move_assignment& operator=(__move_assignment&& __that) = default;);
+_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
+ _Trait::_TriviallyAvailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&& __that) = default;);
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
_Trait::_Available,
- __move_assignment&
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment&
operator=(__move_assignment&& __that) noexcept(
__all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) {
this->__generic_assign(std::move(__that));
return *this;
});
-_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_Unavailable, __move_assignment& operator=(__move_assignment&&) = delete;);
+_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
+ _Trait::_Unavailable, _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&&) = delete;);
# undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
@@ -983,22 +995,25 @@ class _LIBCPP_TEMPLATE_VIS __copy_assignment;
using __base_type::__base_type; \
using __base_type::operator=; \
\
- __copy_assignment(const __copy_assignment&) = default; \
- __copy_assignment(__copy_assignment&&) = default; \
- ~__copy_assignment() = default; \
- copy_assignment __copy_assignment& operator=(__copy_assignment&&) = default; \
+ __copy_assignment(const __copy_assignment&) = default; \
+ __copy_assignment(__copy_assignment&&) = default; \
+ ~__copy_assignment() = default; \
+ _LIBCPP_HIDE_FROM_ABI copy_assignment __copy_assignment& operator=(__copy_assignment&&) = default; \
}
-_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable,
- __copy_assignment& operator=(const __copy_assignment& __that) = default;);
+_LIBCPP_VARIANT_COPY_ASSIGNMENT(
+ _Trait::_TriviallyAvailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
_LIBCPP_VARIANT_COPY_ASSIGNMENT(
- _Trait::_Available, __copy_assignment& operator=(const __copy_assignment& __that) {
+ _Trait::_Available, _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(const __copy_assignment& __that) {
this->__generic_assign(__that);
return *this;
});
-_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, __copy_assignment& operator=(const __copy_assignment&) = delete;);
+_LIBCPP_VARIANT_COPY_ASSIGNMENT(
+ _Trait::_Unavailable,
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(const __copy_assignment&) = delete;);
# undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
@@ -1014,11 +1029,11 @@ public:
_LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default;
template <size_t _Ip, class _Arg>
- _LIBCPP_HIDE_FROM_ABI void __assign(_Arg&& __arg) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign(_Arg&& __arg) {
this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Arg>(__arg));
}
- inline _LIBCPP_HIDE_FROM_ABI void __swap(__impl& __that) {
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__impl& __that) {
if (this->valueless_by_exception() && __that.valueless_by_exception()) {
// do nothing.
} else if (this->index() == __that.index()) {
@@ -1063,7 +1078,7 @@ public:
}
private:
- inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const {
+ constexpr inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const {
constexpr bool __resul...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good, thanks a lot for the patch! I'll want to have another quick look at the patch once the comments are addressed, but I don't expect major issues.
libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I didn't do a deep review, I mainly glossed over the changes.
libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
Show resolved
Hide resolved
9b2828e
to
aaece59
Compare
libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
Show resolved
Hide resolved
31efb09
to
c4ca301
Compare
c4ca301
to
b54f8a1
Compare
You can test this locally with the following command:git-clang-format --diff 50b45b24220ead33cf5cedc49c13e0336297e4eb 0466fbd0bcbcf59f8d7860f4a593fb6c62a34b2d -- libcxx/include/variant libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp View the diff from clang-format here.diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
index f98d968f0e..f813b3f0a1 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
@@ -26,8 +26,8 @@
#include "variant_test_helpers.h"
template <class Var, std::size_t I, class... Args>
-constexpr auto test_emplace_exists_imp(int)
- -> decltype(std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
+constexpr auto
+test_emplace_exists_imp(int) -> decltype(std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
return true;
}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
index 4c635570bd..f14092d145 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_init_list_args.pass.cpp
@@ -36,8 +36,8 @@ struct InitListArg {
};
template <class Var, std::size_t I, class... Args>
-constexpr auto test_emplace_exists_imp(int)
- -> decltype(std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
+constexpr auto
+test_emplace_exists_imp(int) -> decltype(std::declval<Var>().template emplace<I>(std::declval<Args>()...), true) {
return true;
}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
index c2ed54d8a6..2c91debfa1 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
@@ -25,8 +25,8 @@
#include "variant_test_helpers.h"
template <class Var, class T, class... Args>
-constexpr auto test_emplace_exists_imp(int)
- -> decltype(std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
+constexpr auto
+test_emplace_exists_imp(int) -> decltype(std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
return true;
}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
index 644f2418b9..a442c7ed5d 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_init_list_args.pass.cpp
@@ -36,8 +36,8 @@ struct InitListArg {
};
template <class Var, class T, class... Args>
-constexpr auto test_emplace_exists_imp(int)
- -> decltype(std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
+constexpr auto
+test_emplace_exists_imp(int) -> decltype(std::declval<Var>().template emplace<T>(std::declval<Args>()...), true) {
return true;
}
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
index db05691c55..7269eae98e 100644
--- a/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -251,62 +251,63 @@ TEST_CONSTEXPR_CXX20 void test_swap_same_alternative() {
}
}
-void test_swap_same_alternative_throws(){
+void test_swap_same_alternative_throws() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- {using V = std::variant<NothrowTypeWithThrowingSwap, int>;
-int move_called = 0;
-int move_assign_called = 0;
-int swap_called = 0;
-V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
-V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
-try {
- v1.swap(v2);
- assert(false);
-} catch (int) {
-}
-assert(swap_called == 1);
-assert(move_called == 0);
-assert(move_assign_called == 0);
-assert(std::get<0>(v1).value == 42);
-assert(std::get<0>(v2).value == 100);
-}
+ {
+ using V = std::variant<NothrowTypeWithThrowingSwap, int>;
+ int move_called = 0;
+ int move_assign_called = 0;
+ int swap_called = 0;
+ V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
+ V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(swap_called == 1);
+ assert(move_called == 0);
+ assert(move_assign_called == 0);
+ assert(std::get<0>(v1).value == 42);
+ assert(std::get<0>(v2).value == 100);
+ }
-{
- using V = std::variant<ThrowingMoveCtor, int>;
- int move_called = 0;
- int move_assign_called = 0;
- int swap_called = 0;
- V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
- V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
- try {
- v1.swap(v2);
- assert(false);
- } catch (int) {
+ {
+ using V = std::variant<ThrowingMoveCtor, int>;
+ int move_called = 0;
+ int move_assign_called = 0;
+ int swap_called = 0;
+ V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
+ V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(move_called == 1); // call threw
+ assert(move_assign_called == 0);
+ assert(swap_called == 0);
+ assert(std::get<0>(v1).value == 42); // throw happened before v1 was moved from
+ assert(std::get<0>(v2).value == 100);
}
- assert(move_called == 1); // call threw
- assert(move_assign_called == 0);
- assert(swap_called == 0);
- assert(std::get<0>(v1).value == 42); // throw happened before v1 was moved from
- assert(std::get<0>(v2).value == 100);
-}
-{
- using V = std::variant<ThrowingMoveAssignNothrowMoveCtor, int>;
- int move_called = 0;
- int move_assign_called = 0;
- int swap_called = 0;
- V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
- V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
- try {
- v1.swap(v2);
- assert(false);
- } catch (int) {
+ {
+ using V = std::variant<ThrowingMoveAssignNothrowMoveCtor, int>;
+ int move_called = 0;
+ int move_assign_called = 0;
+ int swap_called = 0;
+ V v1(std::in_place_index<0>, 42, &move_called, &move_assign_called, &swap_called);
+ V v2(std::in_place_index<0>, 100, &move_called, &move_assign_called, &swap_called);
+ try {
+ v1.swap(v2);
+ assert(false);
+ } catch (int) {
+ }
+ assert(move_called == 1);
+ assert(move_assign_called == 1); // call threw and didn't complete
+ assert(swap_called == 0);
+ assert(std::get<0>(v1).value == -1); // v1 was moved from
+ assert(std::get<0>(v2).value == 100);
}
- assert(move_called == 1);
- assert(move_assign_called == 1); // call threw and didn't complete
- assert(swap_called == 0);
- assert(std::get<0>(v1).value == -1); // v1 was moved from
- assert(std::get<0>(v2).value == 100);
-}
#endif
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM but please rebase on main
, I made some changes to variant
which conflict with this PR!
constexpr test for default ctor fix c++17
cf69382
to
4933bd8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM w/ a small comment, thanks!
FTM bumping was missing. I'll do the cleanup. |
In C++20 mode, `__cpp_lib_optional` and `__cpp_lib_variant` should be `202106L` due to DR P2231R1. In C++26 mode, `__cpp_lib_variant` should be bumped to `202306L` due to P2637R3. - Clang 16/17 shouldn't get this bumping (as member `visit` requires explicit object parameters), but it's very tricky to make the bumping conditionally enabled. I _hope_ unconditionally bumping in C++26 will be OK for LLVM 20 when the support for Clang 17 is dropped. Related PRs: - https://reviews.llvm.org/D102119 - #83335 - #76447
In C++20 mode, `__cpp_lib_optional` and `__cpp_lib_variant` should be `202106L` due to DR P2231R1. In C++26 mode, `__cpp_lib_variant` should be bumped to `202306L` due to P2637R3. - Clang 16/17 shouldn't get this bumping (as member `visit` requires explicit object parameters), but it's very tricky to make the bumping conditionally enabled. I _hope_ unconditionally bumping in C++26 will be OK for LLVM 20 when the support for Clang 17 is dropped. Related PRs: - https://reviews.llvm.org/D102119 - llvm#83335 - llvm#76447
In C++20 mode, `__cpp_lib_optional` and `__cpp_lib_variant` should be `202106L` due to DR P2231R1. In C++26 mode, `__cpp_lib_variant` should be bumped to `202306L` due to P2637R3. - Clang 16/17 shouldn't get this bumping (as member `visit` requires explicit object parameters), but it's very tricky to make the bumping conditionally enabled. I _hope_ unconditionally bumping in C++26 will be OK for LLVM 20 when the support for Clang 17 is dropped. Related PRs: - https://reviews.llvm.org/D102119 - llvm#83335 - llvm#76447
Fixes #86686