hyperion::mpl#

hyperion::mpl is a C++20 metaprogramming library focused on making metaprogramming simple and easy. With hyperion::mpl, metaprogramming almost as easy as typical application code: you can metaprogram using (relatively) normal variables, values, and functions, in an ergonomic and functional style, instead of the bloat and complexity of the struct templates, partial specializations, SFINAE, and other techniques and tricks typically used in C++ metaprogramming.

See the Quick Start Guide for how to get started using hyperion::mpl.

For an overview of each module, see the links in the left sidebar or below.

Example#
 1#include <hyperion/mpl/list.h>
 2#include <hyperion/mpl/type.h>
 3#include <hyperion/mpl/value.h>
 4
 5#include <concepts>
 6#include <ranges>
 7
 8using namespace hyperion;
 9using namespace hyperion::mpl;
10
11constexpr auto add_const = [](MetaType auto type) noexcept {
12    return type.as_const();
13};
14
15constexpr auto list = List<int, double, float>{};
16constexpr auto zipped = list.zip(List<u32, usize, i32>{});
17constexpr auto constified = zipped.apply(add_const);
18
19static_assert(constified == List<Pair<const int, const u32>,
20                                 Pair<const double, const usize>,
21                                 Pair<const float, const i32>>{});
22static_assert(constified.all_of(is_const));
23
24constexpr auto list2 = List<int, const double, float>{};
25// ranges support is implemented for `mpl::List` at all times,
26// but usage in practice requires a complete standard library implementation
27// for ranges. (i.e. `operator|` isn't particularly useful without the
28// `std::ranges::<things>` to go along with it)
29constexpr auto ranged
30        = list
31            | std::ranges::views::filter([](MetaType auto type) { return not type.is_const(); })
32            | std::ranges::views::transform([](MetaType auto type) {
33                return type.as_lvalue_reference().as_volatile();
34            })
35            | std::ranges::views::reverse
36            | std::ranges::views::drop(1_value);
37static_assert(ranged == List<volatile int&>{});
38
39constexpr auto add_one = [](MetaValue auto value) {
40    return value + 1_value;
41};
42constexpr auto times_two = [](MetaValue auto value) {
43    return value * 2_value;
44};
45
46static_assert(2_value
47              .apply(add_one)
48              .apply(times_two)
49              .apply(add_one) == 7);
50
51constexpr auto val3 = 10;
52static_assert(decltype_(val3)
53              .apply<std::remove_reference>()
54              .apply<std::remove_const>()
55              .apply<std::add_rvalue_reference>()
56              == decltype_<int&&>());
57
58constexpr auto add_lvalue_reference = [](MetaType auto type) {
59    return type.as_lvalue_reference();
60};
61
62constexpr auto remove_reference = [](MetaType auto type)
63    -> std::remove_reference<typename decltype(type)::type>
64{
65    return {};
66};
67
68static_assert(decltype_<int&&>()
69              .apply(remove_reference)
70              .apply(add_const)
71              .apply(add_lvalue_reference)
72              == decltype_<const int&>());
73
74constexpr auto val1 = Value<4>{};
75constexpr auto val2 = Value<2>{};
76constexpr auto meaning_of_life = (val1 * 10_value) + val2;
77static_assert(meaning_of_life == 42);

Getting Started

Quick Reference