-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
is
and as
support for std::expected
- Loading branch information
1 parent
1032a5b
commit afc1b10
Showing
7 changed files
with
379 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// `std::expected` requires C++23 so a dedicated test file is needed | ||
// since only MSVC supports it at time of writing, and there's no #ifdef | ||
// or `static if` support in Cpp2 (yet?). | ||
|
||
main: () -> int = { | ||
|
||
ex1: std::expected<int, int> = (123); | ||
ex2: std::expected<int, int> = std::unexpected(-1); | ||
ex3: std::expected<std::string, size_t> = ("Expect the unexpected"); | ||
|
||
if ex1 is int { | ||
std::cout << "ex1 is int\n"; | ||
} | ||
|
||
if ex1 is bool { | ||
std::cout << "BUG - ex1 is not a bool\n"; | ||
return -1; | ||
} | ||
|
||
if ex1 is void { | ||
std::cout << "BUG - ex1 is not 'empty'\n"; | ||
return -1; | ||
} | ||
|
||
if ex1 is std::unexpected<int> { | ||
std::cout << "BUG - ex1 is not unexpected\n"; | ||
return -1; | ||
} | ||
|
||
if ex1 is 123 { | ||
std::cout << "ex1 is 123\n"; | ||
} | ||
|
||
if ex1 is 100 { | ||
std::cout << "BUG - ex1's value is not 100\n"; | ||
return -1; | ||
} | ||
|
||
val1:= ex1 as int; | ||
std::cout << "ex1 as int = " << val1 << "\n"; | ||
|
||
if ex2 is int { | ||
std::cout << "BUG - ex2 is not an int\n"; | ||
return -1; | ||
} | ||
|
||
if ex2 is bool { | ||
std::cout << "BUG - ex2 is not a bool\n"; | ||
return -1; | ||
} | ||
|
||
if ex2 is 123 { | ||
std::cout << "BUG - ex2 does not have a value\n"; | ||
return -1; | ||
} | ||
|
||
if ex2 is std::unexpected<int> { | ||
std::cout << "ex2 is unexpected<int> and error is: " << ex2.error() << "\n"; | ||
} | ||
|
||
if ex2 is void { | ||
std::cout << "ex2 is 'empty' aka unexpected<int> and error is: " << ex2.error() << "\n"; | ||
} | ||
|
||
ex2_err:= ex2 as std::unexpected<int>; | ||
std::cout << "ex2 as std::unexpected<int> and error = " << ex2_err.error() << "\n"; | ||
|
||
test_inspect(ex1, "expected<int, int> with value"); | ||
test_inspect(ex2, "expected<int, int> with unexpected"); | ||
test_inspect(ex3, "expected<string, size_t> with value"); | ||
|
||
return 0; | ||
} | ||
|
||
test_inspect: ( x: _, msg: _ ) = { | ||
|
||
unwrap:= :(unexp: std::unexpected<int>) -> _ = { | ||
return unexp.error(); | ||
}; | ||
|
||
std::cout | ||
<< "\n" << msg << "\n ..." | ||
<< inspect x -> std::string { | ||
is int = "integer " + std::to_string(x as int); | ||
is std::unexpected<int> = "unexpected<int> " + std::to_string(unwrap(x as std::unexpected<int>)); | ||
is std::string = "string " + x as std::string; | ||
is _ = " no match"; | ||
} | ||
<< "\n"; | ||
} |
67 changes: 67 additions & 0 deletions
67
regression-tests/test-results/msvc-2022-c++20/pure2-expected-is-as.cpp.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
pure2-expected-is-as.cpp | ||
pure2-expected-is-as.cpp2(7): error C2039: 'expected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(7): error C2062: type 'int' unexpected | ||
pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '{' | ||
pure2-expected-is-as.cpp2(7): error C2143: syntax error: missing ';' before '}' | ||
pure2-expected-is-as.cpp2(8): error C2039: 'expected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(8): error C2062: type 'int' unexpected | ||
pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '{' | ||
pure2-expected-is-as.cpp2(8): error C2039: 'unexpected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(8): error C2660: 'unexpected': function does not take 1 arguments | ||
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\eh.h(33): note: see declaration of 'unexpected' | ||
pure2-expected-is-as.cpp2(8): note: while trying to match the argument list '(int)' | ||
pure2-expected-is-as.cpp2(8): error C2143: syntax error: missing ';' before '}' | ||
pure2-expected-is-as.cpp2(9): error C2039: 'expected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(9): error C2275: 'std::string': expected an expression instead of a type | ||
pure2-expected-is-as.cpp2(9): error C2065: 'ex3': undeclared identifier | ||
pure2-expected-is-as.cpp2(9): error C2275: 'size_t': expected an expression instead of a type | ||
pure2-expected-is-as.cpp2(11): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(15): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(20): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(25): error C2039: 'unexpected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(25): error C2062: type 'int' unexpected | ||
pure2-expected-is-as.cpp2(25): error C2059: syntax error: '>' | ||
pure2-expected-is-as.cpp2(25): error C2143: syntax error: missing ';' before '{' | ||
pure2-expected-is-as.cpp2(30): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(34): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(39): error C2065: 'ex1': undeclared identifier | ||
pure2-expected-is-as.cpp2(39): error C2119: 'val1': the type for 'auto' cannot be deduced from an empty initializer | ||
pure2-expected-is-as.cpp2(42): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(47): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(52): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(57): error C2039: 'unexpected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(57): error C2062: type 'int' unexpected | ||
pure2-expected-is-as.cpp2(57): error C2059: syntax error: '>' | ||
pure2-expected-is-as.cpp2(57): error C2143: syntax error: missing ';' before '{' | ||
pure2-expected-is-as.cpp2(58): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(61): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(62): error C2065: 'ex2': undeclared identifier | ||
pure2-expected-is-as.cpp2(65): error C2039: 'unexpected': is not a member of 'std' | ||
predefined C++ types (compiler internal)(346): note: see declaration of 'std' | ||
pure2-expected-is-as.cpp2(65): error C2062: type 'int' unexpected | ||
pure2-expected-is-as.cpp2(65): error C2062: type 'unknown-type' unexpected | ||
pure2-expected-is-as.cpp2(65): error C2143: syntax error: missing ';' before '}' | ||
pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '<<' | ||
pure2-expected-is-as.cpp2(66): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int | ||
pure2-expected-is-as.cpp2(66): error C2371: 'std::cout': redefinition; different basic types | ||
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\include\iostream(39): note: see declaration of 'std::cout' | ||
pure2-expected-is-as.cpp2(66): error C2059: syntax error: '<<' | ||
pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ';' before '{' | ||
pure2-expected-is-as.cpp2(66): error C2447: '{': missing function header (old-style formal list?) | ||
pure2-expected-is-as.cpp2(66): error C2059: syntax error: '||' | ||
pure2-expected-is-as.cpp2(66): error C2065: 'Obj': undeclared identifier | ||
pure2-expected-is-as.cpp2(66): error C2065: 'Params': undeclared identifier | ||
pure2-expected-is-as.cpp2(66): error C2059: syntax error: '}' | ||
pure2-expected-is-as.cpp2(66): error C2143: syntax error: missing ')' before ';' | ||
pure2-expected-is-as.cpp2(66): error C2059: syntax error: 'requires' | ||
pure2-expected-is-as.cpp2(66): error C2059: syntax error: ')' | ||
pure2-expected-is-as.cpp2(66): error C2065: 'obj': undeclared identifier | ||
pure2-expected-is-as.cpp2(66): error C3553: decltype expects an expression not a type | ||
pure2-expected-is-as.cpp2(66): error C2065: 'params': undeclared identifier | ||
pure2-expected-is-as.cpp2(66): fatal error C1003: error count exceeds 100; stopping compilation |
15 changes: 15 additions & 0 deletions
15
regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.execution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ex1 is int | ||
ex1 is 123 | ||
ex1 as int = 123 | ||
ex2 is unexpected<int> and error is: -1 | ||
ex2 is 'empty' aka unexpected<int> and error is: -1 | ||
ex2 as std::unexpected<int> and error = -1 | ||
|
||
expected<int, int> with value | ||
...integer 123 | ||
|
||
expected<int, int> with unexpected | ||
...unexpected<int> -1 | ||
|
||
expected<string, size_t> with value | ||
...string Expect the unexpected |
1 change: 1 addition & 0 deletions
1
regression-tests/test-results/msvc-2022-c++latest/pure2-expected-is-as.cpp.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pure2-expected-is-as.cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
|
||
#define CPP2_IMPORT_STD Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
#line 1 "pure2-expected-is-as.cpp2" | ||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-expected-is-as.cpp2" | ||
// `std::expected` requires C++23 so a dedicated test file is needed | ||
// since only MSVC supports it at time of writing, and there's no #ifdef | ||
// or `static if` support in Cpp2 (yet?). | ||
|
||
#line 5 "pure2-expected-is-as.cpp2" | ||
[[nodiscard]] auto main() -> int; | ||
|
||
#line 75 "pure2-expected-is-as.cpp2" | ||
auto test_inspect(auto const& x, auto const& msg) -> void; | ||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-expected-is-as.cpp2" | ||
|
||
#line 5 "pure2-expected-is-as.cpp2" | ||
[[nodiscard]] auto main() -> int{ | ||
|
||
std::expected<int,int> ex1 {123}; | ||
std::expected<int,int> ex2 {std::unexpected(-1)}; | ||
std::expected<std::string,size_t> ex3 {"Expect the unexpected"}; | ||
|
||
if (cpp2::impl::is<int>(ex1)) { | ||
std::cout << "ex1 is int\n"; | ||
} | ||
|
||
if (cpp2::impl::is<bool>(ex1)) { | ||
std::cout << "BUG - ex1 is not a bool\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is<void>(ex1)) { | ||
std::cout << "BUG - ex1 is not 'empty'\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is<std::unexpected<int>>(ex1)) { | ||
std::cout << "BUG - ex1 is not unexpected\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is(ex1, 123)) { | ||
std::cout << "ex1 is 123\n"; | ||
} | ||
|
||
if (cpp2::impl::is(ex1, 100)) { | ||
std::cout << "BUG - ex1's value is not 100\n"; | ||
return -1; | ||
} | ||
|
||
auto val1 {cpp2::impl::as_<int>(ex1)}; | ||
std::cout << "ex1 as int = " << cpp2::move(val1) << "\n"; | ||
|
||
if (cpp2::impl::is<int>(ex2)) { | ||
std::cout << "BUG - ex2 is not an int\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is<bool>(ex2)) { | ||
std::cout << "BUG - ex2 is not a bool\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is(ex2, 123)) { | ||
std::cout << "BUG - ex2 does not have a value\n"; | ||
return -1; | ||
} | ||
|
||
if (cpp2::impl::is<std::unexpected<int>>(ex2)) { | ||
std::cout << "ex2 is unexpected<int> and error is: " << CPP2_UFCS(error)(ex2) << "\n"; | ||
} | ||
|
||
if (cpp2::impl::is<void>(ex2)) { | ||
std::cout << "ex2 is 'empty' aka unexpected<int> and error is: " << CPP2_UFCS(error)(ex2) << "\n"; | ||
} | ||
|
||
auto ex2_err {cpp2::impl::as_<std::unexpected<int>>(ex2)}; | ||
std::cout << "ex2 as std::unexpected<int> and error = " << CPP2_UFCS(error)(cpp2::move(ex2_err)) << "\n"; | ||
|
||
test_inspect(cpp2::move(ex1), "expected<int, int> with value"); | ||
test_inspect(cpp2::move(ex2), "expected<int, int> with unexpected"); | ||
test_inspect(cpp2::move(ex3), "expected<string, size_t> with value"); | ||
|
||
return 0; | ||
} | ||
|
||
#line 75 "pure2-expected-is-as.cpp2" | ||
auto test_inspect(auto const& x, auto const& msg) -> void{ | ||
|
||
auto unwrap {[](cpp2::impl::in<std::unexpected<int>> unexp) -> auto{ | ||
return CPP2_UFCS(error)(unexp); | ||
}}; | ||
|
||
std::cout | ||
<< "\n" << msg << "\n ..." | ||
<< [&] () -> std::string { auto&& _expr = x; | ||
if (cpp2::impl::is<int>(_expr)) { if constexpr( requires{"integer " + std::to_string(cpp2::impl::as<int>(x));} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("integer " + std::to_string(cpp2::impl::as<int>(x)))),std::string> ) return "integer " + std::to_string(cpp2::impl::as<int>(x)); else return std::string{}; else return std::string{}; } | ||
else if (cpp2::impl::is<std::unexpected<int>>(_expr)) { if constexpr( requires{"unexpected<int> " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as<std::unexpected<int>>(x)));} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("unexpected<int> " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as<std::unexpected<int>>(x))))),std::string> ) return "unexpected<int> " + std::to_string(cpp2::move(unwrap)(cpp2::impl::as<std::unexpected<int>>(x))); else return std::string{}; else return std::string{}; } | ||
else if (cpp2::impl::is<std::string>(_expr)) { if constexpr( requires{"string " + cpp2::impl::as<std::string>(x);} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("string " + cpp2::impl::as<std::string>(x))),std::string> ) return "string " + cpp2::impl::as<std::string>(x); else return std::string{}; else return std::string{}; } | ||
else return " no match"; } | ||
() | ||
<< "\n"; | ||
} | ||
|
2 changes: 2 additions & 0 deletions
2
regression-tests/test-results/pure2-expected-is-as.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pure2-expected-is-as.cpp2... ok (all Cpp2, passes safety checks) | ||
|