Created
April 24, 2015 21:14
-
-
Save mirekfranc/98ee027d04f816b124a6 to your computer and use it in GitHub Desktop.
experiments with template metaprogramming based on one cppcon talk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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