Skip to content

Commit cf6cb03

Browse files
authored
Merge branch 'main' into function_expression_as_index
Signed-off-by: Johel Ernesto Guerrero Peña <[email protected]>
2 parents 6ac6dca + 52a2798 commit cf6cb03

File tree

221 files changed

+1105
-501
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

221 files changed

+1105
-501
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ Finally, here is a roadmap diagram I made in 2016 that is still recognizably a r
196196

197197
![image](https://user-images.githubusercontent.com/1801526/189503047-0b0a4f0f-c5e7-42b2-a17d-37d80bef3970.png)
198198

199-
I haven't updated this roadmap diagram since 2016, but it shows many of the talks and papers that have come since then from this work, and it's still a pretty up-to-date roadmap of the major parts of Cpp2. As of this writing, cppfront implements much of the top part of this roadmap, and I plan for more to follow.
199+
I haven't updated this roadmap diagram since 2016, but it shows many of the talks and papers that have come since then from this work, and it's still a pretty up-to-date roadmap of the major parts of Cpp2. As of spring 2023, cppfront implements most of this roadmap.
200200

201201
I hope you enjoy reading about this personal experiment, and I hope that it might at least start a conversation about what could be possible _**within C++**_'s own evolution to make C++ 10x simpler, safer, and more toolable.
202202

include/cpp2util.h

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
#include <type_traits>
202202
#include <new>
203203
#include <memory>
204+
#include <tuple>
204205
#include <string>
205206
#include <string_view>
206207
#include <vector>
@@ -216,6 +217,7 @@
216217
#include <compare>
217218
#include <iterator>
218219
#include <concepts>
220+
#include <system_error>
219221

220222
#ifndef CPP2_NO_EXCEPTIONS
221223
#include <exception>
@@ -324,8 +326,8 @@ class contract_group {
324326
using handler = void (*)(CPP2_MESSAGE_PARAM msg CPP2_SOURCE_LOCATION_PARAM);
325327

326328
constexpr contract_group (handler h = {}) : reporter(h) { }
327-
constexpr auto set_handler(handler h) -> handler;
328-
constexpr auto get_handler() const -> handler { return reporter; }
329+
constexpr auto set_handler(handler h);
330+
constexpr auto get_handler() const -> handler { return reporter; }
329331
constexpr auto expects (bool b, CPP2_MESSAGE_PARAM msg = "" CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT)
330332
-> void { if (!b) reporter(msg CPP2_SOURCE_LOCATION_ARG); }
331333
private:
@@ -373,11 +375,9 @@ auto inline Testing = contract_group(
373375
}
374376
);
375377

376-
constexpr auto contract_group::set_handler(handler h) -> handler {
378+
constexpr auto contract_group::set_handler(handler h) {
377379
Default.expects(h);
378-
auto old = reporter;
379380
reporter = h;
380-
return old;
381381
}
382382

383383

@@ -681,19 +681,37 @@ class out {
681681
//
682682
//-----------------------------------------------------------------------
683683
//
684-
#ifdef _MSC_VER
684+
#if defined(_MSC_VER) && !defined(__clang_major__)
685685
#define CPP2_FORCE_INLINE __forceinline
686686
#define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]]
687+
#define CPP2_LAMBDA_NO_DISCARD
687688
#else
688689
#define CPP2_FORCE_INLINE __attribute__((always_inline))
689690
#define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline))
691+
692+
#if defined(__clang_major__)
693+
// Also check __cplusplus, only to satisfy Clang -pedantic-errors
694+
#if __cplusplus >= 202302L && (__clang_major__ > 13 || (__clang_major__ == 13 && __clang_minor__ >= 2))
695+
#define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
696+
#else
697+
#define CPP2_LAMBDA_NO_DISCARD
698+
#endif
699+
#elif defined(__GNUC__)
700+
#if __GNUC__ >= 9
701+
#define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
702+
#else
703+
#define CPP2_LAMBDA_NO_DISCARD
704+
#endif
705+
#else
706+
#define CPP2_LAMBDA_NO_DISCARD
707+
#endif
690708
#endif
691709

692710

693711
// Note: [&] is because a nested UFCS might be viewed as trying to capture 'this'
694712

695713
#define CPP2_UFCS(FUNCNAME,PARAM1,...) \
696-
[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
714+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
697715
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \
698716
return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
699717
} else { \
@@ -702,7 +720,7 @@ class out {
702720
}(PARAM1, __VA_ARGS__)
703721

704722
#define CPP2_UFCS_0(FUNCNAME,PARAM1) \
705-
[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
723+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
706724
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
707725
return CPP2_FORWARD(obj).FUNCNAME(); \
708726
} else { \
@@ -713,7 +731,7 @@ class out {
713731
#define CPP2_UFCS_REMPARENS(...) __VA_ARGS__
714732

715733
#define CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) \
716-
[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
734+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
717735
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \
718736
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \
719737
} else { \
@@ -722,7 +740,7 @@ class out {
722740
}(PARAM1, __VA_ARGS__)
723741

724742
#define CPP2_UFCS_TEMPLATE_0(FUNCNAME,TEMPARGS,PARAM1) \
725-
[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
743+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
726744
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
727745
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
728746
} else { \
@@ -734,7 +752,7 @@ class out {
734752
// But for non-local lambdas [&] is not allowed
735753

736754
#define CPP2_UFCS_NONLOCAL(FUNCNAME,PARAM1,...) \
737-
[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
755+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
738756
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \
739757
return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
740758
} else { \
@@ -743,7 +761,7 @@ class out {
743761
}(PARAM1, __VA_ARGS__)
744762

745763
#define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
746-
[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
764+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
747765
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
748766
return CPP2_FORWARD(obj).FUNCNAME(); \
749767
} else { \
@@ -752,7 +770,7 @@ class out {
752770
}(PARAM1)
753771

754772
#define CPP2_UFCS_TEMPLATE_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1,...) \
755-
[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
773+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
756774
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \
757775
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \
758776
} else { \
@@ -761,7 +779,7 @@ class out {
761779
}(PARAM1, __VA_ARGS__)
762780

763781
#define CPP2_UFCS_TEMPLATE_0_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1) \
764-
[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
782+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
765783
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
766784
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
767785
} else { \
@@ -1334,82 +1352,67 @@ constexpr auto as( X const& x ) -> decltype(auto)
13341352

13351353
//-----------------------------------------------------------------------
13361354
//
1337-
// A variation of GSL's final_action_success and finally to run only on success
1338-
// (based on a PR I contributed to Microsoft GSL)
1355+
// A variation of GSL's final_action_success / finally
13391356
//
1340-
// final_action_success ensures something is run at the end of a scope
1341-
// if no exception is thrown
1357+
// finally ensures something is run at the end of a scope always
13421358
//
1343-
// finally_success is a convenience function to make a final_action_success_success
1359+
// finally_success ensures something is run at the end of a scope
1360+
// if no exception is thrown
13441361
//
13451362
//-----------------------------------------------------------------------
13461363
//
13471364

13481365
template <class F>
1349-
class final_action_success
1366+
class finally_success
13501367
{
13511368
public:
1352-
explicit final_action_success(const F& ff) noexcept : f{ff} { }
1353-
explicit final_action_success(F&& ff) noexcept : f{std::move(ff)} { }
1369+
explicit finally_success(const F& ff) noexcept : f{ff} { }
1370+
explicit finally_success(F&& ff) noexcept : f{std::move(ff)} { }
13541371

1355-
~final_action_success() noexcept
1372+
~finally_success() noexcept
13561373
{
13571374
if (invoke && ecount == std::uncaught_exceptions()) {
13581375
f();
13591376
}
13601377
}
13611378

1362-
final_action_success(final_action_success&& that) noexcept
1379+
finally_success(finally_success&& that) noexcept
13631380
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false))
13641381
{ }
13651382

1366-
final_action_success(final_action_success const&) = delete;
1367-
void operator= (final_action_success const&) = delete;
1368-
void operator= (final_action_success&&) = delete;
1383+
finally_success(finally_success const&) = delete;
1384+
void operator= (finally_success const&) = delete;
1385+
void operator= (finally_success&&) = delete;
13691386

13701387
private:
13711388
F f;
13721389
int ecount = std::uncaught_exceptions();
13731390
bool invoke = true;
13741391
};
13751392

1376-
[[nodiscard]] auto finally_success(auto&& f) noexcept
1377-
{
1378-
return final_action_success<CPP2_TYPEOF(f)>{CPP2_FORWARD(f)};
1379-
}
1380-
1381-
1382-
//
1383-
// Same, but clean up also on exceptional paths
1384-
//
13851393

13861394
template <class F>
1387-
class final_action
1395+
class finally
13881396
{
13891397
public:
1390-
explicit final_action(const F& ff) noexcept : f{ff} { }
1391-
explicit final_action(F&& ff) noexcept : f{std::move(ff)} { }
1398+
explicit finally(const F& ff) noexcept : f{ff} { }
1399+
explicit finally(F&& ff) noexcept : f{std::move(ff)} { }
13921400

1393-
~final_action() noexcept { f(); }
1401+
~finally() noexcept { f(); }
13941402

1395-
final_action(final_action&& that) noexcept
1403+
finally(finally&& that) noexcept
13961404
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false))
13971405
{ }
13981406

1399-
final_action (final_action const&) = delete;
1400-
void operator=(final_action const&) = delete;
1401-
void operator=(final_action&&) = delete;
1407+
finally (finally const&) = delete;
1408+
void operator=(finally const&) = delete;
1409+
void operator=(finally&&) = delete;
14021410

14031411
private:
14041412
F f;
14051413
bool invoke = true;
14061414
};
14071415

1408-
[[nodiscard]] auto finally(auto&& f) noexcept
1409-
{
1410-
return final_action<CPP2_TYPEOF(f)>{CPP2_FORWARD(f)};
1411-
}
1412-
14131416

14141417
//-----------------------------------------------------------------------
14151418
//

regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ insert_at: (where: int, val: int)
2020
[[pre: 0 <= where && where <= vec.ssize()]]
2121
[[post: vec.ssize() == vec.ssize()$ + 1]]
2222
= {
23-
vec.insert( vec.begin()+where, val );
23+
_ = vec.insert( vec.begin()+where, val );
2424
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
plus: const std::plus<> = ();
2+
main: () -> int = std::plus<>()(0, 0);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
f: <T> () requires std::regular<T> = g(T());
2+
main: () = { }

regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ main: () -> int = {
88
test_generic(a, "any");
99
test_generic(o, "optional<int>");
1010

11-
v.emplace<0>(1);
11+
_ = v.emplace<0>(1);
1212
a = 2;
1313
o = 3;
1414
test_generic(42, "int");

regression-tests/pure2-stdio-with-raii.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
main: () -> int = {
55
s: std::string = "Freddy";
66
myfile := cpp2::fopen("xyzzy", "w");
7-
myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
7+
_ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
88
}

regression-tests/pure2-stdio.cpp2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
main: () -> int = {
55
s: std::string = "Fred";
66
myfile := fopen("xyzzy", "w");
7-
myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
8-
myfile.fclose();
7+
_ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
8+
_ = myfile.fclose();
99
}
1010

regression-tests/pure2-type-safety-1.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ main: () -> int =
1212

1313
std::cout << "\n";
1414

15-
v.emplace<1>(1);
15+
_ = v.emplace<1>(1);
1616
a = 2;
1717
o = 3;
1818
test_generic(42, "int");

regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ main: () -> int = {
88
test_generic(a, "any");
99
test_generic(o, "optional<int>");
1010

11-
v.emplace<2>(1);
11+
_ = v.emplace<2>(1);
1212
a = 2;
1313
o = 3;
1414
test_generic(42, "int");

regression-tests/pure2-types-order-independence-and-nesting.cpp2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ X: type = {
3434
// X::exx member function description here
3535
exx: (this, count: int) = {
3636
// Exercise '_' anonymous objects too while we're at it
37-
_ := finally( :()= std::cout << "leaving call to 'why((count)$)'\n"; );
37+
_: finally = :()= std::cout << "leaving call to 'why((count)$)'\n";
3838
if count < 5 {
3939
py*.why( count+1 ); // use Y object from X
4040
}

regression-tests/pure2-ufcs-member-access-and-chaining.cpp2

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
main: () -> int = {
22
i := 42;
3-
i.ufcs();
3+
_ = i.ufcs();
44

55
j := fun();
6-
j.i.ufcs();
6+
_ = j.i.ufcs();
77

8-
fun().i.ufcs();
8+
_ = fun().i.ufcs();
99

1010
k := fun().i;
11-
k.ufcs();
11+
_ = k.ufcs();
1212

13-
get_i(j).ufcs();
13+
_ = get_i(j).ufcs();
1414

15-
get_i(fun()).ufcs();
15+
_ = get_i(fun()).ufcs();
1616

1717
res := (42).ufcs();
1818

19-
(j.i).ufcs();
19+
_ = (j.i).ufcs();
20+
21+
42.no_return();
2022
}
2123

24+
no_return: (x: int) = { }
25+
2226
ufcs: (i:int) -> int = {
2327
return i+2;
2428
}

regression-tests/test-results/apple-clang-14/pure2-cpp1-multitoken-fundamental-types.cpp.execution

Lines changed: 0 additions & 1 deletion
This file was deleted.

regression-tests/test-results/apple-clang-14/pure2-inspect-values.cpp.execution

Lines changed: 0 additions & 10 deletions
This file was deleted.

regression-tests/test-results/clang-12/pure2-cpp1-multitoken-fundamental-types.cpp.execution

Lines changed: 0 additions & 1 deletion
This file was deleted.

regression-tests/test-results/clang-12/pure2-inspect-values.cpp.execution

Lines changed: 0 additions & 10 deletions
This file was deleted.

regression-tests/test-results/gcc-10/gcc-version.output

Lines changed: 0 additions & 5 deletions
This file was deleted.

regression-tests/test-results/gcc-10/pure2-cpp1-multitoken-fundamental-types.cpp.execution

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)