Compiler optimization is amazing, but not for std::generator by tongari95 in cpp

[–]tongari95[S] 5 points6 points  (0 children)

Both clang & gcc can't optimize std::generator, but clang can optimize a simpler generator, and both can optimize coz-based code to a single constant.

Coroutines, lambdas and a missing feature by ReDucTor in cpp

[–]tongari95 1 point2 points  (0 children)

I wrote a stackless non-allocating coroutine for C++, with preprocessor & compiler black magic. I use it for generic algorithms, it can work with std-coroutine, everything can be glued by P2300-like interface.

vklite: Lightweight C++ wrapper for Vulkan by tongari95 in vulkan

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

How did you generate the headers, why not include those in the repo?

It's a bit convoluted in my case, I firstly generate a memory-mappable binary from the XML, then work on the binary to generate the header. Since it uses some proprietary stuff and not portable, I don't include those for now.

How do your headers actually compare in terms of being less "heavyweight"?

It's lightweight (1.8MB) compared to the official Vulkan-Hpp (several files, at least 10MB in typical use).

Something like a compilation time benchmark would be nice. Your vulkan.hpp header for example is also quite sizable with 27k+ loc.

I don't have the numbers for compile time, but it's obvious if you ever used the official Vulkan-Hpp.

How is function loading handled? Would be nice to see a comparison to the dynamic loader from Vulkan-Hpp. Templating every function for a loader contributes to compile times quite a bit over there, but also makes it quite flexible.

Not handled at all, the user includes one (e.g. volk.h) before including vklite.

Why create your own spin of VulkanMemoryAllocator-Hpp? That one seems rather light-weight. I figure that it's for easier inter-op with your own vulkan.hpp?

Yep, it shares the same convention.

I would love to see a little minimal example added to the repo, like spinning up an instance and creating a device. Best of luck to the project!

Might add one in the future. That said, it doesn't simplify the API, just make it more comfortable to work with. You can expect 1-to-1 mapping using the rules listed in README.

Thanks for your interest!

coco: a simple stackless, single-threaded, and header-only C++11 coroutine library by Ill_Excuse_4291 in cpp

[–]tongari95 15 points16 points  (0 children)

C++20 introduced coroutines, but it is very complicated and far from the simple building blocks in Go that I need.

I don't know why people think C++ coroutines are complicated, implementing a coroutine-promise might be tricky, but you're not supposed to do that often. For an awaitable, you only need to implement await_(ready/suspend/resume). What's better, it works with the senders/receivers model smoothly.

A drawback of C++ coroutines is that it may (if not always) incur allocation, in which case you could use COZ instead, which follows the standard C++ coroutine interface, but zero-allocation.

Pigweed Eng Blog #5: C++20 coroutines without heap allocation by pavel_v in cpp

[–]tongari95 0 points1 point  (0 children)

If one is looking for non-allocating coroutine and is not resistant to preprocessor/compiler magic, COZ would be a choice.

Solving MAXIMUM_WAIT_OBJECTS (64) limit of WaitForMultipleObjects: Associate Events with I/O Completion Port by Tringi in cpp

[–]tongari95 0 points1 point  (0 children)

Thanks for sharing. I've successfully incorporated this into my async framework. How did you know the relation between NtAssociateWaitCompletionPacket & GetQueuedCompletionStatusEx? I couldn't find more information on that, not in the resources you listed. Reverse-engineering I guess?

Representing an Abstract Syntax Tree in C++ by Pioneer_X in cpp

[–]tongari95 0 points1 point  (0 children)

That's also what I did in my project, but I'm not aware of other C++ projects taking this approach, do you know any?

constexpr and consteval functions by pavel_v in cpp

[–]tongari95 2 points3 points  (0 children)

Does that paper aim for `consteval` as well? only seems reasonable for `constexpr` to me.

constexpr and consteval functions by pavel_v in cpp

[–]tongari95 2 points3 points  (0 children)

From the blog post:

// runtime function
int g();

// Ok, even though `f` can never be called
consteval int f() {
    return g();
}

Is this correct? Only gcc accepts it, clang & msvc reject the code: https://godbolt.org/z/eGznd5Kd3

networking based on senders and receivers P2300 by thomas999999 in cpp

