Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2102,10 +2102,8 @@ constexpr auto is( X const& x ) -> bool {
if (!x.has_value()) {
return std::same_as<T, empty>;
}
if constexpr (requires { static_cast<const T&>(*x);}) {
return true;
}
return false;
return std::same_as<T, typename X::value_type>
|| std::derived_from<std::remove_pointer_t<typename X::value_type>, std::remove_pointer_t<T>>;
}

// is Value
Expand Down
32 changes: 32 additions & 0 deletions regression-tests/pure2-type-safety-1.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ main: () -> int =
test_generic(v, "variant<int, int, double>");
test_generic(a, "any");
test_generic(o, "optional<int>");

oi: std::optional<int> = 5;
std::cout << "optional<int> is: ";
test_1365(oi);
od: std::optional<*D> = nullptr;
std::cout << "\noptional<*D> is: ";
test_1365(od);
std::cout << "\n";
}

test_generic: ( x, msg ) = {
Expand All @@ -28,6 +36,30 @@ test_generic: ( x, msg ) = {
::print( msgx + " is int? ", x is int );
}

B: type = { }
D: type = { this: B; }

test_1365: (o) = {
if o is int {
std::cout << "int ";
}
if o is bool {
std::cout << "bool ";
}
if o is float {
std::cout << "float ";
}
if o is *B {
std::cout << "*B ";
}
if o is *D {
std::cout << "*D ";
}
if o is std::string {
std::cout << "std::string ";
}
}

print: ( msg: std::string, b: bool ) = {
bmsg: * const char;
if b { bmsg = "true"; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
variant<int, int, double> is int? true
any is int? true
optional<int> is int? true
optional<int> is: int
optional<*D> is: *B *D
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
variant<int, int, double> is int? true
any is int? true
optional<int> is int? true
optional<int> is: int
optional<*D> is: *B *D
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
variant<int, int, double> is int? true
any is int? true
optional<int> is int? true
optional<int> is: int
optional<*D> is: *B *D
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
variant<int, int, double> is int? true
any is int? true
optional<int> is int? true
optional<int> is: int
optional<*D> is: *B *D
60 changes: 55 additions & 5 deletions regression-tests/test-results/pure2-type-safety-1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

#line 1 "pure2-type-safety-1.cpp2"

#line 39 "pure2-type-safety-1.cpp2"
class B;
class D;


//=== Cpp2 type definitions and function declarations ===========================

Expand All @@ -16,12 +20,28 @@
#line 2 "pure2-type-safety-1.cpp2"
[[nodiscard]] auto main() -> int;

#line 24 "pure2-type-safety-1.cpp2"
#line 32 "pure2-type-safety-1.cpp2"
auto test_generic(auto const& x, auto const& msg) -> void;

#line 31 "pure2-type-safety-1.cpp2"
#line 39 "pure2-type-safety-1.cpp2"
class B {
public: B() = default;
public: B(B const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(B const&) -> void = delete;
};
#line 40 "pure2-type-safety-1.cpp2"
class D: public B {
public: D() = default;
public: D(D const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(D const&) -> void = delete;
};
#line 41 "pure2-type-safety-1.cpp2"

auto test_1365(auto const& o) -> void;

#line 63 "pure2-type-safety-1.cpp2"
auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void;
#line 37 "pure2-type-safety-1.cpp2"
#line 69 "pure2-type-safety-1.cpp2"

#line 1 "pure2-type-safety-1.cpp2"

Expand Down Expand Up @@ -50,17 +70,47 @@ auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void;
test_generic(cpp2::move(v), "variant<int, int, double>");
test_generic(cpp2::move(a), "any");
test_generic(cpp2::move(o), "optional<int>");

std::optional<int> oi {5};
std::cout << "optional<int> is: ";
test_1365(cpp2::move(oi));
std::optional<D*> od {nullptr};
std::cout << "\noptional<*D> is: ";
test_1365(cpp2::move(od));
std::cout << "\n";
}

#line 24 "pure2-type-safety-1.cpp2"
#line 32 "pure2-type-safety-1.cpp2"
auto test_generic(auto const& x, auto const& msg) -> void{
std::string msgx {msg};
// Full qualification is necessary to avoid ambiguity in C++23
// C++23 defines std::print, which would be picked up here by ADL
::print(cpp2::move(msgx) + " is int? ", cpp2::impl::is<int>(x));
}

#line 31 "pure2-type-safety-1.cpp2"
#line 42 "pure2-type-safety-1.cpp2"
auto test_1365(auto const& o) -> void{
if (cpp2::impl::is<int>(o)) {
std::cout << "int ";
}
if (cpp2::impl::is<bool>(o)) {
std::cout << "bool ";
}
if (cpp2::impl::is<float>(o)) {
std::cout << "float ";
}
if (cpp2::impl::is<B*>(o)) {
std::cout << "*B ";
}
if (cpp2::impl::is<D*>(o)) {
std::cout << "*D ";
}
if (cpp2::impl::is<std::string>(o)) {
std::cout << "std::string ";
}
}

#line 63 "pure2-type-safety-1.cpp2"
auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void{
cpp2::impl::deferred_init<char const*> bmsg;
if (b) { bmsg.construct("true");}
Expand Down
2 changes: 1 addition & 1 deletion regression-tests/test-results/version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

cppfront compiler v0.8.1 Build A206:0852
cppfront compiler v0.8.1 Build 10202:1808
SPDX-License-Identifier Apache-2.0 WITH LLVM-exception
Copyright (c) 2022-2024 Herb Sutter
Loading