Skip to content

dgodfrey206/monster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

345 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Monster LICENSE Documentation Language Platform Gitter Chat

Advanced C++ Template MetaProgramming Framework

Overview

#include <cstdint>
#include <monster.hpp>

using namespace monster;

int main(int argc, char* argv[])
{
    // arrange the same elements adjacent in a sequence, keep the relative order
    using a1 = adjacent_t<std::tuple<char, double, char, int, double>>;
    using a2 = adjacent_t<std::index_sequence<4, 3, 0, 3, 2, 4, 5, 3>>;

    static_assert(std::is_same_v<a1, std::tuple<char, char, double, double, int>>);
    static_assert(std::is_same_v<a2, std::index_sequence<4, 4, 3, 3, 3, 0, 2, 5>>);

    // Boyer-Moore-Horspool (BMH) algorithm searches for occurrences of a sequence within another sequence
    using b1 = bmh_t<std::tuple<int, char, int>, std::tuple<int, int, char, int, char, int, char, int>>;
    using b2 = bmh_t<std::integer_sequence<int, 7, 5>, std::integer_sequence<int, 7, 5, 4, 0, 7, 5, 9>>;

    static_assert(std::is_same_v<b1, std::index_sequence<1, 3, 5>>);
    static_assert(std::is_same_v<b2, std::index_sequence<0, 4>>);

    // Knuth–Morris–Pratt (KMP) algorithm searches for occurrences of a sequence within another sequence
    using k1 = kmp_t<std::tuple<int, char, int>, std::tuple<int, int, char, int, char, int, char, int>>;
    using k2 = kmp_t<std::integer_sequence<int, 7, 5>, std::integer_sequence<int, 7, 5, 4, 0, 7, 5, 9>>;

    static_assert(std::is_same_v<k1, std::index_sequence<1, 3, 5>>);
    static_assert(std::is_same_v<k2, std::index_sequence<0, 4>>);

    // find K-th smallest element in a sequence (k == 2)
    using min1 = select_t<2, std::tuple<short, int, double, int, char>>;
    using min2 = select_t<2, std::integer_sequence<int, -2, 1, 0, -7, 4, 3>>;

    static_assert(std::is_same_v<min1, short>);
    static_assert(std::is_same_v<min2, c_<-2>>);

    // find K-th greatest element in a sequence (k == 2)
    using max1 = select_t<2, std::tuple<short, int, double, int, char>, greater_equal_t>;
    constexpr auto max2 = select_v<2, std::integer_sequence<int, -2, 1, 0, -7, 4, 3>, greater_equal_t>;

    static_assert(std::is_same_v<max1, int>);
    static_assert(max2 == 3);

    // returns element at specific index of a sequence
    using e1 = element_t<1, std::tuple<char, double, int>>;
    using e2 = element_t<3, std::integer_sequence<int, 1, -2, 7, 4>>;

    constexpr auto e3 = element_v<3, std::integer_sequence<int, 1, -2, 7, 4>>;

    static_assert(std::is_same_v<e1, double>);
    static_assert(std::is_same_v<e2, c_4>);

    static_assert(e3 == 4);

    // remove duplicate elements from a sequence, keep the first appearance
    using u1 = unique_t<std::tuple<int, char, int, double>>;
    using u2 = unique_t<std::integer_sequence<int, 2, 2, 3, 4, 3>>;

    static_assert(std::is_same_v<u1, std::tuple<int, char, double>>);
    static_assert(std::is_same_v<u2, std::integer_sequence<int, 2, 3, 4>>);

    // swap elements at specific index of a sequence
    using s1 = swap_t<1, 3, std::tuple<int, double, char, float>>;
    using s2 = swap_t<0, 2, std::integer_sequence<int, 1, -2, 7, 4>>;

    static_assert(std::is_same_v<s1, std::tuple<int, float, char, double>>);
    static_assert(std::is_same_v<s2, std::integer_sequence<int, 7, -2, 1, 4>>);

    // sort elements by value in a sequence
    using s3 = quick_sort_t<std::tuple<double, short, double, int, char, char, double>>;
    using s4 = quick_sort_t<std::integer_sequence<int, 2, 1, 0, -3, 4, 1, -7, 5, -2>>;

    static_assert(std::is_same_v<s3, std::tuple<char, char, short, int, double, double, double>>);
    static_assert(std::is_same_v<s4, std::integer_sequence<int, -7, -3, -2, 0, 1, 1, 2, 4, 5>>);

    // sort elements by index in a sequence
    using s5 = sort_index_t<std::tuple<double, short, double, int, char, char, double>>;
    using s6 = sort_index_t<std::integer_sequence<int, 2, 1, 0, -3, 4, 1, -7, 5, -2>>;

    static_assert(std::is_same_v<s5, std::index_sequence<4, 5, 1, 3, 6, 2, 0>>);
    static_assert(std::is_same_v<s6, std::index_sequence<6, 3, 8, 2, 1, 5, 0, 4, 7>>);

    // reverses the order of the elements of a sequence
    using r1 = reverse_t<std::tuple<float, double, int, short>>;
    using r2 = reverse_t<std::integer_sequence<int, 1, 0, 2, -2, 7, 6>>;

    static_assert(std::is_same_v<r1, std::tuple<short, int, double, float>>);
    static_assert(std::is_same_v<r2, std::integer_sequence<int, 6, 7, -2, 2, 0, 1>>);

    // reverses the order of the elements of a sequence recursively
    using r3 = reverse_recursive_t<std::tuple<int, std::tuple<int, std::tuple<char, short>>, char>>;
    using r4 = reverse_recursive_t<std::tuple<char, std::integer_sequence<int, 7, 2, 0, 4, 8>, int>>;

    static_assert(std::is_same_v<r3, std::tuple<char, std::tuple<std::tuple<short, char>, int>, int>>);
    static_assert(std::is_same_v<r4, std::tuple<int, std::integer_sequence<int, 8, 4, 0, 2, 7>, char>>);

    // rotates the elements in the range [begin, middle, end) of a sequence
    using r5 = rotate_t<0, 2, 5, std::tuple<int, char, double, float, int64_t>>;
    using r6 = rotate_t<2, 4, 7, std::integer_sequence<int, 9, 8, 1, 2, 3, 4, 5, 7, 6>>;

    static_assert(std::is_same_v<r5, std::tuple<double, float, int64_t, int, char>>);
    static_assert(std::is_same_v<r6, std::integer_sequence<int, 9, 8, 3, 4, 5, 1, 2, 7, 6>>);

    // returns the elements in the range [begin, end) of a sequence
    using r7 = range_t<1, 5, std::tuple<int, char, float, double, int, short>>;
    using r8 = range_t<2, 6, std::integer_sequence<int, 1, 2, -2, 4, 3, 5, 8, -5>>;

    static_assert(std::is_same_v<r7, std::tuple<char, float, double, int>>);
    static_assert(std::is_same_v<r8, std::integer_sequence<int, -2, 4, 3, 5>>);

    return 0;
}

