summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/20_util/variant/compile.cc
diff options
context:
space:
mode:
authorTim Shen <timshen@google.com>2016-08-18 20:31:26 +0000
committerTim Shen <timshen@gcc.gnu.org>2016-08-18 20:31:26 +0000
commit197c757cb11681a6ff6df1491ebfde4f5a392627 (patch)
treebc774dd64d1e9187c477c6aa386748350ca8e8d1 /libstdc++-v3/testsuite/20_util/variant/compile.cc
parentcc015f3abebcfe84c64a38d1198ad4601e36893c (diff)
downloadgcc-197c757cb11681a6ff6df1491ebfde4f5a392627.tar.gz
Implement <variant>
* include/Makefile.am: Add new file std/variant. * include/Makefile.in: Generated from Makefile.am. * include/bits/enable_special_members.h: Add a tag type to allow the construction in non-default constructor. * include/bits/uses_allocator.h: Add convenience traits to detect constructibility. * include/std/variant: Implement <variant>. * testsuite/20_util/variant/compile.cc: Compile-time tests. * testsuite/20_util/variant/run.cc: Runtime tests. From-SVN: r239590
Diffstat (limited to 'libstdc++-v3/testsuite/20_util/variant/compile.cc')
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/compile.cc405
1 files changed, 405 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc
new file mode 100644
index 00000000000..b57d356d301
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc
@@ -0,0 +1,405 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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;
+};
+
+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<>>, "");
+ static_assert(!is_default_constructible_v<variant<AllDeleted, string>>, "");
+ static_assert(is_default_constructible_v<variant<string, AllDeleted>>, "");
+
+ static_assert(noexcept(variant<int>()), "");
+ static_assert(!noexcept(variant<Empty>()), "");
+ static_assert(noexcept(variant<DefaultNoexcept>()), "");
+}
+
+void copy_ctor()
+{
+ static_assert(is_copy_constructible_v<variant<int, string>>, "");
+ static_assert(!is_copy_constructible_v<variant<AllDeleted, string>>, "");
+
+ {
+ 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(!noexcept(variant<int, Empty>(variant<int, Empty>())), "");
+ static_assert(noexcept(variant<int, DefaultNoexcept>(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{})), "");
+}
+
+void in_place_index_ctor()
+{
+ variant<string, string> a(in_place<0>, "a");
+ variant<string, string> b(in_place<1>, {'a'});
+}
+
+void in_place_type_ctor()
+{
+ variant<int, string, int> a(in_place<string>, "a");
+ variant<int, string, int> b(in_place<string>, {'a'});
+ static_assert(!is_constructible_v<variant<string, string>, in_place_type_t<string>, const char*>, "");
+}
+
+void uses_alloc_ctors()
+{
+ std::allocator<char> alloc;
+ variant<int> a(allocator_arg, alloc);
+ static_assert(!is_constructible_v<variant<AllDeleted>, allocator_arg_t, std::allocator<char>>, "");
+ {
+ variant<int> b(allocator_arg, alloc, a);
+ static_assert(!is_constructible_v<variant<void>, allocator_arg_t, std::allocator<char>, const variant<void>&>, "");
+ }
+ {
+ variant<int> b(allocator_arg, alloc, std::move(a));
+ static_assert(!is_constructible_v<variant<void>, allocator_arg_t, std::allocator<char>, variant<void>&&>, "");
+ }
+ {
+ variant<string, int> b(allocator_arg, alloc, "a");
+ static_assert(!is_constructible_v<variant<string, string>, allocator_arg_t, std::allocator<char>, const char*>, "");
+ }
+ {
+ variant<string, int> b(allocator_arg, alloc, in_place<0>, "a");
+ variant<string, string> c(allocator_arg, alloc, in_place<1>, "a");
+ }
+ {
+ variant<string, int> b(allocator_arg, alloc, in_place<0>, {'a'});
+ variant<string, string> c(allocator_arg, alloc, in_place<1>, {'a'});
+ }
+ {
+ variant<int, string, int> b(allocator_arg, alloc, in_place<string>, "a");
+ }
+ {
+ variant<int, string, int> b(allocator_arg, alloc, in_place<string>, {'a'});
+ }
+}
+
+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>>, "");
+ {
+ 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>>, "");
+ {
+ 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, string&>())), string&>::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<1>(variant<int, const string&>())), const 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<string&>(variant<int, string&>())), string&>::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, "");
+ static_assert(is_same<decltype(get<const string&>(variant<int, const string&>())), const string&>::value, "");
+ static_assert(is_same<decltype(get<const string&&>(variant<int, const string&&>())), const string&&>::value, "");
+ }
+ {
+ variant<int, string> a;
+ variant<int, string&> b;
+ variant<int, string&&> c;
+ variant<int, const string> d;
+ variant<int, const string&> e;
+ variant<int, const string&&> f;
+
+ static_assert(is_same<decltype(get<0>(a)), int&>::value, "");
+ static_assert(is_same<decltype(get<1>(a)), string&>::value, "");
+ static_assert(is_same<decltype(get<1>(b)), string&>::value, "");
+ static_assert(is_same<decltype(get<1>(c)), string&>::value, "");
+ static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<1>(f)), const string&>::value, "");
+
+ static_assert(is_same<decltype(get<int>(a)), int&>::value, "");
+ static_assert(is_same<decltype(get<string>(a)), string&>::value, "");
+ static_assert(is_same<decltype(get<string&>(b)), string&>::value, "");
+ static_assert(is_same<decltype(get<string&&>(c)), string&>::value, "");
+ static_assert(is_same<decltype(get<const string>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<const string&>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<const string&&>(f)), const string&>::value, "");
+
+ static_assert(is_same<decltype(get_if<0>(&a)), int*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&a)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&b)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&c)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&f)), const string*>::value, "");
+
+ static_assert(is_same<decltype(get_if<int>(&a)), int*>::value, "");
+ static_assert(is_same<decltype(get_if<string>(&a)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<string&>(&b)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<string&&>(&c)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string&>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string&&>(&f)), const string*>::value, "");
+ }
+ {
+ const variant<int, string> a;
+ const variant<int, string&> b;
+ const variant<int, string&&> c;
+ const variant<int, const string> d;
+ const variant<int, const string&> e;
+ const variant<int, const string&&> f;
+
+ static_assert(is_same<decltype(get<0>(a)), const int&>::value, "");
+ static_assert(is_same<decltype(get<1>(a)), const string&>::value, "");
+ static_assert(is_same<decltype(get<1>(b)), string&>::value, "");
+ static_assert(is_same<decltype(get<1>(c)), string&>::value, "");
+ static_assert(is_same<decltype(get<1>(d)), const string&>::value, "");
+ static_assert(is_same<decltype(get<1>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<1>(f)), const string&>::value, "");
+
+ static_assert(is_same<decltype(get<int>(a)), const int&>::value, "");
+ static_assert(is_same<decltype(get<string>(a)), const string&>::value, "");
+ static_assert(is_same<decltype(get<string&>(b)), string&>::value, "");
+ static_assert(is_same<decltype(get<string&&>(c)), string&>::value, "");
+ static_assert(is_same<decltype(get<const string>(d)), const string&>::value, "");
+ static_assert(is_same<decltype(get<const string&>(e)), const string&>::value, "");
+ static_assert(is_same<decltype(get<const string&&>(f)), const string&>::value, "");
+
+ static_assert(is_same<decltype(get_if<0>(&a)), const int*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&a)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&b)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&c)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&d)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<1>(&f)), const string*>::value, "");
+
+ static_assert(is_same<decltype(get_if<int>(&a)), const int*>::value, "");
+ static_assert(is_same<decltype(get_if<string>(&a)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<string&>(&b)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<string&&>(&c)), string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string>(&d)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string&>(&e)), const string*>::value, "");
+ static_assert(is_same<decltype(get_if<const string&&>(&f)), const string*>::value, "");
+ }
+}
+
+void test_relational()
+{
+ {
+ const variant<int, string> a, b;
+ (void)(a < b);
+ (void)(a > b);
+ (void)(a <= b);
+ (void)(a == b);
+ (void)(a != b);
+ (void)(a >= b);
+ }
+ {
+ const monostate a, b;
+ (void)(a < b);
+ (void)(a > b);
+ (void)(a <= b);
+ (void)(a == b);
+ (void)(a != b);
+ (void)(a >= b);
+ }
+}
+
+void test_swap()
+{
+ variant<int, string> a, b;
+ a.swap(b);
+ swap(a, b);
+}
+
+void test_visit()
+{
+ {
+ struct Visitor
+ {
+ void operator()(monostate) {}
+ void operator()(const int&) {}
+ };
+ struct CVisitor
+ {
+ void operator()(monostate) const {}
+ void operator()(const int&) const {}
+ };
+ variant<monostate, int&, const int&, int&&, const int&&> a;
+ const variant<monostate, int&, const int&, int&&, const int&&> b;
+ Visitor v;
+ const CVisitor u;
+ static_assert(is_same<void, decltype(visit(Visitor(), a))>::value, "");
+ static_assert(is_same<void, decltype(visit(Visitor(), b))>::value, "");
+ static_assert(is_same<void, decltype(visit(v, a))>::value, "");
+ static_assert(is_same<void, decltype(visit(v, b))>::value, "");
+ static_assert(is_same<void, decltype(visit(u, a))>::value, "");
+ static_assert(is_same<void, decltype(visit(u, b))>::value, "");
+ }
+ {
+ 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>());
+ }
+}
+
+void test_constexpr()
+{
+ constexpr variant<int> a;
+ static_assert(holds_alternative<int>(a), "");
+ constexpr variant<int, char> b(in_place<0>, int{});
+ static_assert(holds_alternative<int>(b), "");
+ constexpr variant<int, char> c(in_place<int>, int{});
+ static_assert(holds_alternative<int>(c), "");
+ constexpr variant<int, char> d(in_place<1>, char{});
+ static_assert(holds_alternative<char>(d), "");
+ constexpr variant<int, char> e(in_place<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;
+ };
+
+ struct nonliteral {
+ nonliteral() { }
+ };
+
+ constexpr variant<literal, nonliteral> v{};
+ constexpr variant<literal, nonliteral> v1{in_place<literal>};
+ constexpr variant<literal, nonliteral> v2{in_place<0>};
+ }
+}
+
+void test_void()
+{
+ static_assert(is_same<int&&, decltype(get<int>(variant<int, void>()))>::value, "");
+ static_assert(!is_default_constructible_v<variant<void, int>>, "");
+ static_assert(!is_copy_constructible_v<variant<int, void>>, "");
+ static_assert(!is_move_constructible_v<variant<int, void>>, "");
+ static_assert(!is_copy_assignable_v<variant<int, void>>, "");
+ static_assert(!is_move_assignable_v<variant<int, void>>, "");
+ variant<int, void, string> v;
+ v = 3;
+ v = "asdf";
+}