
Also reorder some directives so that the dg-options setting -std=gnu++17 comes before the dg-do that requires c++17. libstdc++-v3/ChangeLog: * testsuite/17_intro/headers/c++2017/all_attributes.cc: Add c++17 effective-target. * testsuite/17_intro/headers/c++2017/all_no_exceptions.cc: Likewise. * testsuite/17_intro/headers/c++2017/all_no_rtti.cc: Likewise. * testsuite/17_intro/headers/c++2017/all_pedantic_errors.cc: Likewise. * testsuite/17_intro/headers/c++2017/operator_names.cc: Likewise. * testsuite/17_intro/headers/c++2017/stdc++.cc: Likewise. * testsuite/17_intro/headers/c++2017/stdc++_multiple_inclusion.cc: Likewise. * testsuite/18_support/uncaught_exceptions/uncaught_exceptions.cc: Likewise. * testsuite/19_diagnostics/error_code/is_error_code_v.cc: Likewise. * testsuite/20_util/any/assign/1.cc: Likewise. * testsuite/20_util/any/assign/2.cc: Likewise. * testsuite/20_util/any/assign/emplace.cc: Likewise. * testsuite/20_util/any/assign/exception.cc: Likewise. * testsuite/20_util/any/assign/self.cc: Likewise. * testsuite/20_util/any/cons/1.cc: Likewise. * testsuite/20_util/any/cons/2.cc: Likewise. * testsuite/20_util/any/cons/aligned.cc: Likewise. * testsuite/20_util/any/cons/explicit.cc: Likewise. * testsuite/20_util/any/cons/in_place.cc: Likewise. * testsuite/20_util/any/cons/nontrivial.cc: Likewise. * testsuite/20_util/any/make_any.cc: Likewise. * testsuite/20_util/any/misc/any_cast.cc: Likewise. * testsuite/20_util/any/misc/any_cast_no_rtti.cc: Likewise. * testsuite/20_util/any/misc/swap.cc: Likewise. * testsuite/20_util/any/modifiers/1.cc: Likewise. * testsuite/20_util/any/observers/type.cc: Likewise. * testsuite/20_util/any/requirements.cc: Likewise. * testsuite/20_util/any/typedefs.cc: Likewise. * testsuite/20_util/as_const/1.cc: Likewise. * testsuite/20_util/as_const/rvalue_neg.cc: Likewise. * testsuite/20_util/bind/is_placeholder_v.cc: Likewise. * testsuite/20_util/bool_constant/requirements.cc: Likewise. * testsuite/20_util/duration/requirements/treat_as_floating_point_v.cc: Likewise. * testsuite/20_util/duration_cast/rounding.cc: Likewise. * testsuite/20_util/enable_shared_from_this/members/weak_from_this.cc: Likewise. * testsuite/20_util/function_objects/invoke/59768.cc: Likewise. * testsuite/20_util/function_objects/not_fn/1.cc: Likewise. * testsuite/20_util/function_objects/searchers.cc: Likewise. * testsuite/20_util/in_place/requirements.cc: Likewise. * testsuite/20_util/is_invocable/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_invocable/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_invocable/value.cc: Likewise. * testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_nothrow_invocable/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_nothrow_swappable/value.cc: Likewise. * testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_nothrow_swappable_with/value.cc: Likewise. * testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_swappable/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_swappable/value.cc: Likewise. * testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/is_swappable_with/requirements/typedefs.cc: Likewise. * testsuite/20_util/is_swappable_with/value.cc: Likewise. * testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc: Likewise. * testsuite/20_util/logical_traits/requirements/typedefs.cc: Likewise. * testsuite/20_util/logical_traits/value.cc: Likewise. * testsuite/20_util/optional/constexpr/make_optional.cc: Likewise. * testsuite/20_util/optional/constexpr/observers/2.cc: Likewise. * testsuite/20_util/optional/constexpr/observers/3.cc: Likewise. * testsuite/20_util/optional/hash.cc: Likewise. * testsuite/20_util/pair/swap_cxx17.cc: Likewise. * testsuite/20_util/ratio/requirements/ratio_equal_v.cc: Likewise. * testsuite/20_util/shared_ptr/requirements/weak_type.cc: Likewise. * testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc: Likewise. * testsuite/20_util/tuple/apply/1.cc: Likewise. * testsuite/20_util/tuple/make_from_tuple/1.cc: Likewise. * testsuite/20_util/tuple/swap_cxx17.cc: Likewise. * testsuite/20_util/tuple/tuple_size_v.cc: Likewise. * testsuite/20_util/unique_ptr/specialized_algorithms/swap_cxx17.cc: Likewise. * testsuite/20_util/uses_allocator/requirements/uses_allocator_v.cc: Likewise. * testsuite/20_util/variant/any.cc: Likewise. * testsuite/20_util/variant/compile.cc: Likewise. * testsuite/20_util/variant/hash.cc: Likewise. * testsuite/20_util/variant/index_type.cc: Likewise. * testsuite/20_util/variant/run.cc: Likewise. * testsuite/20_util/void_t/1.cc: Likewise. * testsuite/21_strings/basic_string/79162.cc: Likewise. * testsuite/21_strings/basic_string/cons/char/7.cc: Likewise. * testsuite/21_strings/basic_string/cons/wchar_t/7.cc: Likewise. * testsuite/21_strings/basic_string/lwg2758.cc: Likewise. * testsuite/21_strings/basic_string/lwg2946.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/append/char/4.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/append/wchar_t/4.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/assign/char/4.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/assign/wchar_t/4.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/insert/char/3.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/insert/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/replace/char/7.cc: Likewise. * testsuite/21_strings/basic_string/modifiers/replace/wchar_t/7.cc: Likewise. * testsuite/21_strings/basic_string/operations/compare/char/2.cc: Likewise. * testsuite/21_strings/basic_string/operations/compare/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string/operations/data/char/2.cc: Likewise. * testsuite/21_strings/basic_string/operations/data/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string/operations/find/char/5.cc: Likewise. * testsuite/21_strings/basic_string/operations/find/wchar_t/5.cc: Likewise. * testsuite/21_strings/basic_string/operators/char/5.cc: Likewise. * testsuite/21_strings/basic_string/operators/wchar_t/5.cc: Likewise. * testsuite/21_strings/basic_string_view/capacity/1.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/char/3.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string_view/cons/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/empty.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/front_back.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/empty.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/front_back.cc: Likewise. * testsuite/21_strings/basic_string_view/include.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/char/3.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/pod/10081-out.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string_view/inserters/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string_view/literals/types-char8_t.cc: Likewise. * testsuite/21_strings/basic_string_view/literals/types.cc: Likewise. * testsuite/21_strings/basic_string_view/literals/values-char8_t.cc: Likewise. * testsuite/21_strings/basic_string_view/literals/values.cc: Likewise. * testsuite/21_strings/basic_string_view/modifiers/remove_prefix/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/modifiers/remove_prefix/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/modifiers/remove_suffix/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/modifiers/remove_suffix/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/compare/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/compare/char/13650.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/compare/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/compare/wchar_t/13650.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/copy/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/copy/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/data/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/data/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/char/3.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/char/4.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/find/wchar_t/4.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/char/2.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/char/3.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/rfind/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/string_conversion/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/substr/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/operations/substr/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/range_access/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/range_access/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/char/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/char16_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/char32_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/char8_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/explicit_instantiation/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string_view/requirements/typedefs.cc: Likewise. * testsuite/21_strings/basic_string_view/typedefs.cc: Likewise. * testsuite/21_strings/basic_string_view/types/1.cc: Likewise. * testsuite/23_containers/array/specialized_algorithms/swap_cxx17.cc: Likewise. * testsuite/23_containers/map/modifiers/extract.cc: Likewise. * testsuite/23_containers/map/modifiers/insert_or_assign/1.cc: Likewise. * testsuite/23_containers/map/modifiers/merge.cc: Likewise. * testsuite/23_containers/map/modifiers/try_emplace/1.cc: Likewise. * testsuite/23_containers/multimap/modifiers/extract.cc: Likewise. * testsuite/23_containers/multimap/modifiers/merge.cc: Likewise. * testsuite/23_containers/multiset/modifiers/extract.cc: Likewise. * testsuite/23_containers/multiset/modifiers/merge.cc: Likewise. * testsuite/23_containers/set/modifiers/extract.cc: Likewise. * testsuite/23_containers/set/modifiers/merge.cc: Likewise. * testsuite/23_containers/unordered_map/modifiers/extract.cc: Likewise. * testsuite/23_containers/unordered_map/modifiers/insert_or_assign.cc: Likewise. * testsuite/23_containers/unordered_map/modifiers/merge.cc: Likewise. * testsuite/23_containers/unordered_map/modifiers/try_emplace.cc: Likewise. * testsuite/23_containers/unordered_multimap/modifiers/extract.cc: Likewise. * testsuite/23_containers/unordered_multimap/modifiers/merge.cc: Likewise. * testsuite/23_containers/unordered_multiset/modifiers/extract.cc: Likewise. * testsuite/23_containers/unordered_multiset/modifiers/merge.cc: Likewise. * testsuite/23_containers/unordered_set/modifiers/extract.cc: Likewise. * testsuite/23_containers/unordered_set/modifiers/merge.cc: Likewise. * testsuite/24_iterators/headers/iterator/range_access_c++17.cc: Likewise. * testsuite/24_iterators/headers/iterator/synopsis_c++17.cc: Likewise. * testsuite/25_algorithms/clamp/1.cc: Likewise. * testsuite/25_algorithms/clamp/2.cc: Likewise. * testsuite/25_algorithms/clamp/constexpr.cc: Likewise. * testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc: Likewise. * testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc: Likewise. * testsuite/26_numerics/headers/cmath/functions_std_c++17.cc: Likewise. * testsuite/26_numerics/headers/cmath/special_functions_global.cc: Likewise. * testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: Likewise. * testsuite/29_atomics/atomic/is_always_lock_free.cc: Likewise. * testsuite/29_atomics/atomic_integral/is_always_lock_free.cc: Likewise. * testsuite/30_threads/shared_lock/70766.cc: Likewise. * testsuite/30_threads/shared_mutex/cons/1.cc: Likewise. * testsuite/30_threads/shared_mutex/cons/assign_neg.cc: Likewise. * testsuite/30_threads/shared_mutex/cons/copy_neg.cc: Likewise. * testsuite/30_threads/shared_mutex/requirements/standard_layout.cc: Likewise. * testsuite/30_threads/shared_mutex/try_lock/1.cc: Likewise. * testsuite/30_threads/shared_mutex/try_lock/2.cc: Likewise. * testsuite/30_threads/shared_mutex/unlock/1.cc: Likewise.
619 lines
21 KiB
C++
619 lines
21 KiB
C++
// { dg-options "-std=gnu++17" }
|
|
// { dg-do compile { target c++17 } }
|
|
|
|
// Copyright (C) 2016-2020 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with this library; see the file COPYING3. If not see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
#include <variant>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
using namespace std;
|
|
|
|
struct AllDeleted
|
|
{
|
|
AllDeleted() = delete;
|
|
AllDeleted(const AllDeleted&) = delete;
|
|
AllDeleted(AllDeleted&&) = delete;
|
|
AllDeleted& operator=(const AllDeleted&) = delete;
|
|
AllDeleted& operator=(AllDeleted&&) = delete;
|
|
};
|
|
|
|
struct Empty
|
|
{
|
|
Empty() { };
|
|
Empty(const Empty&) { };
|
|
Empty(Empty&&) { };
|
|
Empty& operator=(const Empty&) { return *this; };
|
|
Empty& operator=(Empty&&) { return *this; };
|
|
};
|
|
|
|
struct DefaultNoexcept
|
|
{
|
|
DefaultNoexcept() noexcept = default;
|
|
DefaultNoexcept(const DefaultNoexcept&) noexcept = default;
|
|
DefaultNoexcept(DefaultNoexcept&&) noexcept = default;
|
|
DefaultNoexcept& operator=(const DefaultNoexcept&) noexcept = default;
|
|
DefaultNoexcept& operator=(DefaultNoexcept&&) noexcept = default;
|
|
};
|
|
|
|
struct MoveCtorOnly
|
|
{
|
|
MoveCtorOnly() noexcept = delete;
|
|
MoveCtorOnly(const MoveCtorOnly&) noexcept = delete;
|
|
MoveCtorOnly(MoveCtorOnly&&) noexcept { }
|
|
MoveCtorOnly& operator=(const MoveCtorOnly&) noexcept = delete;
|
|
MoveCtorOnly& operator=(MoveCtorOnly&&) noexcept = delete;
|
|
};
|
|
|
|
struct MoveCtorAndSwapOnly : MoveCtorOnly { };
|
|
void swap(MoveCtorAndSwapOnly&, MoveCtorAndSwapOnly&) { }
|
|
|
|
struct DeletedMoves
|
|
{
|
|
DeletedMoves() = default;
|
|
DeletedMoves(const DeletedMoves&) = default;
|
|
DeletedMoves(DeletedMoves&&) = delete;
|
|
DeletedMoves& operator=(const DeletedMoves&) = default;
|
|
DeletedMoves& operator=(DeletedMoves&&) = delete;
|
|
};
|
|
|
|
struct nonliteral
|
|
{
|
|
nonliteral() { }
|
|
|
|
bool operator<(const nonliteral&) const;
|
|
bool operator<=(const nonliteral&) const;
|
|
bool operator==(const nonliteral&) const;
|
|
bool operator!=(const nonliteral&) const;
|
|
bool operator>=(const nonliteral&) const;
|
|
bool operator>(const nonliteral&) const;
|
|
};
|
|
|
|
struct virtual_default_dtor {
|
|
virtual ~virtual_default_dtor() = default;
|
|
};
|
|
|
|
void default_ctor()
|
|
{
|
|
static_assert(is_default_constructible_v<variant<int, string>>);
|
|
static_assert(is_default_constructible_v<variant<string, string>>);
|
|
static_assert(!is_default_constructible_v<variant<AllDeleted, string>>);
|
|
static_assert(is_default_constructible_v<variant<string, AllDeleted>>);
|
|
static_assert(is_default_constructible_v<variant<DeletedMoves>>);
|
|
|
|
static_assert(noexcept(variant<int>()));
|
|
static_assert(!noexcept(variant<Empty>()));
|
|
static_assert(noexcept(variant<DefaultNoexcept>()));
|
|
{
|
|
variant<virtual_default_dtor> a;
|
|
}
|
|
}
|
|
|
|
void copy_ctor()
|
|
{
|
|
static_assert(is_copy_constructible_v<variant<int, string>>);
|
|
static_assert(!is_copy_constructible_v<variant<AllDeleted, string>>);
|
|
static_assert(is_trivially_copy_constructible_v<variant<int>>);
|
|
static_assert(!is_trivially_copy_constructible_v<variant<std::string>>);
|
|
static_assert(is_trivially_copy_constructible_v<variant<DeletedMoves>>);
|
|
|
|
{
|
|
variant<int> a;
|
|
static_assert(noexcept(variant<int>(a)));
|
|
}
|
|
{
|
|
variant<string> a;
|
|
static_assert(!noexcept(variant<string>(a)));
|
|
}
|
|
{
|
|
variant<int, string> a;
|
|
static_assert(!noexcept(variant<int, string>(a)));
|
|
}
|
|
{
|
|
variant<int, char> a;
|
|
static_assert(noexcept(variant<int, char>(a)));
|
|
}
|
|
}
|
|
|
|
void move_ctor()
|
|
{
|
|
static_assert(is_move_constructible_v<variant<int, string>>);
|
|
static_assert(!is_move_constructible_v<variant<AllDeleted, string>>);
|
|
static_assert(is_move_constructible_v<variant<int, DeletedMoves>>); // uses copy ctor
|
|
static_assert(is_trivially_move_constructible_v<variant<int>>);
|
|
static_assert(!is_trivially_move_constructible_v<variant<std::string>>);
|
|
static_assert(!noexcept(variant<int, Empty>(declval<variant<int, Empty>>())));
|
|
static_assert(noexcept(variant<int, DefaultNoexcept>(declval<variant<int, DefaultNoexcept>>())));
|
|
}
|
|
|
|
void arbitrary_ctor()
|
|
{
|
|
static_assert(!is_constructible_v<variant<string, string>, const char*>);
|
|
static_assert(is_constructible_v<variant<int, string>, const char*>);
|
|
static_assert(noexcept(variant<int, Empty>(int{})));
|
|
static_assert(noexcept(variant<int, DefaultNoexcept>(int{})));
|
|
static_assert(!noexcept(variant<int, Empty>(Empty{})));
|
|
static_assert(noexcept(variant<int, DefaultNoexcept>(DefaultNoexcept{})));
|
|
|
|
// P0608R3 disallow narrowing conversions and boolean conversions
|
|
static_assert(!is_constructible_v<variant<float>, int>);
|
|
static_assert(!is_constructible_v<variant<float, vector<int>>, int>);
|
|
static_assert(is_constructible_v<variant<float, int>, char>);
|
|
static_assert(!is_constructible_v<variant<float, char>, int>);
|
|
static_assert(is_constructible_v<variant<float, long>, int>);
|
|
struct big_int { big_int(int) { } };
|
|
static_assert(is_constructible_v<variant<float, big_int>, int>);
|
|
|
|
static_assert(!is_constructible_v<variant<int>, unsigned>);
|
|
static_assert(!is_constructible_v<variant<bool>, int>);
|
|
static_assert(!is_constructible_v<variant<bool>, void*>);
|
|
|
|
// P1957R2 Converting from T* to bool should be considered narrowing
|
|
struct ConvertibleToBool
|
|
{
|
|
operator bool() const { return true; }
|
|
};
|
|
static_assert(is_constructible_v<variant<bool>, ConvertibleToBool>);
|
|
static_assert(is_constructible_v<variant<bool, int>, ConvertibleToBool>);
|
|
}
|
|
|
|
struct none { none() = delete; };
|
|
struct any { template <typename T> any(T&&) {} };
|
|
|
|
void in_place_index_ctor()
|
|
{
|
|
variant<string, string> a(in_place_index<0>, "a");
|
|
variant<string, string> b(in_place_index<1>, {'a'});
|
|
|
|
static_assert(!is_constructible_v<variant<none, any>, std::in_place_index_t<0>>, "PR libstdc++/90165");
|
|
}
|
|
|
|
void in_place_type_ctor()
|
|
{
|
|
variant<int, string, int> a(in_place_type<string>, "a");
|
|
variant<int, string, int> b(in_place_type<string>, {'a'});
|
|
static_assert(!is_constructible_v<variant<string, string>, in_place_type_t<string>, const char*>);
|
|
static_assert(!is_constructible_v<variant<none, any>, std::in_place_type_t<none>>, "PR libstdc++/90165");
|
|
}
|
|
|
|
void dtor()
|
|
{
|
|
static_assert(is_destructible_v<variant<int, string>>);
|
|
static_assert(is_destructible_v<variant<AllDeleted, string>>);
|
|
}
|
|
|
|
void copy_assign()
|
|
{
|
|
static_assert(is_copy_assignable_v<variant<int, string>>);
|
|
static_assert(!is_copy_assignable_v<variant<AllDeleted, string>>);
|
|
static_assert(is_trivially_copy_assignable_v<variant<int>>);
|
|
static_assert(!is_trivially_copy_assignable_v<variant<string>>);
|
|
static_assert(is_trivially_copy_assignable_v<variant<DeletedMoves>>);
|
|
{
|
|
variant<Empty> a;
|
|
static_assert(!noexcept(a = a));
|
|
}
|
|
{
|
|
variant<DefaultNoexcept> a;
|
|
static_assert(noexcept(a = a));
|
|
}
|
|
}
|
|
|
|
void move_assign()
|
|
{
|
|
static_assert(is_move_assignable_v<variant<int, string>>);
|
|
static_assert(!is_move_assignable_v<variant<AllDeleted, string>>);
|
|
static_assert(is_move_assignable_v<variant<int, DeletedMoves>>); // uses copy assignment
|
|
static_assert(is_trivially_move_assignable_v<variant<int>>);
|
|
static_assert(!is_trivially_move_assignable_v<variant<string>>);
|
|
{
|
|
variant<Empty> a;
|
|
static_assert(!noexcept(a = std::move(a)));
|
|
}
|
|
{
|
|
variant<DefaultNoexcept> a;
|
|
static_assert(noexcept(a = std::move(a)));
|
|
}
|
|
}
|
|
|
|
void arbitrary_assign()
|
|
{
|
|
static_assert(!is_assignable_v<variant<string, string>, const char*>);
|
|
static_assert(is_assignable_v<variant<int, string>, const char*>);
|
|
static_assert(noexcept(variant<int, Empty>() = int{}));
|
|
static_assert(noexcept(variant<int, DefaultNoexcept>() = int{}));
|
|
static_assert(!noexcept(variant<int, Empty>() = Empty{}));
|
|
static_assert(noexcept(variant<int, DefaultNoexcept>() = DefaultNoexcept{}));
|
|
}
|
|
|
|
void test_get()
|
|
{
|
|
static_assert(is_same<decltype(get<0>(variant<int, string>())), int&&>::value);
|
|
static_assert(is_same<decltype(get<1>(variant<int, string>())), string&&>::value);
|
|
static_assert(is_same<decltype(get<1>(variant<int, const string>())), const string&&>::value);
|
|
|
|
static_assert(is_same<decltype(get<int>(variant<int, string>())), int&&>::value);
|
|
static_assert(is_same<decltype(get<string>(variant<int, string>())), string&&>::value);
|
|
static_assert(is_same<decltype(get<const string>(variant<int, const string>())), const string&&>::value);
|
|
}
|
|
|
|
void test_relational()
|
|
{
|
|
{
|
|
constexpr variant<int, nonliteral> a(42), b(43);
|
|
static_assert((a < b));
|
|
static_assert(!(a > b));
|
|
static_assert((a <= b));
|
|
static_assert(!(a == b));
|
|
static_assert((a != b));
|
|
static_assert(!(a >= b));
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(42), b(42);
|
|
static_assert(!(a < b));
|
|
static_assert(!(a > b));
|
|
static_assert((a <= b));
|
|
static_assert((a == b));
|
|
static_assert(!(a != b));
|
|
static_assert((a >= b));
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(43), b(42);
|
|
static_assert(!(a < b));
|
|
static_assert((a > b));
|
|
static_assert(!(a <= b));
|
|
static_assert(!(a == b));
|
|
static_assert((a != b));
|
|
static_assert((a >= b));
|
|
}
|
|
{
|
|
constexpr monostate a, b;
|
|
static_assert(!(a < b));
|
|
static_assert(!(a > b));
|
|
static_assert((a <= b));
|
|
static_assert((a == b));
|
|
static_assert(!(a != b));
|
|
static_assert((a >= b));
|
|
}
|
|
}
|
|
|
|
// Not swappable, and variant<C> not swappable via the generic std::swap.
|
|
struct C { };
|
|
void swap(C&, C&) = delete;
|
|
|
|
static_assert( !std::is_swappable_v<variant<C>> );
|
|
static_assert( !std::is_swappable_v<variant<int, C>> );
|
|
static_assert( !std::is_swappable_v<variant<C, int>> );
|
|
|
|
// Not swappable, and variant<D> not swappable via the generic std::swap.
|
|
struct D { D(D&&) = delete; };
|
|
|
|
static_assert( !std::is_swappable_v<variant<D>> );
|
|
static_assert( !std::is_swappable_v<variant<int, D>> );
|
|
static_assert( !std::is_swappable_v<variant<D, int>> );
|
|
|
|
void test_swap()
|
|
{
|
|
static_assert(is_swappable_v<variant<int, string>>);
|
|
static_assert(!is_swappable_v<variant<MoveCtorOnly>>);
|
|
static_assert(is_swappable_v<variant<MoveCtorAndSwapOnly>>);
|
|
static_assert(!is_swappable_v<variant<AllDeleted>>);
|
|
}
|
|
|
|
void test_visit()
|
|
{
|
|
{
|
|
struct Visitor
|
|
{
|
|
void operator()(monostate) {}
|
|
void operator()(const int&) {}
|
|
};
|
|
struct CVisitor
|
|
{
|
|
void operator()(monostate) const {}
|
|
void operator()(const int&) const {}
|
|
};
|
|
}
|
|
{
|
|
struct Visitor
|
|
{
|
|
bool operator()(int, float) { return false; }
|
|
bool operator()(int, double) { return false; }
|
|
bool operator()(char, float) { return false; }
|
|
bool operator()(char, double) { return false; }
|
|
};
|
|
visit(Visitor(), variant<int, char>(), variant<float, double>());
|
|
}
|
|
{
|
|
struct Visitor
|
|
{
|
|
constexpr bool operator()(const int&) { return true; }
|
|
constexpr bool operator()(const nonliteral&) { return false; }
|
|
};
|
|
static_assert(visit(Visitor(), variant<int, nonliteral>(0)));
|
|
}
|
|
{
|
|
struct Visitor
|
|
{
|
|
constexpr bool operator()(const int&) { return true; }
|
|
constexpr bool operator()(const nonliteral&) { return false; }
|
|
};
|
|
static_assert(visit(Visitor(), variant<int, nonliteral>(0)));
|
|
}
|
|
// PR libstdc++/79513
|
|
{
|
|
std::variant<int> v [[gnu::unused]] (5);
|
|
std::visit([](int&){}, v);
|
|
std::visit([](int&&){}, std::move(v));
|
|
}
|
|
}
|
|
|
|
void test_constexpr()
|
|
{
|
|
constexpr variant<int> a;
|
|
static_assert(holds_alternative<int>(a));
|
|
constexpr variant<int, char> b(in_place_index<0>, int{});
|
|
static_assert(holds_alternative<int>(b));
|
|
constexpr variant<int, char> c(in_place_type<int>, int{});
|
|
static_assert(holds_alternative<int>(c));
|
|
constexpr variant<int, char> d(in_place_index<1>, char{});
|
|
static_assert(holds_alternative<char>(d));
|
|
constexpr variant<int, char> e(in_place_type<char>, char{});
|
|
static_assert(holds_alternative<char>(e));
|
|
constexpr variant<int, char> f(char{});
|
|
static_assert(holds_alternative<char>(f));
|
|
|
|
{
|
|
struct literal {
|
|
constexpr literal() = default;
|
|
};
|
|
|
|
constexpr variant<literal, nonliteral> v{};
|
|
constexpr variant<literal, nonliteral> v1{in_place_type<literal>};
|
|
constexpr variant<literal, nonliteral> v2{in_place_index<0>};
|
|
}
|
|
|
|
{
|
|
constexpr variant<int> a(42);
|
|
static_assert(get<0>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(42);
|
|
static_assert(get<0>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<nonliteral, int> a(42);
|
|
static_assert(get<1>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int> a(42);
|
|
static_assert(get<int>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(42);
|
|
static_assert(get<int>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<nonliteral, int> a(42);
|
|
static_assert(get<int>(a) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int> a(42);
|
|
static_assert(get<0>(std::move(a)) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(42);
|
|
static_assert(get<0>(std::move(a)) == 42);
|
|
}
|
|
{
|
|
constexpr variant<nonliteral, int> a(42);
|
|
static_assert(get<1>(std::move(a)) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int> a(42);
|
|
static_assert(get<int>(std::move(a)) == 42);
|
|
}
|
|
{
|
|
constexpr variant<int, nonliteral> a(42);
|
|
static_assert(get<int>(std::move(a)) == 42);
|
|
}
|
|
{
|
|
constexpr variant<nonliteral, int> a(42);
|
|
static_assert(get<int>(std::move(a)) == 42);
|
|
}
|
|
}
|
|
|
|
void test_pr77641()
|
|
{
|
|
struct X {
|
|
constexpr X() { }
|
|
};
|
|
|
|
constexpr std::variant<X> v1 = X{};
|
|
}
|
|
|
|
namespace adl_trap
|
|
{
|
|
struct X {
|
|
X() = default;
|
|
X(int) { }
|
|
X(std::initializer_list<int>, const X&) { }
|
|
};
|
|
template<typename T> void move(T&) { }
|
|
template<typename T> void forward(T&) { }
|
|
|
|
struct Visitor {
|
|
template<typename T> void operator()(T&&) { }
|
|
};
|
|
}
|
|
|
|
void test_adl()
|
|
{
|
|
using adl_trap::X;
|
|
X x;
|
|
std::initializer_list<int> il;
|
|
adl_trap::Visitor vis;
|
|
|
|
std::variant<X> v0(x);
|
|
v0 = x;
|
|
v0.emplace<0>(x);
|
|
v0.emplace<0>(il, x);
|
|
visit(vis, v0);
|
|
variant<X> v1{in_place_index<0>, x};
|
|
variant<X> v2{in_place_type<X>, x};
|
|
variant<X> v3{in_place_index<0>, il, x};
|
|
variant<X> v4{in_place_type<X>, il, x};
|
|
}
|
|
|
|
void test_variant_alternative()
|
|
{
|
|
static_assert(is_same_v<variant_alternative_t<0, variant<int, string>>, int>);
|
|
static_assert(is_same_v<variant_alternative_t<1, variant<int, string>>, string>);
|
|
|
|
static_assert(is_same_v<variant_alternative_t<0, const variant<int>>, const int>);
|
|
static_assert(is_same_v<variant_alternative_t<0, volatile variant<int>>, volatile int>);
|
|
static_assert(is_same_v<variant_alternative_t<0, const volatile variant<int>>, const volatile int>);
|
|
}
|
|
|
|
template<typename V, typename T>
|
|
constexpr auto has_type_emplace(int) -> decltype((declval<V>().template emplace<T>(), true))
|
|
{ return true; };
|
|
|
|
template<typename V, typename T>
|
|
constexpr bool has_type_emplace(...)
|
|
{ return false; };
|
|
|
|
template<typename V, size_t N>
|
|
constexpr auto has_index_emplace(int) -> decltype((declval<V>().template emplace<N>(), true))
|
|
{ return true; };
|
|
|
|
template<typename V, size_t T>
|
|
constexpr bool has_index_emplace(...)
|
|
{ return false; };
|
|
|
|
void test_emplace()
|
|
{
|
|
static_assert(has_type_emplace<variant<int>, int>(0));
|
|
static_assert(!has_type_emplace<variant<long>, int>(0));
|
|
static_assert(has_index_emplace<variant<int>, 0>(0));
|
|
static_assert(!has_type_emplace<variant<AllDeleted>, AllDeleted>(0));
|
|
static_assert(!has_index_emplace<variant<AllDeleted>, 0>(0));
|
|
static_assert(has_type_emplace<variant<int, AllDeleted>, int>(0));
|
|
static_assert(has_index_emplace<variant<int, AllDeleted>, 0>(0));
|
|
static_assert(has_type_emplace<variant<int, vector<int>, AllDeleted>, vector<int>>(0));
|
|
static_assert(has_index_emplace<variant<int, vector<int>, AllDeleted>, 1>(0));
|
|
|
|
// The above tests only check the emplace members are available for
|
|
// overload resolution. The following odr-uses will instantiate them:
|
|
variant<int, vector<int>, AllDeleted> v;
|
|
v.emplace<0>(1);
|
|
v.emplace<int>(1);
|
|
v.emplace<1>(1, 1);
|
|
v.emplace<vector<int>>(1, 1);
|
|
v.emplace<1>({1, 2, 3, 4});
|
|
v.emplace<vector<int>>({1, 2, 3, 4});
|
|
}
|
|
|
|
void test_triviality()
|
|
{
|
|
#define TEST_TEMPLATE(DT, CC, MC, CA, MA, CC_VAL, MC_VAL, CA_VAL, MA_VAL) \
|
|
{ \
|
|
struct A \
|
|
{ \
|
|
~A() DT; \
|
|
A(const A&) CC; \
|
|
A(A&&) MC; \
|
|
A& operator=(const A&) CA; \
|
|
A& operator=(A&&) MA; \
|
|
}; \
|
|
static_assert(CC_VAL == is_trivially_copy_constructible_v<variant<A>>); \
|
|
static_assert(MC_VAL == is_trivially_move_constructible_v<variant<A>>); \
|
|
static_assert(CA_VAL == is_trivially_copy_assignable_v<variant<A>>); \
|
|
static_assert(MA_VAL == is_trivially_move_assignable_v<variant<A>>); \
|
|
}
|
|
TEST_TEMPLATE(=default, =default, =default, =default, =default, true, true, true, true)
|
|
TEST_TEMPLATE(=default, =default, =default, =default, , true, true, true, false)
|
|
TEST_TEMPLATE(=default, =default, =default, , =default, true, true, false, true)
|
|
TEST_TEMPLATE(=default, =default, =default, , , true, true, false, false)
|
|
TEST_TEMPLATE(=default, =default, , =default, =default, true, false, true, false)
|
|
TEST_TEMPLATE(=default, =default, , =default, , true, false, true, false)
|
|
TEST_TEMPLATE(=default, =default, , , =default, true, false, false, false)
|
|
TEST_TEMPLATE(=default, =default, , , , true, false, false, false)
|
|
TEST_TEMPLATE(=default, , =default, =default, =default, false, true, false, true)
|
|
TEST_TEMPLATE(=default, , =default, =default, , false, true, false, false)
|
|
TEST_TEMPLATE(=default, , =default, , =default, false, true, false, true)
|
|
TEST_TEMPLATE(=default, , =default, , , false, true, false, false)
|
|
TEST_TEMPLATE(=default, , , =default, =default, false, false, false, false)
|
|
TEST_TEMPLATE(=default, , , =default, , false, false, false, false)
|
|
TEST_TEMPLATE(=default, , , , =default, false, false, false, false)
|
|
TEST_TEMPLATE(=default, , , , , false, false, false, false)
|
|
TEST_TEMPLATE( , =default, =default, =default, =default, false, false, false, false)
|
|
TEST_TEMPLATE( , =default, =default, =default, , false, false, false, false)
|
|
TEST_TEMPLATE( , =default, =default, , =default, false, false, false, false)
|
|
TEST_TEMPLATE( , =default, =default, , , false, false, false, false)
|
|
TEST_TEMPLATE( , =default, , =default, =default, false, false, false, false)
|
|
TEST_TEMPLATE( , =default, , =default, , false, false, false, false)
|
|
TEST_TEMPLATE( , =default, , , =default, false, false, false, false)
|
|
TEST_TEMPLATE( , =default, , , , false, false, false, false)
|
|
TEST_TEMPLATE( , , =default, =default, =default, false, false, false, false)
|
|
TEST_TEMPLATE( , , =default, =default, , false, false, false, false)
|
|
TEST_TEMPLATE( , , =default, , =default, false, false, false, false)
|
|
TEST_TEMPLATE( , , =default, , , false, false, false, false)
|
|
TEST_TEMPLATE( , , , =default, =default, false, false, false, false)
|
|
TEST_TEMPLATE( , , , =default, , false, false, false, false)
|
|
TEST_TEMPLATE( , , , , =default, false, false, false, false)
|
|
TEST_TEMPLATE( , , , , , false, false, false, false)
|
|
#undef TEST_TEMPLATE
|
|
|
|
#define TEST_TEMPLATE(CC, MC, CA, MA) \
|
|
{ \
|
|
struct A \
|
|
{ \
|
|
A(const A&) CC; \
|
|
A(A&&) MC; \
|
|
A& operator=(const A&) CA; \
|
|
A& operator=(A&&) MA; \
|
|
}; \
|
|
static_assert(!is_trivially_copy_constructible_v<variant<AllDeleted, A>>); \
|
|
static_assert(!is_trivially_move_constructible_v<variant<AllDeleted, A>>); \
|
|
static_assert(!is_trivially_copy_assignable_v<variant<AllDeleted, A>>); \
|
|
static_assert(!is_trivially_move_assignable_v<variant<AllDeleted, A>>); \
|
|
}
|
|
TEST_TEMPLATE(=default, =default, =default, =default)
|
|
TEST_TEMPLATE(=default, =default, =default, )
|
|
TEST_TEMPLATE(=default, =default, , =default)
|
|
TEST_TEMPLATE(=default, =default, , )
|
|
TEST_TEMPLATE(=default, , =default, =default)
|
|
TEST_TEMPLATE(=default, , =default, )
|
|
TEST_TEMPLATE(=default, , , =default)
|
|
TEST_TEMPLATE(=default, , , )
|
|
TEST_TEMPLATE( , =default, =default, =default)
|
|
TEST_TEMPLATE( , =default, =default, )
|
|
TEST_TEMPLATE( , =default, , =default)
|
|
TEST_TEMPLATE( , =default, , )
|
|
TEST_TEMPLATE( , , =default, =default)
|
|
TEST_TEMPLATE( , , =default, )
|
|
TEST_TEMPLATE( , , , =default)
|
|
TEST_TEMPLATE( , , , )
|
|
#undef TEST_TEMPLATE
|
|
|
|
static_assert(is_trivially_copy_constructible_v<variant<DefaultNoexcept, int, char, float, double>>);
|
|
static_assert(is_trivially_move_constructible_v<variant<DefaultNoexcept, int, char, float, double>>);
|
|
static_assert(is_trivially_copy_assignable_v<variant<DefaultNoexcept, int, char, float, double>>);
|
|
static_assert(is_trivially_move_assignable_v<variant<DefaultNoexcept, int, char, float, double>>);
|
|
}
|