Introduction

Monster is a header-only, extensible metaprogramming library designed for modern C++.
It focuses on pure type programming, offering compile-time algorithms, sequences, and Higher-Order Metafunctions.

Monster delivers a solid conceptual base along with a wide set of powerful and consistent tools, making explicit advanced Template MetaProgramming (TMP) in modern C++ both simple and enjoyable.

Compiler requirements

The library requires a C++20-compliant compiler and standard library—no additional dependencies.

More specifically, Monster depends on support for these C++20 features (non-exhaustively):

  • concepts
  • lambda templates
  • all C++20 type traits from the <type_traits> header

Building

Monster is header-only. To use it, just include it in your source files:

#include <monster.hpp>

To build the example using CMake, cd into the project root and set up a build directory:

mkdir build cd build
cmake ..

Then build and install the executables:

make -j4
make install

The resulting executables will appear in the project's bin directory.
Alternatively, you can run the build.sh script, which places the executables in /tmp.

Documentation

The documentation is available online at Guidelines.md.
It provides everything you need, including installation details, a full table of contents, and a comprehensive reference section with examples.

Full example

Please see Tutorial.md.

License

Monster is licensed as Boost Software License 1.0.

About

The Art of Template MetaProgramming (TMP) in Modern C++♦️A header-only, extensible metaprogramming library designed for modern C++

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors

Languages