TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25689 10
26)
```cpp
constexpr auto parse() {
// Allowed
static_assert(false, "Expected ';'");

// Not allowed :( (until C++ 26)
std::size_t line = 5;
static_assert(false, "Expected ';' at line " + to_string(line));
}
```
I didn't want my project to require C++ 26, so I used another trick. The formatted string gets turned into a static array just like a vector (into `const_string` actually) and then it's passed into `ErrorMessage<const_string Msg>` that triggers compilation error. So we force the compiler to print the full type name that includes our error. But sadly the type name has a limit about 100 symbols. I think I could solve it with splitting the message into several ErrorMessages... God, I don't want to read this in my console.
```c++
template<const_string Msg>
struct ErrorMessage {
static_assert(false, "Check the template parameter for details");
};

template<auto err_getter>
consteval auto report_error() -> void {
// C++ 26 support
#ifdef KORKA_FEATURE_FORMATTED_STATIC_ASSERT
static_assert(false, to_string(err_getter()));
#else
constexpr auto msg = const_string_from_string_view<[] { return to_string(err_getter()); }>();
std::ignore = ErrorMessage<msg>{};
#endif
}
```

I don't want you to see it, so I'll just show C++ 26 version.
```
error: static assertion failed: Lexer Error: Unterminated string at line 12
```

### Mapping signatures to names. And vice versa
In our little runtime C++ we are used to `std::unordered_map<string, value_t>` and other standard or non-standard (hello, Boost!) containers. But I needed a table where a key is a string and the value is a TYPE. And in C++ I can't treat types as values, I can't just put them into a dict... :(

So, welcome another hack!
```c++
template<auto, class>
struct signature_mapper;

// function_info_getter takes an index to our mapped function,
// and Is... holds all indices
template<auto function_info_getter, std::size_t... Is>
struct signature_mapper<
function_info_getter,
std::index_sequence<Is...>
> {
// hash func
consteval static auto hash(auto &&v) -> std::size_t {
return frozen::elsa<std::string_view>{}(v, 0);
}

// Our function overloaded with many unique types based on hash of the mapped function
constexpr static auto _overloaded = overloaded{
(
[](unique_type<hash(function_info_getter(Is).name)>)
-> const_function_info_to_signature_t<[] { return function_info_getter(Is); }> * {
return nullptr;
}
)...
};

// Extracting the type by name
template<const_string name>
using get_signature_t = std::remove_pointer_t<decltype(
_overloaded(
unique_type<hash(name)>{}
)
)>;

};
```

We use well-known function overload (~~but for evil things~~). Basically, one type inherits a lot of lambdas that take an empty `unique_type<hash>` that serves as our key and returns the pointer to our type.
```cpp
// How our mapper looks after expanding our params
struct overloaded : lambda1, lambda2, lambda3 {
using lambda1::operator();
using lambda2::operator();
using lambda3::operator();
};

// And every lambda looks like this
auto lambda_fib = [](unique_type<hash("fib")>) -> signature_of_fib* { return nullptr; };
```
When we call `_overloaded(unique_type<hash(name)>())` our poor compiler has to resolve the overload. And he looks for right one through all `()` operators. And then we just take that it returns (our `T*`) and get the `T`.
I use this "mechanism" to extract script functions into the native C++.
```cpp
constexpr auto script_fib = compile_result.function<"fib">();
```

### Bindings from C++ to our script lang
This was the most exhausting part. Well, how "exhausting" exactly... I was thinking for a few evenings and then made it work one morning. The problem was with me. I wanted to make a pretty API that was impossible in the current standard (maybe it's possible in C++ 26, but I didn't check it).
I wanted it to look like this:
```cpp
auto func() -> void;
auto foo(int) -> int;

// Примерно так
constexpr auto bindings = korka::make_bindings<
"func", func,
"foo", foo
>();

// Или так
constexpr auto
More from @r_cpp
  1. Sep 26, 2026Token Sequence Injection & Modern Macros: The Most Game-Changing Compile-Time Feature in C…
  2. Sep 25, 2026myStringStream.str("") Considered Harmful Under C++20 I was recently looking at some (rath…
  3. Sep 20, 2026A clever branch free optimization I'm the developer of memlz which is an extremely fast co…
  4. Sep 15, 2026Inside Boost.PolyCollection https://bannalia.blogspot.com/2026/09/inside-boostpolycollecti…
  5. Sep 11, 2026C++26: Standard Library Hardening Experiments https://www.cppstories.com/2026/hardening-ex…
  6. Sep 11, 2026MSVC C++23: constexpr cmath with LLVM Libc https://devblogs.microsoft.com/cppblog/msvc-c23…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →