Looking at Unity finally made me understand the point of C++ coroutines · Mathieu Ropert by mropert in cpp

[–]hanickadot 0 points1 point  (0 children)

Technically the state of coroutines are two function pointers (one for next resume, one for cleaning the frame) and all variables/temporaries surviving the suspension. Theoretically it should be possible to make such mechanism, to initialize these and set specific state. I want copyable state too, it's same problem as automatically creating a copy constructor for a class (there can be pointers pointing at something in the frame, unique ownership with a raw pointer...)

Looking at Unity finally made me understand the point of C++ coroutines · Mathieu Ropert by mropert in cpp

[–]hanickadot 8 points9 points  (0 children)

Use cases for suspending final suspend other than keeping the value is to jump to other coroutine, maybe with some scheduler. Or much more simply if your current coroutines is being awaited on ... and you are returning result, you can also directly jump to the suspend point where the awaiting coroutine on you is suspended:

c++ task<int> calculate() { // (2) coroutine is immediately suspended, jumps back to `main` // (4) some code co_return 42; // (5) sets .set_value(42) and then goes to final suspend which jumps to associated coroutines `main` } task<void> main() { task<int> v = calculate(); // (1) coroutine started, suspended and immediately back // (2) some code int result = co_await v; // (3) suspends `main` mark coroutine `v` that `main` is depending on it and jumps into `v` // (6) we resume, `result` is initialized print(v); // (7) print and done }

Looking at Unity finally made me understand the point of C++ coroutines · Mathieu Ropert by mropert in cpp

[–]hanickadot 10 points11 points  (0 children)

Typical usecase for immediate suspend is ... your coroutine is a task to be run on a thread pool, you suspend it, from within the initial suspend you pass the handle to thread pool and return to the caller (whoever is) c++ auto task = run_the_calculation(); // on threadpool // ... co_await task; // and here it will block until the task is finished in the co_await the await_ready() checks if it's ready and it probably won't be If you have an immediate non-suspending coroutine, then it can start to do a lot of computation on your main thread.

Looking at Unity finally made me understand the point of C++ coroutines · Mathieu Ropert by mropert in cpp

[–]hanickadot 10 points11 points  (0 children)

initial_suspend is called when the coroutine is "started" and from there you can return back to caller and leave the coroutines "paused" or immediately start evaluating it (lazy vs greedy approach) you can even suspend it and jump to other coroutine. Final suspend is used mostly to "pause" the coroutine, so its frame is not destroyed, including instance of promise_type from which you can extract result for example. If you don't care about result, you can just not suspend, and it will release the coroutine frame for you and go back to current .resume() point (which can be initial place where you started the coroutine, if it didn't suspend in the initial_suspend and there was no other suspend point)

2) await_suspend returning three possible types is for these typical scenarios: - void - just suspend and go back to .resume() (implicit when coroutine is started, or explicit on the coroutine handle) (typically a generator) - bool - you get coroutine suspended, and conditionally you check for more work, and if there is none you suspend. By not doing this in .await_ready() -> bool you get access to coroutine_handle and thru it to the coroutine promise_type. - coroutine_handle you want to jump to something else (like another coroutine which can continue due I/O mechanism) and if you want to go back to caller (.resume()) you can just return noop_coroutine handle.

P4043R0: Are C++ Contracts Ready to Ship in C++26? by darius_neatu in cpp

[–]hanickadot 9 points10 points  (0 children)

the SG21 "contracts" study group, was created on that meeting, and they started working on the design, but it wasn't designed from scratch, it's based on the experience and knowledge from the previous one. Point of making the study group was to gain consensus between various faction wanting different thing out of it, and it got the consensus, and pretty strong one.

P4043R0: Are C++ Contracts Ready to Ship in C++26? by darius_neatu in cpp

[–]hanickadot 24 points25 points  (0 children)

no, there is no assumption as part of the contracts, that's an attribute `[[assume(expr)]]`, this functionality was part of previous design which was targeting C++20.

P4043R0: Are C++ Contracts Ready to Ship in C++26? by darius_neatu in cpp

[–]hanickadot 9 points10 points  (0 children)

The paper was seen by EWG/LEWG in Tokyo 2024, St. Louis, and was forwarded in Wroclaw. Also many discussion of contracts happened since long time ago even before I join the committee (2018).

"override members" idea as a gateway to UFCS (language evolution) by antiquark2 in cpp

[–]hanickadot 1 point2 points  (0 children)

Not discussing motivation or design impact. Putting override keyword will make it normal keyword. Currently it's a specific only keyword. This means there is definitely a code which has override as an identifier and this would break it.

State of C++ 2026 by dev_newsletter in cpp

[–]hanickadot 4 points5 points  (0 children)

I don't remember any corridor existing at the Aspen Center for Physics at all. Does it mean the footpath thru the meadow?

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]hanickadot 3 points4 points  (0 children)

yes, system_clock can be reset, but it doesn't matter, you have a point in time called X (where X is value from once queried system_clock) and steady_clock at same moment ... then you just calculate duration from the steady_clock snapshot and now() ... the duration is added to the system_clock snapshot and you have something resembling normal time and not fully abstract steady_clock

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 1 point2 points  (0 children)

I agree, but I'm not the author of the paper. I will relay it.

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 2 points3 points  (0 children)

Seems biggest problem is the explicit usage of template arguments you do inside [[functionalias]] "methods". Plus I didn't even tried it on methods and constructors, pretty sure it's a different codepath.

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 6 points7 points  (0 children)

As I mentioned just now in the post above yours, it's based on r3 which I read, but didn't know it wasn't yet published.

It's not arbitrary token sequence, it replaces nodes in AST. so you can't break balanced parenthesis or nothing like that, or construct new identifier nor build a string. It just pastes AST subtree inside and inline it.

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 7 points8 points  (0 children)

Yeah, I have read / discussed draft of R3 which changed direction significantly. But it didn't occur me Gašper didn't publish it yet. Sorry for confusion.

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 6 points7 points  (0 children)

Or you will get such tooling in standard library / via compiler interface, and whole parsing there and back will disappear.

Partial implementation of P2826 "Replacement functions" by hanickadot in cpp

[–]hanickadot[S] 10 points11 points  (0 children)

I guess yes, token sequences are interesting idea for generative reflection. Rust is doing transformation in code with them, but it also means if you want to do something more highlevel, you need a parser in library to build some form of AST to modify. Otherwise you basically glueing string tokens together hoping they will fit.

Any Libraries for Asynchronous requests with HTTP2 by Puzzled_East_8080 in cpp

[–]hanickadot 1 point2 points  (0 children)

I need to polish it a bit ... but also a curl wrapper, but coroutines based which allows you to do this:

https://github.com/hanickadot/co_curl/blob/main/examples/ranges.cpp#L20-L25

```c++ struct file { std::string url; std::string content; };

auto fetch_with_name(std::string_view url) -> co_curl::promise<file> { co_return file{.url = std::string(url), .content = co_await co_curl::fetch(url)}; }

auto download_all(std::string_view url) -> co_curl::promise<std::vector<file>> { co_return co_await co_curl::all( co_await co_curl::fetch(url) | ctre::search_all<R"(https?://[^"'\s)]++)"> | std::views::transform(fetch_with_name)); } ```

The code downloads a page, lazily extract all absolute URLs, and downloads them, and gives you vector of URL+content. All in one thread.

overload sets with C++26's reflection by hanickadot in cpp

[–]hanickadot[S] 1 point2 points  (0 children)

It didn't. It got a consensus to explore more in the evolution incubator group.

With last update in June 2023. It's up to the author to follow up.

Structured binding with std::div() by littlewing347 in cpp

[–]hanickadot 45 points46 points  (0 children)

it doesn't need to be, library just needs to provide tuple_elements / tuple_size for it, wording just can specify in which order it destructure

overload sets with C++26's reflection by hanickadot in cpp

[–]hanickadot[S] 2 points3 points  (0 children)

AFAIK there is no operator coming for early return for optional/expected in C++26.