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
35 changes: 20 additions & 15 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1635,39 +1635,44 @@ constexpr auto is( X&& ) {
// Types
//
template< typename C, typename X >
auto is( X const& x ) -> bool {
constexpr auto is( X const& x ) -> auto {
if constexpr (
std::is_same_v<C, X>
|| std::is_base_of_v<C, X>
)
{
return true;
return std::true_type{};
}
else if constexpr (
std::is_base_of_v<X, C>
|| (
std::is_polymorphic_v<C>
&& std::is_polymorphic_v<X>
)
std::is_polymorphic_v<C>
&& std::is_polymorphic_v<X>
)
{
if constexpr (std::is_pointer_v<X>) {
return Dynamic_cast<C const*>(x) != nullptr;
}
else {
return Dynamic_cast<C const*>(&x) != nullptr;
}
return Dynamic_cast<C const*>(&x) != nullptr;
}
else if constexpr (
requires { *x; X(); }
(
std::is_same_v<X, std::nullptr_t>
|| requires { *x; X(); }
)
&& std::is_same_v<C, empty>
)
{
return x == X();
}
else {
else if constexpr (
std::is_pointer_v<C>
&& std::is_pointer_v<X>
)
{
if (x != nullptr) {
return bool{is<std::remove_pointer_t<C>>(*x)};
}
return false;
}
else {
return std::false_type{};
}
}


Expand Down
3 changes: 2 additions & 1 deletion regression-tests/mixed-type-safety-1.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class Square : public Shape { };

//--- printing helpers -----------------

print: ( msg: std::string, x: _ ) =
print: <T : type> ( msg: std::string, x: T )
requires !std::convertible_to<T, bool> =
std::cout << msg << x << "\n";

print: ( msg: std::string, b: bool ) =
Expand Down
45 changes: 45 additions & 0 deletions regression-tests/pure2-is-with-polymorphic-types.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
A: type = {}

VA: @polymorphic_base <I:int> type = {}

VC: type = {
this: VA<0>;
this: VA<1>;
}

VD: type = {
this: VA<0>;
}

fun: (v, name) = {
std::cout << "(name)$ is";
if v is VC { std::cout << " VC"; }
if v is VA<0> { std::cout << " VA<0>"; }
if v is VA<1> { std::cout << " VA<1>"; }
if v is VD { std::cout << " VD"; }
if v is *VC { std::cout << " *VC"; }
if v is *VA<0> { std::cout << " *VA<0>"; }
if v is *VA<1> { std::cout << " *VA<1>"; }
if v is *VD { std::cout << " *VD"; }
if v is void { std::cout << " empty"; }
if v is A { std::cout << " A"; }
std::cout << std::endl;
}

main: () = {

vc : VC = ();
p0 : *VA<0> = vc&;
p1 : *VA<1> = vc&;

fun(vc, "vc");
fun(p0*, "p0*");
fun(p1*, "p1*");

fun(vc&, "vc&");
fun(p0, "p0");
fun(p1, "p1");

fun(nullptr, "nullptr");
fun(A(), "A");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
16 changes: 10 additions & 6 deletions regression-tests/test-results/mixed-type-safety-1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ class Square : public Shape { };
//--- printing helpers -----------------

#line 13 "mixed-type-safety-1.cpp2"
auto print(cpp2::impl::in<std::string> msg, auto const& x) -> void;
template<typename T> auto print(cpp2::impl::in<std::string> msg, T const& x) -> void
CPP2_REQUIRES (!(std::convertible_to<T,bool>)) ;

#line 16 "mixed-type-safety-1.cpp2"
#line 17 "mixed-type-safety-1.cpp2"
auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void;

#line 24 "mixed-type-safety-1.cpp2"
#line 25 "mixed-type-safety-1.cpp2"
//--- examples -------------------------

[[nodiscard]] auto main() -> int;
Expand All @@ -39,10 +40,13 @@ auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void;
#line 1 "mixed-type-safety-1.cpp2"

#line 13 "mixed-type-safety-1.cpp2"
auto print(cpp2::impl::in<std::string> msg, auto const& x) -> void {
template<typename T> auto print(cpp2::impl::in<std::string> msg, T const& x) -> void
requires (!(std::convertible_to<T,bool>)) {

#line 15 "mixed-type-safety-1.cpp2"
std::cout << msg << x << "\n"; }

#line 16 "mixed-type-safety-1.cpp2"
#line 17 "mixed-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;
Expand All @@ -51,7 +55,7 @@ auto print(cpp2::impl::in<std::string> msg, cpp2::impl::in<bool> b) -> void
std::cout << msg << cpp2::move(bmsg.value()) << "\n";
}

#line 26 "mixed-type-safety-1.cpp2"
#line 27 "mixed-type-safety-1.cpp2"
[[nodiscard]] auto main() -> int
{
print("1.1 is int? ", cpp2::impl::is<int>(1.1));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vc is VC VA<0> VA<1>
p0* is VC VA<0> VA<1>
p1* is VC VA<0> VA<1>
vc& is *VC *VA<0> *VA<1>
p0 is *VC *VA<0> *VA<1>
p1 is *VC *VA<0> *VA<1>
nullptr is empty
A is A
104 changes: 104 additions & 0 deletions regression-tests/test-results/pure2-is-with-polymorphic-types.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

#define CPP2_IMPORT_STD Yes

//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"

#line 1 "pure2-is-with-polymorphic-types.cpp2"
class A;
#line 2 "pure2-is-with-polymorphic-types.cpp2"

template<int I> class VA;

class VC;


#line 10 "pure2-is-with-polymorphic-types.cpp2"
class VD;


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

#line 1 "pure2-is-with-polymorphic-types.cpp2"
class A {
public: A() = default;
public: A(A const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(A const&) -> void = delete;
};
#line 2 "pure2-is-with-polymorphic-types.cpp2"

template<int I> class VA {
public: virtual ~VA() noexcept;

public: VA() = default;
public: VA(VA const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(VA const&) -> void = delete;
};
#line 4 "pure2-is-with-polymorphic-types.cpp2"

class VC: public VA<0>, public VA<1> {
public: VC() = default;
public: VC(VC const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(VC const&) -> void = delete;


#line 8 "pure2-is-with-polymorphic-types.cpp2"
};

class VD: public VA<0> {
public: VD() = default;
public: VD(VD const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(VD const&) -> void = delete;


#line 12 "pure2-is-with-polymorphic-types.cpp2"
};

auto fun(auto const& v, auto const& name) -> void;

#line 29 "pure2-is-with-polymorphic-types.cpp2"
auto main() -> int;

//=== Cpp2 function definitions =================================================

#line 1 "pure2-is-with-polymorphic-types.cpp2"


template <int I> VA<I>::~VA() noexcept{}
#line 14 "pure2-is-with-polymorphic-types.cpp2"
auto fun(auto const& v, auto const& name) -> void{
std::cout << "" + cpp2::to_string(name) + " is";
if (cpp2::impl::is<VC>(v)) {std::cout << " VC";}
if (cpp2::impl::is<VA<0>>(v)) {std::cout << " VA<0>";}
if (cpp2::impl::is<VA<1>>(v)) {std::cout << " VA<1>";}
if (cpp2::impl::is<VD>(v)) {std::cout << " VD";}
if (cpp2::impl::is<VC*>(v)) {std::cout << " *VC";}
if (cpp2::impl::is<VA<0>*>(v)) {std::cout << " *VA<0>";}
if (cpp2::impl::is<VA<1>*>(v)) {std::cout << " *VA<1>";}
if (cpp2::impl::is<VD*>(v)) {std::cout << " *VD";}
if (cpp2::impl::is<void>(v)) {std::cout << " empty";}
if (cpp2::impl::is<A>(v)) {std::cout << " A";}
std::cout << std::endl;
}

#line 29 "pure2-is-with-polymorphic-types.cpp2"
auto main() -> int{

VC vc {};
VA<0>* p0 {&vc};
VA<1>* p1 {&vc};

fun(vc, "vc");
fun(*cpp2::impl::assert_not_null(p0), "p0*");
fun(*cpp2::impl::assert_not_null(p1), "p1*");

fun(&vc, "vc&");
fun(cpp2::move(p0), "p0");
fun(cpp2::move(p1), "p1");

fun(nullptr, "nullptr");
fun(A(), "A");
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-is-with-polymorphic-types.cpp2... ok (all Cpp2, passes safety checks)