mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
We use CARBON_KIND_SWITCH for handling the output of TypeIterator in the TypeStructureBuilder Here is how the errors look when it is misused: - If you don't cover ever type in the variant with a case ``` Enumeration value 'VariantTypeT1NotHandledInSwitch' not handled in switch ``` Is attached to the CARBON_KIND_SWITCH() usage, the `T1` being a 0-based index into the std::variant's type list, indicating which type was missed. - If you have a case for a type that is not in the variant ``` In template: constraints not satisfied for class template 'ValidCaseType' [with T = char] ... bunch of instantiation stuff ... kind_switch.h(124, 12): Because 'char' does not satisfy 'TypeFoundInVariant' ``` Where `char` was the type I put in the `CARBON_KIND` macro, which was not in the variant. - If you have too many types in your variant (currently > 12) ``` In template: static assertion failed due to requirement 'sizeof...(Ts) <= 12': CARBON_KIND_SWITCH supports std::variant with up to 12 types. Add more if needed. ``` Is attached to the CARBON_KIND_SWITCH() usage. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
58 lines
1.4 KiB
C++
58 lines
1.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/base/kind_switch.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
#include "common/raw_string_ostream.h"
|
|
|
|
namespace Carbon {
|
|
namespace {
|
|
|
|
TEST(KindSwitch, Variant) {
|
|
auto f = [](std::variant<int, float, char> v) -> std::string {
|
|
RawStringOstream str;
|
|
CARBON_KIND_SWITCH(v) {
|
|
case CARBON_KIND(int n):
|
|
str << "int = " << n;
|
|
return str.TakeStr();
|
|
case CARBON_KIND(float f):
|
|
str << "float = " << f;
|
|
return str.TakeStr();
|
|
case CARBON_KIND(char c):
|
|
str << "char = " << c;
|
|
return str.TakeStr();
|
|
}
|
|
};
|
|
|
|
EXPECT_EQ(f(int{1}), "int = 1");
|
|
EXPECT_EQ(f(float{2}), "float = 2.000000e+00");
|
|
EXPECT_EQ(f(char{'h'}), "char = h");
|
|
}
|
|
|
|
TEST(KindSwitch, VariantUnusedValue) {
|
|
auto f = [](std::variant<int, float> v) -> std::string {
|
|
RawStringOstream str;
|
|
CARBON_KIND_SWITCH(v) {
|
|
case CARBON_KIND(int n):
|
|
str << "int = " << n;
|
|
return str.TakeStr();
|
|
case CARBON_KIND(float _):
|
|
// The float value is not used, we see that using `_` works.
|
|
str << "float";
|
|
return str.TakeStr();
|
|
}
|
|
};
|
|
|
|
EXPECT_EQ(f(int{1}), "int = 1");
|
|
EXPECT_EQ(f(float{2}), "float");
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace Carbon
|