Skip to content

Commit

Permalink
Checking in various improvements done in the last few evenings
Browse files Browse the repository at this point in the history
Replace `store_as_base` with generated aggregate bases - better fix for #336, thanks @JohelEGP for the suggestion! This way we also don't need to obfuscate the name anywhere beyond the constructor(s), as the right member object name just enters the class's scope

If the user didn't write a constructor, provide a default constructor

If the user didn't write a 'that' constructor, suppress Cpp1's compiler-generated copying and assignment

Clean up emission of the just-mentioned generated/=deleted constructors, more naturally line up inside the class body following the indentation for other members that the original source code uses

Rename file `load.h` to `io.h` (`file.h` was another candidate), just because it has been bothering me for a year now that except for that one file all the headers were in natural alphabetical order by compilation phase... as of this commit we now have them all in alpha order and phase order: common.h -> io.h -> lex.h -> parse.h -> [*] -> sema.h -> cppfront.h

    [*] coming next here: reflect.h, which will also be in both alpha order and compilation order

Guard `out.construct` with `if constexpr` in case the type is not copy assignable and that path is never requested

Rename `cpp2::error` to `cpp2::error_entry` to quiet a new(? why?) GCC message about shadowing the former name with `parser::error`... I get why the warning is there, but this is a slightly annoying warning to have to satisfy just to compile high-warning-clean on GCC... oh well

Change semantics of emitting `.h2` files: In `-p` pure mode do the existing split of phases 0 and 1 into `.h` and phase 2 into a separate `.hpp`, but in mixed mode put all phases into the `.h`
  • Loading branch information
