Love template metaprogramming
Clone or download

README.md

Metal version travis.badge appveyor.badge gitter.badge godbolt.badge

Metal is a single header C++11 library designed to make you love template metaprogramming.

Overview

#include <metal.hpp>

// First we need some Values
union x { char payload[10]; };
class y { public: char c; };
struct z { char c; int i; };

// ... from which we construct some Lists
using l0 = metal::list<>;
using l1 = metal::prepend<l0, x>;
using l2 = metal::append<l1, z>;
using l3 = metal::insert<l2, metal::number<1>, y>;

static_assert(metal::same<l1, metal::list<x>>::value, "");
static_assert(metal::same<l2, metal::list<x, z>>::value, "");
static_assert(metal::same<l3, metal::list<x, y, z>>::value, "");

// Lists are versatile, we can check their sizes...
static_assert(metal::size<l0>::value == 0, "");
static_assert(metal::size<l1>::value == 1, "");
static_assert(metal::size<l2>::value == 2, "");
static_assert(metal::size<l3>::value == 3, "");

// retrieve their elements...
static_assert(metal::same<metal::front<l3>, x>::value, "");
static_assert(metal::same<metal::back<l3>, z>::value, "");
static_assert(metal::same<metal::at<l3, metal::number<1>>, y>::value, "");

// count those that satisfy a predicate...
static_assert(metal::count_if<l3, metal::trait<std::is_class>>::value == 2, "");
static_assert(metal::count_if<l3, metal::trait<std::is_union>>::value == 1, "");

// We can create new Lists by removing elements...
using l0_ = metal::drop<l3, metal::number<3>>;
using l1_ = metal::take<l3, metal::number<1>>;
using l2_ = metal::erase<l3, metal::number<1>>;

static_assert(metal::same<l0, l0_>::value, "");
static_assert(metal::same<l1, l1_>::value, "");
static_assert(metal::same<l2, l2_>::value, "");

// by reversing the order of elements...
static_assert(metal::same<metal::reverse<l0>, metal::list<>>::value, "");
static_assert(metal::same<metal::reverse<l1>, metal::list<x>>::value, "");
static_assert(metal::same<metal::reverse<l2>, metal::list<z, x>>::value, "");
static_assert(metal::same<metal::reverse<l3>, metal::list<z, y, x>>::value, "");

// by transforming the elements...
using l2ptrs = metal::transform<metal::lazy<std::add_pointer>, l2>;
using l3refs = metal::transform<metal::lazy<std::add_lvalue_reference>, l3>;

static_assert(metal::same<l2ptrs, metal::list<x*, z*>>::value, "");
static_assert(metal::same<l3refs, metal::list<x&, y&, z&>>::value, "");

// even by sorting them...
template<typename x, typename y>
using smaller = metal::number<(sizeof(x) < sizeof(y))>;

using sorted = metal::sort<l3, metal::lambda<smaller>>;

static_assert(metal::same<sorted, metal::list<y, z, x>>::value, "");

// that and much more!

Quick Start

  1. Download metal.hpp
  2. # include </path/to/metal.hpp>
  3. Love template metaprogramming

Blazing Fast

You don't have to just take my word for it, see for yourself at metaben.ch.

Portable

The following compilers are continuously tested at Travis CI and Appveyor CI.

Compiler Version Operating System
GCC 4.7 Ubuntu 14.04 LTS
GCC 4.8 Ubuntu 14.04 LTS
GCC 4.9 Ubuntu 14.04 LTS
GCC 5 Ubuntu 14.04 LTS
GCC 6 Ubuntu 14.04 LTS
GCC 7 Ubuntu 14.04 LTS
GCC 8 Ubuntu 14.04 LTS
Clang 3.4 Ubuntu 14.04 LTS
Clang 3.5 Ubuntu 14.04 LTS
Clang 3.6 Ubuntu 14.04 LTS
Clang 3.7 Ubuntu 14.04 LTS
Clang 3.8 Ubuntu 14.04 LTS
Clang 3.9 Ubuntu 14.04 LTS
Clang 4.0 Ubuntu 14.04 LTS
Clang 5.0 Ubuntu 14.04 LTS
Clang 6.0 Ubuntu 14.04 LTS
Xcode 6.4 OS X 10.10
Xcode 7.3 OS X 10.11
Xcode 8.0 OS X 10.11
Xcode 8.1 OS X 10.12
Xcode 8.2 OS X 10.12
Xcode 8.3 OS X 10.12
Xcode 9.0 OS X 10.12
Xcode 9.1 OS X 10.12
Xcode 9.2 OS X 10.12
Xcode 9.3 OS X 10.13
MinGW-w64 5 Windows Server 2012
MinGW-w64 6 Windows Server 2012
Visual Studio 14 (2015) Windows Server 2012
Visual Studio 15 (2017) Windows Server 2016

Documentation

The complete up to date documentation is available online.

License

This project is licensed under the MIT.