Skip to content

Instantly share code, notes, and snippets.

@supsm
Last active December 2, 2024 21:30
Show Gist options
  • Save supsm/b7331309700f3b4f297c8d6aadd2ac56 to your computer and use it in GitHub Desktop.
Save supsm/b7331309700f3b4f297c8d6aadd2ac56 to your computer and use it in GitHub Desktop.
Blursed C++ Code

Collection of blursed C++ code that may or may not be useful.

Xieite

Blursed library with a bunch of random stuff, some of which might be useful.
https://github.com/Eczbek/xieite

Type deduplication

Code:

template <typename...>
struct deduplicate {};

template <typename ...A, typename B>
auto operator->*(deduplicate<A...>, deduplicate<B>)
    -> std::conditional_t<(std::is_same_v<A, B> || ...),
                          deduplicate<A...>,
                          deduplicate<A..., B>>;

template <typename ...Ts>
using deduplicate_t = decltype((deduplicate<>{} ->* ... ->* deduplicate<Ts>{}));

Example usage:

static_assert(std::is_same_v<deduplicate<int, float>,
                             deduplicate_t<int, int, float, int, float, float, int>>);

Credit: Eisenchan from discord
March 27, 2023

Modification for use with std::variant

Code:

template <typename... Ts>
struct deduplicated_variant
{
    using type = std::variant<Ts...>;
};

template <typename... A, typename B>
auto operator->*(deduplicated_variant<A...>, deduplicated_variant<B>)
    -> std::conditional_t<(std::is_same_v<A, B> || ...),
                          deduplicated_variant<A...>,
                          deduplicated_variant<A..., B>>;

template <typename... Ts>
using deduplicated_variant_t = decltype((deduplicated_variant<>{} ->* ... ->* deduplicated_variant<Ts>{}))::type;

Example usage:

deduplicated_variant<int, int, float, int, float, float, int> v = 1;

Credit: me (and Eisenchan for original)
December 1, 2024

Compile-time "string" manipulation

https://godbolt.org/z/1nz69T6bf
Credit: me
December 12, 2023

Remove all pointers/references/arrays/etc from type

https://godbolt.org/z/ET1j4s99f
Credit: me
October 7, 2024

Basic coroutine task

https://godbolt.org/z/q4fM87qs3
Credit: me
October 19, 2024

Debug utilities

https://github.com/TymianekPL/DebugLib/blob/main/debuglib.hpp
Credit: Tymi from discord
November 17, 2024

Finding type in list of types

Variant 1:

template <typename T, typename ...P>
consteval int find_type()
{
    int ret = 0;
    ((std::is_same_v<T, P> || (void(ret++), false)) || ...);
    if (ret != sizeof...(P))
        { return ret; }
}

Credit: Holyblackcat from discord
November 25, 2024

Variant 2:

template<typename T, typename... List>
consteval std::size_t find_type()
{
    bool same[] = { std::is_same<T, List>()... };

    for(std::size_t i = 0; i < sizeof...(List); i++)
    {
        if (same[i]) return i;
    }
}

Credit: Veeloxfire from discord November 25, 2024

Variant 3 (kinda cursed and also slow compliation):

template<typename T>
struct wrap {};

template<typename T, typename... Ts>
consteval std::size_t find_type()
{
    return std::variant<wrap<Ts>...>(wrap<T>()).index();
}

Can also replace wrap with a standard empty type like std::type_identity (imo less clear intent though).
Credit: stabilewespe from discord and me
November 25, 2024

Indexing type template parameter packs

Variant 1:

std::tuple_element<IND, std::tuple<TYPES...>>

November 25, 2024

Variant 2 (cursed, no stdlib):

Code (fill in IND and TYPES...):

decltype([]<std::size_t ind, typename T, typename... Ts>(this auto&& self) { if constexpr (ind == 0) { struct { using type = T; } ret; return ret; } else { return self.template operator()<ind - 1, Ts...>(); } }.template operator()<IND, TYPES...>())::type

Example usage:

using num_type = decltype([]<std::size_t ind, typename T, typename... Ts>(this auto&& self) { if constexpr (ind == 0) { struct { using type = T; } ret; return ret; } else { return self.template operator()<ind - 1, Ts...>(); } }.template operator()<3, int, long, float, double>())::type;
num_type i = 1;

Credit: me
November 25, 2024

Wait-free producer with possibly-waiting consumer

Code:

std::atomic_bool r, w;
std::array<Data, 2> buffer;

void producer() {
    bool w_ = 0;
    while (true)
    {
        auto data = produce();
        if (r == w_) {
            w_ = !w_;
            buffer[w_] = data;
            w = w_;
            w.notify_one();
        }
        else {
            buffer[w_] = data;
        }
    }
}

void consumer() {
    bool r_ = 1;
    while (true)
    {
        if (r_ != w) {
            r_ = !r_;
            r = r_;
        }
        w.wait(r_); // wait until w != r
        auto data = buffer[r_];
        display(data);
    }
}

Credit: me (also thanks to Eisenchan from discord)
December 1, 2024

Check if a value is equal to any of a list of values

Code:

constexpr bool any_eq(const auto& lhs, const auto&... var_rhs)
{
  return (... || (lhs == var_rhs));
}

Example usage:

if (any_eq(x, a, b, c)) {

}

Credit: Dragon from discord
December 1, 2024

Copy template parameters from one class to another

Code:

template<typename Source, typename Target>
struct copy_tparams {};

template<template<typename...> typename Source, typename... SourceArgs, template<typename...> typename Target, typename... TargetArgs>
struct copy_tparams<Source<SourceArgs...>, Target<TargetArgs...>>
{
    using type = Target<SourceArgs...>;
};

template<typename Source, typename Target>
using copy_tparams_t = copy_tparams<Source, Target>::type;

Example usage:

using tuple_type = copy_tparams_t<std::vector<int>, std::tuple<void>>; // void is a placeholder
// tuple_type is std::tuple<int, std::allocator<int>>

Credit: me
December 1, 2024

Indexing non-type template parameter packs

std::get<IND>(std::tuple(ARGS...))

Each element of ARGS must be copyable. Code should also work for function parameter packs, but not recommended due to unnecessary copy (consider e.g. std::tie instead).
Credit: eczbek
December 2, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment