cmoon::meta::choice_t
Defined in module
<cmoon.meta>
template<class T>
struct choice_t
{
T strategy {};
bool no_throw {false};
};
Used in meta programming to instantiate different choice_t
based on compile-time choices about a given path.
The no_throw
member can be queried to check if the choice is not throwing (such as a choice for a given function call).
Template parameters
T | - | Custom strategy type |
Member Objects
Member name | Type |
---|---|
strategy | T |
no_throw | bool |
Example
#include <concepts>
#include <type_traits>
import cmoon.meta;
template<class T>
void func(const T& value) noexcept(std::integer<T>);
enum class state
{
floating_call,
integer_call,
none
};
template<class T>
consteval cmoon::meta::choice_t<state> choose() noexcept
{
if constexpr (std::integer<std::remove_cvref_t<T>>)
{
return {state::integer_call, noexcept(func(std::declval<T>()))};
}
else if constexpr (std::floating_point<std::remove_cvref_t<T>>)
{
return {state::floating_call, noexcept(func(std::declval<T>()))};
}
else
{
return {state::none, true};
}
}
template<class T>
void func2(const T& value) noexcept(choose<T>().no_throw)
{
// Find out what kind of call we can make, and whether that call
// is throwing or not
constexpr auto choice = choose<T>();
if constexpr (choice.strategy == state::integer_call)
{
// Do something before calling with an integer
func(value);
}
else if constexpr (choice.strategy == state::floating_call)
{
// Do something before calling with a float
func(value);
}
else if constexpr (choice.strategy == state::none)
{
// We don't want to call it
}
}
int main()
{
const auto value = 5;
func2(value);
}