There are 2 hard problems in computer science: cache invalidation, naming things and off-by-one errors.
This is about the 2nd problem: naming things.
I'm looking if this technique or type has been used somewhere else already and has a name. dichotomy
is an ok name, but bools_at_compile_time
is a horrible one.
using dichotomy_t = std::variant<std::false_type, std::true_type>; // (or a struct that inherits from that, and overloads operator bool()) constexpr dichotomy_t dichotomy( bool b ) { if (b) return std::true_type{}; return std::false_type{}; } template<class F, class...Bools> constexpr auto bools_at_compile_time( F&& f, Bools...bools ) { static_assert( (std::is_same<Bools, bool>{} && ...) ); return std::visit( std::forward<F>(f), dichotomy(bools)... ); }
dichotomy_t
is a variant between true and false. Its runtime representation is 0
or 1
.
What this lets you do is:
auto foo( bool x, bool y ) { // <-- x and y are run-time bools here auto func = [&](auto x, auto y) { return some_template<x,y>(); // <-- x and y are compile-time bools here }; return bools_at_compile_time( func, x, y ); // <-- converts runtime to compile time bools }
Is there a name for dichotomy_t
or the more general bools_at_compile_time
technique? I'm looking for a name that is well known in any community (even a non-C++ one), even a verb that describes "taking a runtime value and creating a switch and a set of compile time value in generated code to pick between" better than a sentence.
Live example
A good answer would include the name, citations/quotes describing what that name means, examples of that named thing in use in the other context, and evidence that this name is equivalent to or inclusive of the above type/value and function.
(It may help to find a name the generalization of this would be an enum
instead of a bool
, which has a fixed number of known states, and a switch/case map that converts the runtime value into a compile-time constant in each case clause.)
Functions are the moving parts of the application, so having named them precisely increases the readability. The scope is to understand what the function does from its name, arguments list and the way it is invoked.
Function Name − This is the actual name of the function. The function name and the parameter list together constitute the function signature. Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter.
Define a function named "myFunction", and make it display "Hello World!" in the <p> element. Hint. Hint: Use the function keyword to define the function (followed by a name, followed by parentheses). Place the code you want executed by the function, inside curly brackets. Then, call the function.
I do not know of any existing names for this pattern, but if you take a good look at how the STL is naming things, you can use name close enough to make your code explicit.
I also liked the dispatcher_t
idea from @Jarod42 , I think it is more generic than dichotomy_t
or n_chotomy_t
.
dichotomy()
could be called make_variant(b)
. Since it will return the std::variant
value of a boolean given in argument. Much like std::make_tuple
makes a tuple from multiple arguments.
I would suggest to replace bools_at_compile_time
by static_eval
. Much like static_assert
makes an assertion at compile time.
Not that if eval
is not the correct adjective for your use case you can easily adapt it static_*
.
#include <type_traits> #include <variant> #include <utility> using dichotomy_t = std::variant<std::false_type, std::true_type>; // (or a struct that inherits from that, and overloads operator bool()) constexpr dichotomy_t make_variant( bool b ) { if (b) return std::true_type{}; return std::false_type{}; } template<class F, class...Bools> constexpr auto static_eval( F&& f, Bools...bools ) { static_assert( (std::is_same<Bools, bool>{} && ...) ); return std::visit( std::forward<F>(f), make_variant(bools)... ); } template<bool x, bool y> auto some_template() { return x || y; } auto foo( bool x, bool y ) { // <-- x and y are run-time bools here auto func = [&](auto x, auto y) { return some_template<x,y>(); // <-- x and y are compile-time bools here }; return static_eval( func, x, y ); // <-- converts runtime to compile time bools } #include <iostream> int main() { std::cout << foo( true, true ) << "\n"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With