Skip to content

Instantly share code, notes, and snippets.

@mirekfranc
Created April 24, 2015 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mirekfranc/98ee027d04f816b124a6 to your computer and use it in GitHub Desktop.
Save mirekfranc/98ee027d04f816b124a6 to your computer and use it in GitHub Desktop.
experiments with template metaprogramming based on one cppcon talk
#ifndef META_H
#define META_H
namespace mirek
{
#include <climits>
// abs ////////////////////////////////////////////////////////////////////////////////
template<int N>
struct abs
{
static_assert (N != INT_MIN, "blah until C++17");
static constexpr int value = (N < 0) ? -N : N;
// initialization instead of an assigment
// we do this instead of return, since we cannot do that
};
// gcd ////////////////////////////////////////////////////////////////////////////////
// recursion part
template<unsigned M, unsigned N>
struct gcd
{
static constexpr int value = gcd<N, M%N>::value;
};
// base case with partial specialization
template<unsigned M>
struct gcd<M, 0>
{
static_assert (M != 0, "blah until C++17"); // gcd<0,0>::value is undefined
static constexpr int value = M;
};
// rank metafuction, base case in a primary template /////////////////////////////////
template<typename A>
struct rank
{
static constexpr unsigned value = 0u;
};
// rank metafuction, recursion in a specialization
template<typename A, unsigned U>
struct rank<A[U]>
{
static constexpr unsigned value = 1u + rank<A>::value;
};
// template<typename A> struct rank : integral_constant<size_t, 0u> {};
// template<typename A, size_t U> struct rank<A[U]> : integral_constant<size_t, 1u + rank<U>::value> {};
// template<typename A> struct rank<A[]> : integral_constant<size_t, 1u + rank<U>::value> {};
// remove_const ///////////////////////////////////////////////////////////////////////
template<typename T> // identity, very useful
struct type_is
{
using type = T;
};
template<typename T>
struct remove_const : type_is<T> {};
template<typename T>
struct remove_const<const T> : type_is<T> {};
// IF /////////////////////////////////////////////////////////////////////////////////
// is part of C++11 as "conditional", in C++14 "conditional_t" for conveniece
template<bool, typename T, typename> // unused parameters
struct IF : type_is<T> {};
template<typename T, typename F>
struct IF<false, T, F> : type_is<F> {};
// myenable_if ////////////////////////////////////////////////////////////////////////
template<bool, typename T = void>
struct myenable_if : type_is<T> {};
template<typename T>
struct myenable_if<false, T> {}; // only sometimes an error (SFINAE) (explicit overload set management)
}
#endif // META_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment