P2162R2 Inheriting From variant (#2006)

Co-authored-by: Casey Carter <Casey@Carter.net>
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Igor Zhukov 2021-06-30 04:23:08 +07:00 коммит произвёл GitHub
Родитель a8c7283e02
Коммит aaa5d08964
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 102 добавлений и 4 удалений

Просмотреть файл

@ -111,6 +111,7 @@
// P0858R0 Constexpr Iterator Requirements
// P1065R2 constexpr INVOKE
// (the std::invoke function only; other components like bind and reference_wrapper are C++20 only)
// P2162R2 Inheriting From variant
// _HAS_CXX17 indirectly controls:
// N4190 Removing auto_ptr, random_shuffle(), And Old <functional> Stuff
@ -1198,7 +1199,7 @@
#define __cpp_lib_shared_ptr_weak_type 201606L
#define __cpp_lib_string_view 201803L
#define __cpp_lib_to_chars 201611L
#define __cpp_lib_variant 201606L
#define __cpp_lib_variant 202102L
#endif // _HAS_CXX17
// C++20

Просмотреть файл

@ -654,6 +654,10 @@ std/language.support/support.limits/support.limits.general/chrono.version.pass.c
# "should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
std/language.support/support.limits/support.limits.general/memory.version.pass.cpp FAIL
# Test should be enabled after LLVM update
# updated test https://github.com/llvm/llvm-project/commit/0324b46cd873abc4fabe19f4bd468d10398ffd0d#diff-a9be5c3f8e18be99f40fb35f58960f400413a76252d86b53f80d76cb09cb53ef
# should work
std/language.support/support.limits/support.limits.general/variant.version.pass.cpp FAIL
# *** LIKELY STL BUGS ***
# Not yet analyzed, likely STL bugs. Assertions and other runtime failures.

Просмотреть файл

@ -654,6 +654,10 @@ language.support\support.limits\support.limits.general\chrono.version.pass.cpp
# "should not be defined when TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700 is not defined!"
language.support\support.limits\support.limits.general\memory.version.pass.cpp
# Test should be enabled after LLVM update
# updated test https://github.com/llvm/llvm-project/commit/0324b46cd873abc4fabe19f4bd468d10398ffd0d#diff-a9be5c3f8e18be99f40fb35f58960f400413a76252d86b53f80d76cb09cb53ef
# should work
language.support\support.limits\support.limits.general\variant.version.pass.cpp
# *** LIKELY STL BUGS ***
# Not yet analyzed, likely STL bugs. Assertions and other runtime failures.

Просмотреть файл

@ -420,6 +420,7 @@ tests\P1502R1_standard_library_header_units
tests\P1614R2_spaceship
tests\P1645R1_constexpr_numeric
tests\P1682R3_to_underlying
tests\P2162R2_std_visit_for_derived_classes_from_variant
tests\VSO_0000000_allocator_propagation
tests\VSO_0000000_any_calling_conventions
tests\VSO_0000000_c_math_functions

Просмотреть файл

@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
RUNALL_INCLUDE ..\usual_17_matrix.lst

Просмотреть файл

@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include <cassert>
#include <memory>
#include <utility>
#include <variant>
using namespace std;
struct Disconnected {
int val;
};
struct Connecting {
char val;
};
struct Connected {
double val;
};
struct State : variant<Disconnected, Connecting, Connected> {
using variant::variant;
};
void example1_from_p2162r2() {
State v1 = Disconnected{45};
const State v2 = Connecting{'d'};
visit([](auto x) { assert(x.val == 45); }, v1);
visit([](auto x) { assert(x.val == 'd'); }, v2);
visit([](auto x) { assert(x.val == 5.5); }, State{Connected{5.5}});
visit([](auto x) { assert(x.val == 45); }, move(v1));
visit([](auto x) { assert(x.val == 'd'); }, move(v2));
}
struct Expr;
struct Neg {
shared_ptr<Expr> expr;
};
struct Add {
shared_ptr<Expr> lhs;
shared_ptr<Expr> rhs;
};
struct Mul {
shared_ptr<Expr> lhs;
shared_ptr<Expr> rhs;
};
struct Expr : variant<int, Neg, Add, Mul> {
using variant::variant;
};
int eval(const Expr& expr) {
struct visitor {
int operator()(int i) const {
return i;
}
int operator()(const Neg& n) const {
return -eval(*n.expr);
}
int operator()(const Add& a) const {
return eval(*a.lhs) + eval(*a.rhs);
}
int operator()(const Mul& m) const {
return eval(*m.lhs) * eval(*m.rhs);
}
};
return visit(visitor{}, expr);
}
void example2_from_p2162r2() {
// (1) + (2*3)
const Expr e = Add{make_shared<Expr>(1), make_shared<Expr>(Mul{make_shared<Expr>(2), make_shared<Expr>(3)})};
assert(eval(e) == (1 + 2 * 3));
}
int main() {
example1_from_p2162r2();
example2_from_p2162r2();
}

Просмотреть файл

@ -1664,10 +1664,10 @@ STATIC_ASSERT(__cpp_lib_unwrap_ref == 201811L);
#if _HAS_CXX17
#ifndef __cpp_lib_variant
#error __cpp_lib_variant is not defined
#elif __cpp_lib_variant != 201606L
#error __cpp_lib_variant is not 201606L
#elif __cpp_lib_variant != 202102L
#error __cpp_lib_variant is not 202102L
#else
STATIC_ASSERT(__cpp_lib_variant == 201606L);
STATIC_ASSERT(__cpp_lib_variant == 202102L);
#endif
#else
#ifdef __cpp_lib_variant