meta.hpp

A bunch of C++ Template Meta-programming tricks.

Developer notes:

  • Right now test_type<> returns false if a template can’t resolve, but if it’s true it checks if a value field is present; if so that determines success. The reason for this choice was to make sure that true_type and false_type are handled correctly (with built-in type_tratis)

Defines

emp_bool_decoy(TEST)
emp_int_decoy(TEST)

Typedefs

template<typename ...Ts>
using first_type = typename type_index<Ts...>::t1

Trim off a specific type position from a pack.

template<typename ...Ts>
using second_type = typename type_index<Ts...>::t2
template<typename ...Ts>
using third_type = typename type_index<Ts...>::t3
template<typename ...Ts>
using fourth_type = typename type_index<Ts...>::t4
template<size_t ID, typename ...Ts>
using pack_id = typename internal::pack_id_impl<ID, Ts...>::type

Pick a specific position from a type pack.

template<typename ...Ts>
using last_type = pack_id<sizeof...(Ts) - 1, Ts...>

Trim off the last type from a pack.

template<typename REAL_TYPE, typename EVAL_TYPE>
using sfinae_decoy = REAL_TYPE
template<typename REAL_TYPE, typename EVAL_TYPE>
using type_decoy = REAL_TYPE
template<typename REAL_TYPE, typename EVAL_TYPE>
using decoy_t = REAL_TYPE
template<typename EVAL_TYPE>
using bool_decoy = bool
template<typename EVAL_TYPE>
using int_decoy = int
template<typename T, typename ...U>
using AdaptTemplate = typename internal::AdaptTemplateHelper<T, U...>::type
template<typename T, typename U>
using AdaptTemplate_Arg1 = typename internal::AdaptTemplateHelper_Arg1<T, U>::type

Functions

template<typename ...Ts>
void DoNothing(Ts...)

A function that will take any number of argument and do nothing with them.

template<typename OBJ_T>
void BuildObjVector1(vector<OBJ_T>&)

Group types in a parameter pack to build a vector of a designated type.

template<typename OBJ_T>
void BuildObjVector2(vector<OBJ_T>&)
template<typename OBJ_T>
void BuildObjVector3(vector<OBJ_T>&)
template<typename OBJ_T>
void BuildObjVector4(vector<OBJ_T>&)
template<typename OBJ_T, typename T1, typename ...Ts>
void BuildObjVector1(vector<OBJ_T> &v, T1 &arg1, Ts&... extras)
template<typename OBJ_T, typename T1, typename T2, typename ...Ts>
void BuildObjVector2(vector<OBJ_T> &v, T1 &arg1, T2 &arg2, Ts&... extras)
template<typename OBJ_T, typename T1, typename T2, typename T3, typename ...Ts>
void BuildObjVector3(vector<OBJ_T> &v, T1 &arg1, T2 &arg2, T3 &arg3, Ts&... extras)
template<typename OBJ_T, typename T1, typename T2, typename T3, typename T4, typename ...Ts>
void BuildObjVector4(vector<OBJ_T> &v, T1 &arg1, T2 &arg2, T3 &arg3, T4 &arg4, Ts&... extras)
template<typename OBJ_T, size_t NUM_ARGS, typename ...Ts>
vector<OBJ_T> BuildObjVector(Ts&... args)
template<typename TEST, typename FIRST, typename ...OTHERS>
constexpr bool has_type()
template<typename TEST, typename FIRST, typename ...OTHERS>
constexpr size_t count_type()
template<typename TEST_T, typename ...Ts>
constexpr int get_type_index()
template<typename TYPE1, typename TYPE2, typename ...TYPE_LIST>
constexpr bool has_unique_first_type()
template<typename TYPE1, typename TYPE2, typename ...TYPE_LIST>
constexpr bool has_unique_types()
template<template<typename...> class TEST, typename T>
constexpr bool test_type_exist()
template<template<typename...> class TEST, typename T>
constexpr bool test_type_value()
template<template<typename...> class TEST, typename T>
constexpr bool test_type()
template<typename R, typename ...PARAMS, typename ...ARGS>
auto TruncateCall(std::function<R(PARAMS...)> fun, ARGS&&... args)
template<typename T, size_t N>
constexpr size_t GetSize(T (&)[N])

Determine the size of a built-in array.

struct run_and_ignore
#include <meta.hpp>

Effectively create a function (via constructor) where all args are computed, then ignored.

Public Functions

template<typename ...T>
inline run_and_ignore(T&&...)
template<>
struct type_index<>
#include <meta.hpp>

Public Types

using t1 = void
using t2 = void
using t3 = void
using t4 = void
template<typename T1>
struct type_index<T1>
#include <meta.hpp>

Public Types

using t1 = T1
using t2 = void
using t3 = void
using t4 = void
template<typename T1, typename T2>
struct type_index<T1, T2>
#include <meta.hpp>

Public Types

using t1 = T1
using t2 = T2
using t3 = void
using t4 = void
template<typename T1, typename T2, typename T3>
struct type_index<T1, T2, T3>
#include <meta.hpp>

Public Types

using t1 = T1
using t2 = T2
using t3 = T3
using t4 = void
template<typename T1, typename T2, typename T3, typename T4, typename ...Ts>
struct type_index<T1, T2, T3, T4, Ts...>
#include <meta.hpp>

Public Types

using t1 = T1
using t2 = T2
using t3 = T3
using t4 = T4
template<class T>
struct dependent_false : public std::false_type
#include <meta.hpp>

A false type that does NOT resolve in unexecuted if-constexpr branches. By Brian Bi; from: https://stackoverflow.com/questions/69501472/best-way-to-trigger-a-compile-time-error-if-no-if-constexprs-succeed

template<typename R, typename ...ARGS>
struct AdaptFunction
#include <meta.hpp>

Public Static Functions

template<typename ...EXTRA_ARGS>
static inline auto Expand(const std::function<R(ARGS...)> &fun)
template<int I, int... Is>
struct tIntMath
#include <meta.hpp>

Public Static Functions

static inline constexpr int Sum()
static inline constexpr int Product()
template<int I>
struct tIntMath<I>
#include <meta.hpp>

Public Static Functions

static inline constexpr int Sum()
static inline constexpr int Product()