hsutter committed Apr 14, 2023
1 parent f83ca9b commit 10241cd
Show file tree
Hide file tree
Showing 15 changed files with 389 additions and 260 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
.editorconfig
*.xml
*.sarif
*.bin
63 changes: 27 additions & 36 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -530,8 +530,6 @@ using in =
//
// out<T> For out parameter
//
// store_as_base<T> For member object declared before a base object
//
//-----------------------------------------------------------------------
//
template<typename T>
Expand Down Expand Up @@ -596,13 +594,23 @@ class out {

auto construct(auto&& ...args) -> void {
if (has_t || called_construct()) {
Default.expects( t );
*t = T(CPP2_FORWARD(args)...);
if constexpr (requires { *t = T(CPP2_FORWARD(args)...); }) {
Default.expects( t );
*t = T(CPP2_FORWARD(args)...);
}
else {
Default.expects(!"attempted to copy assign, but copy assignment is not available");
}
}
else {
Default.expects( dt );
if (dt->init) {
dt->value() = T(CPP2_FORWARD(args)...);
if constexpr (requires { *t = T(CPP2_FORWARD(args)...); }) {
dt->value() = T(CPP2_FORWARD(args)...);
}
else {
Default.expects(!"attempted to copy assign, but copy assignment is not available");
}
}
else {
dt->construct(CPP2_FORWARD(args)...);
Expand All @@ -613,16 +621,26 @@ class out {

auto construct_list(auto&& ...args) -> void {
if (has_t || called_construct()) {
Default.expects( t );
*t = T{CPP2_FORWARD(args)...};
if constexpr (requires { *t = T{CPP2_FORWARD(args)...}; }) {
Default.expects( t );
*t = T{CPP2_FORWARD(args)...};
}
else {
Default.expects(!"attempted to copy assign, but copy assignment is not available");
}
}
else {
Default.expects( dt );
if (dt->init) {
dt->value() = T{CPP2_FORWARD(args)...};
if constexpr (requires { *t = T{CPP2_FORWARD(args)...}; }) {
dt->value() = T{CPP2_FORWARD(args)...};
}
else {
Default.expects(!"attempted to copy assign, but copy assignment is not available");
}
}
else {
dt->construct_list(CPP2_FORWARD(args)...);
dt->construct(CPP2_FORWARD(args)...);
called_construct() = true;
}
}
Expand All @@ -641,33 +659,6 @@ class out {
};


template<String Name, typename T>
class store_as_base
{
T value;

public:
store_as_base()
requires requires { T{ }; }
: value{ } { }

store_as_base( T const& t )
requires requires { T{t}; }
: value{t} { }

store_as_base( T && t )
requires requires { T{std::move(t)}; }
: value{std::move(t)} { }

store_as_base( auto && args )
requires requires { T{CPP2_FORWARD(args)}; }
: value{CPP2_FORWARD(args)} { }

auto value__() -> T & { return value; }
auto value__() const -> T const& { return value; }
};


//-----------------------------------------------------------------------
//
// CPP2_UFCS: Variadic macro generating a variadic lamba, oh my...
Expand Down
1 change: 0 additions & 1 deletion regression-tests/pure2-types-inheritance.cpp2
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

Human: type = {
operator=: (out this) = {}
speak: (virtual this);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Microsoft (R) C/C++ Optimizing Compiler Version 19.35.32215 for x86
Microsoft (R) C/C++ Optimizing Compiler Version 19.35.32217.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

4 changes: 4 additions & 0 deletions regression-tests/test-results/pure2-requires-clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ template<typename T, typename U>
&& std::is_same_v<U,int> )
class X {
public: X();

public: X(X const&) = delete;
public: auto operator=(X const&) -> void = delete;
#line 8 "pure2-requires-clauses.cpp2"
};

template<typename T, typename U> [[nodiscard]] auto f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ class myclass {
public: using str = std::string;

private: using str2 = std::string;
public: myclass() = default; myclass(myclass const&) = delete; auto operator=(myclass const&) -> void = delete; };

public: myclass() = default;
public: myclass(myclass const&) = delete;
public: auto operator=(myclass const&) -> void = delete;
#line 13 "pure2-type-and-namespace-aliases.cpp2"
};

namespace N3 = ::std::literals;

Expand Down
10 changes: 9 additions & 1 deletion regression-tests/test-results/pure2-types-basics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,21 @@ class myclass {

public: class nested {
public: static auto g() -> void;
public: nested() = default; nested(nested const&) = delete; auto operator=(nested const&) -> void = delete; };

public: nested() = default;
public: nested(nested const&) = delete;
public: auto operator=(nested const&) -> void = delete;
#line 51 "pure2-types-basics.cpp2"
};

public: template<typename T, typename U> [[nodiscard]] static auto f1(T const& t, U const& u) -> auto;
public: template<typename T, typename U> [[nodiscard]] static auto f2(T const& t, U const& u) -> auto;
public: template<auto T, auto U> [[nodiscard]] static auto f3() -> auto;
public: template<cpp2::i8 T, cpp2::i16 U> [[nodiscard]] static auto f4() -> auto;

public: myclass(myclass const&) = delete;
public: auto operator=(myclass const&) -> void = delete;
#line 58 "pure2-types-basics.cpp2"
};

}
Expand Down
65 changes: 38 additions & 27 deletions regression-tests/test-results/pure2-types-inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
#line 2 "pure2-types-inheritance.cpp2"
class Human;

#line 7 "pure2-types-inheritance.cpp2"
#line 6 "pure2-types-inheritance.cpp2"
namespace N {
template<int I> class Machine;

#line 12 "pure2-types-inheritance.cpp2"
#line 11 "pure2-types-inheritance.cpp2"
}

class Cyborg;
Expand All @@ -24,84 +24,95 @@ class Cyborg;

#line 2 "pure2-types-inheritance.cpp2"
class Human {
public: Human();
public: virtual auto speak() const -> void = 0;

public: Human() = default;
public: Human(Human const&) = delete;
public: auto operator=(Human const&) -> void = delete;
#line 4 "pure2-types-inheritance.cpp2"
};

namespace N {
template<int I> class Machine {
public: explicit Machine(cpp2::in<std::string> id);
public: virtual auto work() const -> void = 0;

public: Machine(Machine const&) = delete;
public: auto operator=(Machine const&) -> void = delete;
#line 10 "pure2-types-inheritance.cpp2"
};
}

class Cyborg: private cpp2::store_as_base<"name",std::string>, public Human, private cpp2::store_as_base<"address",std::string>, public N::Machine<99> {
struct Cyborg_name_as_base { std::string name; };
struct Cyborg_address_as_base { std::string address; };
#line 13 "pure2-types-inheritance.cpp2"
class Cyborg: public Cyborg_name_as_base, public Human, public Cyborg_address_as_base, public N::Machine<99> {

#line 20 "pure2-types-inheritance.cpp2"
#line 19 "pure2-types-inheritance.cpp2"
public: explicit Cyborg(cpp2::in<std::string> n);

#line 26 "pure2-types-inheritance.cpp2"
#line 25 "pure2-types-inheritance.cpp2"
public: auto speak() const -> void override;

#line 29 "pure2-types-inheritance.cpp2"
#line 28 "pure2-types-inheritance.cpp2"
public: auto work() const -> void override;

#line 32 "pure2-types-inheritance.cpp2"
#line 31 "pure2-types-inheritance.cpp2"
public: auto print() const -> void;

#line 35 "pure2-types-inheritance.cpp2"
#line 34 "pure2-types-inheritance.cpp2"
public: ~Cyborg();

public: Cyborg(Cyborg const&) = delete;
public: auto operator=(Cyborg const&) -> void = delete;
#line 36 "pure2-types-inheritance.cpp2"
};

auto make_speak(cpp2::in<Human> h) -> void;

#line 44 "pure2-types-inheritance.cpp2"
#line 43 "pure2-types-inheritance.cpp2"
auto do_work(cpp2::in<N::Machine<99>> m) -> void;

#line 49 "pure2-types-inheritance.cpp2"
#line 48 "pure2-types-inheritance.cpp2"
auto main() -> int;

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


#line 3 "pure2-types-inheritance.cpp2"
Human::Human(){}

#line 7 "pure2-types-inheritance.cpp2"
#line 6 "pure2-types-inheritance.cpp2"
namespace N {

template <int I> Machine<I>::Machine(cpp2::in<std::string> id){}

#line 12 "pure2-types-inheritance.cpp2"
#line 11 "pure2-types-inheritance.cpp2"
}

#line 20 "pure2-types-inheritance.cpp2"
#line 19 "pure2-types-inheritance.cpp2"
Cyborg::Cyborg(cpp2::in<std::string> n)
: cpp2::store_as_base<"name",std::string>{ n }
: Cyborg_name_as_base{ n }
, Human{ }
, cpp2::store_as_base<"address",std::string>{ "123 Main St." }
, Cyborg_address_as_base{ "123 Main St." }
, N::Machine<99>{ "Acme Corp. engineer tech" }
#line 20 "pure2-types-inheritance.cpp2"
#line 19 "pure2-types-inheritance.cpp2"
{

#line 23 "pure2-types-inheritance.cpp2"
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " checks in for the day's shift\n";
#line 22 "pure2-types-inheritance.cpp2"
std::cout << cpp2::to_string(name) + " checks in for the day's shift\n";
}

auto Cyborg::speak() const -> void {
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " cracks a few jokes with a coworker\n"; }
std::cout << cpp2::to_string(name) + " cracks a few jokes with a coworker\n"; }

auto Cyborg::work() const -> void {
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " carries some half-tonne crates of Fe2O3 to cold storage\n"; }
std::cout << cpp2::to_string(name) + " carries some half-tonne crates of Fe2O3 to cold storage\n"; }

auto Cyborg::print() const -> void {
std::cout << "printing: " + cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " lives at " + cpp2::to_string(cpp2::store_as_base<"address",std::string>::value__()) + "\n"; }
std::cout << "printing: " + cpp2::to_string(name) + " lives at " + cpp2::to_string(address) + "\n"; }

Cyborg::~Cyborg() {
std::cout << "Tired but satisfied after another successful day, " + cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " checks out and goes home to their family\n"; }
std::cout << "Tired but satisfied after another successful day, " + cpp2::to_string(name) + " checks out and goes home to their family\n"; }

