| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -481,6 +481,10 @@ class out { | |||
| 481 | 481 | // when customizing is/as for std::variant | |
| 482 | 482 | static std::nullptr_t nonesuch = nullptr; | |
| 483 | 483 | ||
| 484 | + // For designating "holds no value" -- used only with is, not as | ||
| 485 | + // TODO: Does this really warrant a new synonym? Perhaps "is void" is enough | ||
| 486 | + using empty = void; | ||
| 487 | + | ||
| 484 | 488 | template< typename C, typename X > | |
| 485 | 489 | auto is( X const& ) -> bool { | |
| 486 | 490 | return false; | |
@@ -510,6 +514,12 @@ auto is( X const* x ) -> bool { | |||
| 510 | 514 | return dynamic_cast<C const&>(x) != nullptr; | |
| 511 | 515 | } | |
| 512 | 516 | ||
| 517 | + template< typename C, typename X > | ||
| 518 | + requires (requires (X x) { *x; X(); } && std::is_same_v<C, empty>) | ||
| 519 | + auto is( X const& x ) -> bool { | ||
| 520 | + return x == X(); | ||
| 521 | + } | ||
| 522 | + | ||
| 513 | 523 | ||
| 514 | 524 | //------------------------------------------------------------------------------------------------------------- | |
| 515 | 525 | // Built-in as (partial) | |
@@ -570,6 +580,7 @@ template<typename... Ts> | |||
| 570 | 580 | constexpr auto operator_is( std::variant<Ts...> const& x ) { | |
| 571 | 581 | return x.index(); | |
| 572 | 582 | } | |
| 583 | + | ||
| 573 | 584 | template<size_t I, typename... Ts> | |
| 574 | 585 | constexpr auto operator_as( std::variant<Ts...> const& x ) -> auto&& { | |
| 575 | 586 | if constexpr (I < std::variant_size_v<std::variant<Ts...>>) { | |
@@ -580,6 +591,10 @@ constexpr auto operator_as( std::variant<Ts...> const& x ) -> auto&& { | |||
| 580 | 591 | } | |
| 581 | 592 | } | |
| 582 | 593 | ||
| 594 | + // A helper for is... | ||
| 595 | + template <class T, class... Ts> | ||
| 596 | + inline constexpr auto is_any = std::disjunction_v<std::is_same<T, Ts>...> {}; | ||
| 597 | + | ||
| 583 | 598 | template<typename T, typename... Ts> | |
| 584 | 599 | auto is( std::variant<Ts...> const& x ) { | |
| 585 | 600 | if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<0>(x)), T >) if (x.index() == 0) return true; | |
@@ -592,6 +607,11 @@ auto is( std::variant<Ts...> const& x ) { | |||
| 592 | 607 | if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<7>(x)), T >) if (x.index() == 7) return true; | |
| 593 | 608 | if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<8>(x)), T >) if (x.index() == 8) return true; | |
| 594 | 609 | if constexpr (std::is_same_v< CPP2_TYPEOF(operator_as<9>(x)), T >) if (x.index() == 9) return true; | |
| 610 | + if constexpr (std::is_same_v< T, empty > ) { | ||
| 611 | + if (x.valueless_by_exception()) return true; | ||
| 612 | + // Need to guard this with is_any otherwise the get_if is illegal | ||
| 613 | + if constexpr (is_any<std::monostate, Ts...>) return std::get_if<std::monostate>(&x) != nullptr; | ||
| 614 | + } | ||
| 595 | 615 | return false; | |
| 596 | 616 | } | |
| 597 | 617 | ||
@@ -615,10 +635,15 @@ auto as( std::variant<Ts...> const& x ) { | |||
| 615 | 635 | // std::any is and as | |
| 616 | 636 | // | |
| 617 | 637 | template<typename T, typename X> | |
| 618 | - requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any>) | ||
| 638 | + requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>) | ||
| 619 | 639 | constexpr auto is( X const& x ) -> bool | |
| 620 | 640 | { return x.type() == typeid(T); } | |
| 621 | 641 | ||
| 642 | + template<typename T, typename X> | ||
| 643 | + requires (std::is_same_v<X,std::any> && std::is_same_v<T,empty>) | ||
| 644 | + constexpr auto is( X const& x ) -> bool | ||
| 645 | + { return !x.has_value(); } | ||
| 646 | + | ||
| 622 | 647 | template<typename T, typename X> | |
| 623 | 648 | requires (!std::is_reference_v<T> && std::is_same_v<X,std::any> && !std::is_same_v<T,std::any>) | |
| 624 | 649 | constexpr auto as( X const& x ) -> T | |
@@ -633,6 +658,11 @@ template<typename T, typename X> | |||
| 633 | 658 | constexpr auto is( X const& x ) -> bool | |
| 634 | 659 | { return x.has_value(); } | |
| 635 | 660 | ||
| 661 | + template<typename T, typename U> | ||
| 662 | + requires std::is_same_v<T,empty> | ||
| 663 | + constexpr auto is( std::optional<U> const& x ) -> bool | ||
| 664 | + { return !x.has_value(); } | ||
| 665 | + | ||
| 636 | 666 | template<typename T, typename X> | |
| 637 | 667 | requires std::is_same_v<X,std::optional<T>> | |
| 638 | 668 | constexpr auto as( X const& x ) -> auto&& | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + | ||
| 2 | + main: () -> int = { | ||
| 3 | + p: std::unique_ptr<int> = (); | ||
| 4 | + i: std::vector<int>::iterator = (); | ||
| 5 | + v: std::variant<std::monostate, int, std::string> = (); | ||
| 6 | + a: std::any = (); | ||
| 7 | + o: std::optional<std::string> = (); | ||
| 8 | + | ||
| 9 | + std::cout << "\nAll these cases satisfy \"VOYDE AND EMPTIE\"\n"; | ||
| 10 | + | ||
| 11 | + test_generic(p); | ||
| 12 | + test_generic(i); | ||
| 13 | + test_generic(v); | ||
| 14 | + test_generic(a); | ||
| 15 | + test_generic(o); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + test_generic: ( x: _ ) = { | ||
| 19 | + std::cout | ||
| 20 | + << "\n" << typeid(x).name() << "\n ..." | ||
| 21 | + << inspect x -> std::string { | ||
| 22 | + is void = " VOYDE AND EMPTIE"; | ||
| 23 | + is _ = " no match"; | ||
| 24 | + } | ||
| 25 | + << "\n"; | ||
| 26 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,39 @@ | |||
| 1 | + // ----- Cpp2 support ----- | ||
| 2 | + #define CPP2_USE_MODULES Yes | ||
| 3 | + #include "cpp2util.h" | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + #line 2 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" | ||
| 7 | + [[nodiscard]] auto main() -> int; | ||
| 8 | + #line 18 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" | ||
| 9 | + auto test_generic(auto const& x) -> void; | ||
| 10 | + | ||
| 11 | + //=== Cpp2 definitions ========================================================== | ||
| 12 | + | ||
| 13 | + #line 1 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" | ||
| 14 | + | ||
| 15 | + [[nodiscard]] auto main() -> int{ | ||
| 16 | + std::unique_ptr<int> p { }; | ||
| 17 | + std::vector<int>::iterator i { }; | ||
| 18 | + std::variant<std::monostate,int,std::string> v { }; | ||
| 19 | + std::any a { }; | ||
| 20 | + std::optional<std::string> o { }; | ||
| 21 | + | ||
| 22 | + std::cout << "\nAll these cases satisfy \"VOYDE AND EMPTIE\"\n"; | ||
| 23 | + | ||
| 24 | + test_generic(p); | ||
| 25 | + test_generic(i); | ||
| 26 | + test_generic(v); | ||
| 27 | + test_generic(a); | ||
| 28 | + test_generic(o); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + auto test_generic(auto const& x) -> void{ | ||
| 32 | + std::cout | ||
| 33 | + << "\n" << typeid(x).name() << "\n ..." | ||
| 34 | + << [&] () -> std::string { auto&& __expr = x; | ||
| 35 | + if (cpp2::is<void>(__expr)) { if constexpr( requires{" VOYDE AND EMPTIE";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(" VOYDE AND EMPTIE"),std::string> ) return " VOYDE AND EMPTIE"; else return std::string{}; else return std::string{}; } | ||
| 36 | + else return " no match"; } | ||
| 37 | + () | ||
| 38 | + << "\n"; | ||
| 39 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + | ||
| 2 | + main: () -> int = { | ||
| 3 | + p: std::unique_ptr<int> = (); | ||
| 4 | + i: std::vector<int>::iterator = (); | ||
| 5 | + v: std::variant<std::monostate, int, std::string> = (); | ||
| 6 | + a: std::any = (); | ||
| 7 | + o: std::optional<std::string> = (); | ||
| 8 | + | ||
| 9 | + std::cout << "\nAll these cases satisfy \"VOYDE AND EMPTIE\"\n"; | ||
| 10 | + | ||
| 11 | + test_generic(p); | ||
| 12 | + test_generic(i); | ||
| 13 | + test_generic(v); | ||
| 14 | + test_generic(a); | ||
| 15 | + test_generic(o); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + test_generic: ( x: _ ) = { | ||
| 19 | + std::cout | ||
| 20 | + << "\n" << typeid(x).name() << "\n ..." | ||
| 21 | + << inspect x -> std::string { | ||
| 22 | + is void = " VOYDE AND EMPTIE"; | ||
| 23 | + is _ = " no match"; | ||
| 24 | + } | ||
| 25 | + << "\n"; | ||
| 26 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2... ok (all Cpp2, passes safety checks) | ||
| 2 | + | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments