// 23.6.3.1, constructors
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
- optional(const optional &);
- optional(optional &&) noexcept(see below);
+ constexpr optional(const optional &);
+ constexpr optional(optional &&) noexcept(see below);
template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
// 23.6.3.3, assignment
optional &operator=(nullopt_t) noexcept; // constexpr in C++20
- optional &operator=(const optional &); // constexpr in C++20
- optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
+ constexpr optional &operator=(const optional &);
+ constexpr optional &operator=(optional &&) noexcept(see below);
template <class U = T> optional &operator=(U &&); // constexpr in C++20
template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
template <class U> optional &operator=(optional<U> &&); // constexpr in C++20
return *this;
}
- _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
- _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
+ constexpr optional& operator=(const optional&) = default;
+ constexpr optional& operator=(optional&&) = default;
// LWG2756
template <class _Up = value_type,
// 20.7.2.1, constructors
constexpr variant() noexcept(see below);
- variant(const variant&); // constexpr in C++20
- variant(variant&&) noexcept(see below); // constexpr in C++20
+ constexpr variant(const variant&);
+ constexpr variant(variant&&) noexcept(see below);
template <class T> constexpr variant(T&&) noexcept(see below);
~variant();
// 20.7.2.3, assignment
- variant& operator=(const variant&); // constexpr in C++20
- variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
+ constexpr variant& operator=(const variant&);
+ constexpr variant& operator=(variant&&) noexcept(see below);
template <class T> variant& operator=(T&&) noexcept(see below);
constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
: __impl_(in_place_index<0>) {}
- variant(const variant&) = default;
- variant(variant&&) = default;
+ constexpr variant(const variant&) = default;
+ constexpr variant(variant&&) = default;
template <
class _Arg,
~variant() = default;
- variant& operator=(const variant&) = default;
- variant& operator=(variant&&) = default;
+ constexpr variant& operator=(const variant&) = default;
+ constexpr variant& operator=(variant&&) = default;
template <
class _Arg,
// UNSUPPORTED: c++03, c++11, c++14
// <optional>
-// optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20
+// constexpr optional<T>& operator=(const optional<T>& rhs);
#include <optional>
#include <type_traits>
{
{
using O = optional<int>;
-#if TEST_STD_VER > 17
- LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
- LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
-#endif
+ static_assert(assign_empty(O{42}));
+ static_assert(assign_value(O{42}));
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
{
using O = optional<TrivialTestTypes::TestType>;
-#if TEST_STD_VER > 17
- LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
- LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
-#endif
+ static_assert(assign_empty(O{42}));
+ static_assert(assign_value(O{42}));
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
// UNSUPPORTED: c++03, c++11, c++14
// <optional>
-// optional<T>& operator=(optional<T>&& rhs)
+// constexpr optional<T>& operator=(optional<T>&& rhs)
// noexcept(is_nothrow_move_assignable<T>::value &&
-// is_nothrow_move_constructible<T>::value); // constexpr in C++20
+// is_nothrow_move_constructible<T>::value);
#include <optional>
#include <cassert>
}
{
using O = optional<int>;
-#if TEST_STD_VER > 17
- LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
- LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
-#endif
+ static_assert(assign_empty(O{42}));
+ static_assert(assign_value(O{42}));
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
{
using O = optional<TrivialTestTypes::TestType>;
-#if TEST_STD_VER > 17
- LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
- LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
-#endif
+ static_assert(assign_empty(O{42}));
+ static_assert(assign_value(O{42}));
assert(assign_empty(O{42}));
assert(assign_value(O{42}));
}
+++ /dev/null
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: c++17
-// <optional>
-
-// constexpr optional(const optional<T>&& rhs);
-// C++17 said:
-// If is_trivially_move_constructible_v<T> is true,
-// this constructor shall be a constexpr constructor.
-//
-// P0602 changed this to:
-// If is_trivially_move_constructible_v<T> is true, this constructor is trivial.
-//
-// which means that it can't be constexpr if T is not trivially move-constructible,
-// because you have to do a placement new to get the value into place.
-// Except in the case where it is moving from an empty optional - that could be
-// made to be constexpr (and libstdc++ does so).
-
-#include <optional>
-#include <type_traits>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct S {
- constexpr S() : v_(0) {}
- S(int v) : v_(v) {}
- constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable
- constexpr S( S &&rhs) : v_(rhs.v_) {} // not trivially moveable
- int v_;
- };
-
-
-constexpr bool test() // expected-error {{constexpr function never produces a constant expression}}
-{
- std::optional<S> o1{3};
- std::optional<S> o2 = std::move(o1);
- return o2.has_value(); // return -something-
-}
-
-
-int main(int, char**)
-{
- static_assert (!std::is_trivially_move_constructible_v<S>, "" );
- static_assert (test(), ""); // expected-error-re {{{{(static_assert|static assertion)}} expression is not an integral constant expression}}
- return 0;
-}
// template <class ...Types> class variant;
-// variant& operator=(variant const&); // constexpr in C++20
+// constexpr variant& operator=(variant const&);
#include <cassert>
#include <string>
}
// Make sure we properly propagate triviality (see P0602R4).
-#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_copy_assignable<V>::value, "");
using V = std::variant<int, CopyOnly>;
static_assert(std::is_trivially_copy_assignable<V>::value, "");
}
-#endif // > C++17
}
void test_copy_assignment_empty_empty() {
#endif // TEST_HAS_NO_EXCEPTIONS
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
-#endif // > C++17
}
void test_copy_assignment_different_index() {
#endif // TEST_HAS_NO_EXCEPTIONS
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
struct {
constexpr Result<long> operator()() const {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
-#endif // > C++17
}
template <size_t NewIdx, class ValueType>
void test_constexpr_copy_assignment() {
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
using V = std::variant<long, void*, int>;
static_assert(std::is_trivially_copyable<V>::value, "");
static_assert(std::is_trivially_copy_assignable<V>::value, "");
static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), "");
static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), "");
static_assert(test_constexpr_assign_imp<2>(V(42l), 101), "");
-#endif // > C++17
}
int main(int, char**) {
// template <class ...Types> class variant;
-// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
+// constexpr variant& operator=(variant&&) noexcept(see below);
#include <cassert>
#include <string>
}
// Make sure we properly propagate triviality (see P0602R4).
-#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_move_assignable<V>::value, "");
using V = std::variant<int, CopyOnly>;
static_assert(std::is_trivially_move_assignable<V>::value, "");
}
-#endif // > C++17
}
void test_move_assignment_empty_empty() {
#endif // TEST_HAS_NO_EXCEPTIONS
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
-#endif // > C++17
}
void test_move_assignment_different_index() {
#endif // TEST_HAS_NO_EXCEPTIONS
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
struct {
constexpr Result<long> operator()() const {
static_assert(result.index == 1, "");
static_assert(result.value == 42, "");
}
-#endif // > C++17
}
template <size_t NewIdx, class ValueType>
void test_constexpr_move_assignment() {
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
using V = std::variant<long, void*, int>;
static_assert(std::is_trivially_copyable<V>::value, "");
static_assert(std::is_trivially_move_assignable<V>::value, "");
static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), "");
static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), "");
static_assert(test_constexpr_assign_imp<2>(V(42l), 101), "");
-#endif // > C++17
}
int main(int, char**) {
// template <class ...Types> class variant;
-// variant(variant const&); // constexpr in C++20
+// constexpr variant(variant const&);
#include <cassert>
#include <type_traits>
}
// Make sure we properly propagate triviality (see P0602R4).
-#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_copy_constructible<V>::value, "");
using V = std::variant<int, TCopyNTMove>;
static_assert(std::is_trivially_copy_constructible<V>::value, "");
}
-#endif // > C++17
}
void test_copy_ctor_basic() {
}
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
constexpr std::variant<int> v(std::in_place_index<0>, 42);
static_assert(v.index() == 0, "");
static_assert(v2.index() == 1, "");
static_assert(std::get<1>(v2).value == 42, "");
}
-#endif // > C++17
}
void test_copy_ctor_valueless_by_exception() {
void test_constexpr_copy_ctor() {
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
static_assert(test_constexpr_copy_ctor_imp<0>(V(42l)), "");
static_assert(test_constexpr_copy_ctor_imp<1>(V(nullptr)), "");
static_assert(test_constexpr_copy_ctor_imp<2>(V(101)), "");
-#endif // > C++17
}
int main(int, char**) {
// template <class ...Types> class variant;
-// variant(variant&&) noexcept(see below); // constexpr in C++20
+// constexpr variant(variant&&) noexcept(see below);
#include <cassert>
#include <string>
}
// Make sure we properly propagate triviality (see P0602R4).
-#if TEST_STD_VER > 17
{
using V = std::variant<int, long>;
static_assert(std::is_trivially_move_constructible<V>::value, "");
using V = std::variant<int, TMoveNTCopy>;
static_assert(std::is_trivially_move_constructible<V>::value, "");
}
-#endif // > C++17
}
template <typename T>
}
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
{
struct {
constexpr Result<int> operator()() const {
static_assert(result.index == 1, "");
static_assert(result.value.value == 42, "");
}
-#endif // > C++17
}
void test_move_ctor_valueless_by_exception() {
void test_constexpr_move_ctor() {
// Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4).
-#if TEST_STD_VER > 17
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
static_assert(test_constexpr_ctor_imp<0>(V(42l)), "");
static_assert(test_constexpr_ctor_imp<1>(V(nullptr)), "");
static_assert(test_constexpr_ctor_imp<2>(V(101)), "");
-#endif // > C++17
}
int main(int, char**) {