#line 39 "pure2-types-inheritance.cpp2"
#line 38 "pure2-types-inheritance.cpp2"
auto make_speak(cpp2::in<Human> h) -> void{
std::cout << "-> [vcall: make_speak] ";
CPP2_UFCS_0(speak, h);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class X {
// X::exx member function description here
public: auto exx(cpp2::in<int> count) const -> void;

public: X(X const&) = delete;
public: auto operator=(X const&) -> void = delete;
#line 42 "pure2-types-order-independence-and-nesting.cpp2"
};

Expand All @@ -61,6 +63,9 @@ class Y {

public: auto why(cpp2::in<int> count) const -> void;

public: Y(Y const&) = delete;
public: auto operator=(Y const&) -> void = delete;
#line 53 "pure2-types-order-independence-and-nesting.cpp2"
};

namespace M {
Expand All @@ -69,8 +74,18 @@ namespace M {
template<typename T, typename U> class A {
public: template<int I> class B {
public: template<typename V, int J, typename W> static auto f(W const& w) -> void;
public: B() = default; B(B const&) = delete; auto operator=(B const&) -> void = delete; };
public: A() = default; A(A const&) = delete; auto operator=(A const&) -> void = delete; };

public: B() = default;
public: B(B const&) = delete;
public: auto operator=(B const&) -> void = delete;
#line 61 "pure2-types-order-independence-and-nesting.cpp2"
};

public: A() = default;
public: A(A const&) = delete;
public: auto operator=(A const&) -> void = delete;
#line 62 "pure2-types-order-independence-and-nesting.cpp2"
};

}

Expand Down
6 changes: 3 additions & 3 deletions source/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,14 @@ struct multiline_raw_string
//
//-----------------------------------------------------------------------
//
struct error
struct error_entry
{
source_position where;
std::string msg;
bool internal = false;
bool fallback = false; // only emit this message if there was nothing better

error(
error_entry(
source_position w,
std::string const& m,
bool i = false,
Expand All @@ -269,7 +269,7 @@ struct error
, fallback{f}
{ }

auto operator==(error const& that)
auto operator==(error_entry const& that)
-> bool
{
return
Expand Down
Loading

3 comments on commit 10241cd

@JohelEGP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as of this commit we now have them all in alpha order and phase order: common.h -> io.h -> lex.h -> parse.h -> [*] -> sema.h -> cppfront.h

That's not really true for cppfront.cpp.
Out of the available letters STUVWXYZ,
the part that lowers to Cpp1 could be moved to transform.h.

@JohelEGP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or to_cpp1.h for clarity.

@hsutter
Copy link
Owner Author

@hsutter hsutter commented on 10241cd Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the good name. That's reasonable, done: 99686e9

Please sign in to comment.