Skip to content

Commit aec5cce

Browse files
committed
Address comments + Add some tests for function refs and array refs
1 parent b48fe30 commit aec5cce

File tree

7 files changed

+71
-24
lines changed

7 files changed

+71
-24
lines changed

libcxx/include/optional

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,6 @@ namespace std {
266266
_LIBCPP_PUSH_MACROS
267267
# include <__undef_macros>
268268

269-
# if _LIBCPP_STD_VER >= 26
270-
# define _LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_TP, _UP) \
271-
requires(is_lvalue_reference_v<_TP> && reference_constructs_from_temporary_v<_TP, _UP>)
272-
# endif
273-
274269
namespace std // purposefully not using versioning namespace
275270
{
276271

@@ -702,6 +697,12 @@ private:
702697
static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
703698
static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
704699

700+
# if _LIBCPP_STD_VER >= 26
701+
template <class _Up>
702+
constexpr static bool __libcpp_opt_ref_ctor_deleted =
703+
is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>;
704+
# endif
705+
705706
// LWG2756: conditionally explicit conversion from _Up
706707
struct _CheckOptionalArgsConstructor {
707708
template <class _Up>
@@ -818,33 +819,33 @@ public:
818819
template <class _Up,
819820
class... _Args,
820821
enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
821-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
822+
requires __libcpp_opt_ref_ctor_deleted<_Up>
822823
_LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) = delete;
823824

824825
template <class _Up = value_type,
825826
enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
826-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
827+
requires __libcpp_opt_ref_ctor_deleted<_Up>
827828
_LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) = delete;
828829

829830
template <class _Up = remove_cv_t<_Tp>,
830831
enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
831-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
832+
requires __libcpp_opt_ref_ctor_deleted<_Up>
832833
_LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) = delete;
833834

834835
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
835-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
836+
requires __libcpp_opt_ref_ctor_deleted<_Up>
836837
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) = delete;
837838

838839
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
839-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
840+
requires __libcpp_opt_ref_ctor_deleted<_Up>
840841
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) = delete;
841842

842843
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
843-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
844+
requires __libcpp_opt_ref_ctor_deleted<_Up>
844845
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) = delete;
845846

846847
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
847-
_LIBCPP_OPT_REF_DELETED_CONS_REQUIRES(_Tp, _Up)
848+
requires __libcpp_opt_ref_ctor_deleted<_Up>
848849
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) = delete;
849850
# endif
850851

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ void test_reference_extension() {
136136
assert(T::alive == 0);
137137
assert(T::destroyed == 1);
138138
{
139-
static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
140-
static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
139+
static_assert(!std::is_copy_constructible_v<std::optional<T&&>>);
140+
static_assert(!std::is_copy_constructible_v<std::optional<T const&&>>);
141141
}
142142
# endif
143143
#endif

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_constructs_from_temporary.verify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ int main(int, char**) {
3232
std::optional<const X&> o6{std::optional<int>(1)}; // optional(optional<U>&&)
3333
std::optional<const X&> o7{_co}; // optional(const optional<U>&)
3434
std::optional<const X&> o8{_o}; // optional(optional<U>&)
35-
}
35+
}

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ref_t.pass.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,44 @@ constexpr bool test() {
3232
return true;
3333
}
3434

35-
int main(int, char**) {
36-
static_assert((test<int&, 1>()));
37-
static_assert((test<double&, 1.0>()));
35+
template <typename T>
36+
constexpr T foo(T val) {
37+
return val;
38+
}
39+
40+
template <typename T, T _Val>
41+
constexpr bool fn_ref_test() {
42+
std::optional<T (&)(T)> opt{foo<T>};
43+
assert(opt.has_value());
44+
assert((*opt)(_Val) == _Val);
45+
46+
return true;
47+
}
48+
49+
template <typename T, T _Val>
50+
constexpr bool array_ref_test() {
51+
T arr[5]{};
52+
std::optional<T(&)[5]> opt{arr};
53+
54+
assert(opt.has_value());
55+
(*opt)[0] = _Val;
56+
assert((*opt)[0] == _Val);
57+
assert(arr[0] == _Val);
58+
59+
return true;
60+
}
61+
62+
constexpr bool tests() {
3863
assert((test<int&, 1>()));
3964
assert((test<double&, 1.0>()));
65+
assert((fn_ref_test<int, 1>()));
66+
assert((array_ref_test<int, 1>()));
67+
assert((fn_ref_test<double, 1.0>()));
68+
assert((array_ref_test<double, 1.0>()));
69+
return true;
70+
}
71+
72+
int main(int, char**) {
73+
static_assert(tests());
74+
tests();
4075
}

libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,21 @@ int main(int, char**)
6666
}
6767
#if TEST_STD_VER >= 26
6868
{
69-
typedef int& T;
70-
static_assert(std::is_trivially_destructible<T>::value, "");
71-
static_assert(std::is_trivially_destructible<optional<T>>::value, "");
69+
typedef X& T;
70+
static_assert(std::is_trivially_destructible<T>::value);
71+
static_assert(std::is_trivially_destructible<optional<T>>::value);
72+
}
73+
X::dtor_called = false;
74+
X x;
75+
{
76+
optional<X&> opt{x};
77+
assert(X::dtor_called == false);
78+
}
79+
assert(X::dtor_called == false);
80+
81+
{
82+
static_assert(std::is_trivially_destructible<X (&)()>::value);
83+
static_assert(std::is_trivially_destructible<optional<X (&)()>>::value);
7284
}
7385
#endif
7486
return 0;

libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ int main(int, char**)
3737
{
3838
static constexpr int i = 0;
3939
constexpr optional<const int&> opt{i};
40-
static_assert(opt.has_value(), "");
40+
static_assert(opt.has_value());
4141
}
4242
#endif
4343

libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.verify.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ int main(int, char**)
2929
{
3030
#if TEST_STD_VER >= 26
3131
// expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}}
32-
optional<int&&> opt2;
3332
#else
3433
// expected-error-re@optional:* 2 {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}}
34+
#endif
3535
optional<int&> opt1;
3636
optional<int&&> opt2;
37-
#endif
3837
}
3938
{
4039
// expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}}

0 commit comments

Comments
 (0)