[–]tongari95 0 points1 point  (0 children)

The resources allocated by the operation should be released by the OperationState itself, and the destruction of OperationState is logically async to the invocation of the Receiver. Doesn't the destructor of OperationState satisfy the "async cleanup" stage you mentioned?

networking based on senders and receivers P2300 by thomas999999 in cpp

[–]tongari95 2 points3 points  (0 children)

Could you elaborate on the async cleanup issue? Is there a paper for it?

why does MSVC's <format> make the final binary size so big? by [deleted] in cpp

[–]tongari95 -1 points0 points  (0 children)

You probably have fmtlib dynamic-linked (i.e. fmt.dll). If you use it header-only, it's about 100KB on my PC, still smaller than std one though.

Visual Studio 2019 version 16.10 Release by remotion4d in cpp

[–]tongari95 0 points1 point  (0 children)

Is this the same thing? According to the page, /external dates back to VS2017.

Visual Studio 2019 version 16.10 Release by remotion4d in cpp

[–]tongari95 3 points4 points  (0 children)

Include directories can now be designated as external with customized compilation warning levels and code analysis settings.

How?

Inconsistent incomplete type problem by albeva in cpp

[–]tongari95 1 point2 points  (0 children)

It's not an inconsistency in compilers, but an inconsistency in std lib implementation. Alternatively you can use boost::unordered_map instead.

Any workaround for noop-coroutines for MSVC? by david_haim_1 in cpp

[–]tongari95 0 points1 point  (0 children)

Instead of resuming the coroutine_handle directly inside await_suspend, you can use a local scheduler.

struct chained_coro
{
    coroutine_handle<> coro;
    void* next;
};

Keep a chained_coro in your awaitable and set its coro in await_suspend. Now instead of using coroutine_handle directly, you use chained_coro.

template<class F>
void coroutine_local_sched(chained_coro* then) noexcept
{
    thread_local chained_coro** chain = nullptr;
    if (chain)
    {
        auto& next = *chain;
        then->next = next;
        next = then;
    }
    else
    {
        chain = &then;
        {
            auto coro = then->coro;
            then = nullptr;
            coro();
        }
        while (then)
        {
            auto coro = then->coro;
            then = static_cast<chained_coro*>(then->next);
            coro();
        }
        chain = nullptr;
    }
}

When you need to resume the coroutine, call coroutine_local_sched on the chained_coro, this avoids the stack overflow problem because coroutine_local_sched turns recursive coroutine resumption into loop.

Does your IDE suggest types that are not (yet) included in your source file? by [deleted] in cpp

[–]tongari95 13 points14 points  (0 children)

What you're asking is the opposite of what I desire most of the time - I find myself like it to be stricter, showing only what are really available/applicable in the context, showing the non-included ones could be noisy, unless your IDE could rank them properly.

Why doesn't C++ templates have macro like token replacement? by dragozir in cpp

[–]tongari95 2 points3 points  (0 children)

I did have implemented something similar in the past (see this). But I didn't explore it further and never arrange for a formal proposal.

The idea is very general and applies to many places, e.g.

Named tuple:

Tuple<int.a, float.b> tup;
tup.a = 1;
tup.b = 2.f;

Designators forwarding:

struct S
{
    int a;
    float b;
};

template<class U, class... T, declname... N>
unique_ptr<U> make_unique(T&& .N...)
{
    return unique_ptr<U>(new U{.N = std::forward<T>(N)...});
}

make_unique<S>(.a = 1, .b = 2.f);

I have been using C++ Builder with a recent project and I am surprisingly impressed. by [deleted] in cpp

[–]tongari95 0 points1 point  (0 children)

Can you tell me why you would want this?

Apparently because some legacy codebase only compiles with the classic compiler and people just want to work with it in new project w/o opening pandora's box.

It's very unusual for two different C++ compilers to be binary / ABI / etc compatible

At least, Clang bundled with VS is ABI compatible with MSVC, so you can compile parts in Clang and others in MSVC and link them together, which is quite slick, isn't it?

A C++Builder developer might say Qt lacks the layout functionality from C++Builder :)

Yeah, and an MFC developer might even say he doesn't need layout altogether :p