- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
/* Q: Can someone recommend a more elegant way to achieve these compile-time constants? */
template <int> struct Map;
template <> struct Map<0> {static const int value = 4;};
template <> struct Map<1> {static const int value = 8;};
template <> struct Map<2> {static const int value = 15;};
template <int> struct MapInverse;
template <> struct MapInverse<4> {static const int value = 0;};
template <> struct MapInverse<8> {static const int value = 1;};
template <> struct MapInverse<15> {static const int value = 2;};
/* A: Another TMP approach for a linear search using C++11: */
#include <type_traits>
// === Types:
// Usage:
// Function<Map<x1,y1>,Map<x2,y2>,...>
template<int D, int R> struct Map { enum { domain=D, range=R }; };
template<typename ...A> struct Function {};
// === Metafunctions:
// Usage:
// ApplyFunction<x,F>::value
template<int I, typename M> struct ApplyFunction;
// Usage:
// ApplyFunctionInverse<x,F>::value
template<int I, typename M> struct ApplyFunctionInverse;
// ==== Example:
// Define function M to the mapping in your original post.
typedef Function<Map<0,4>,Map<1,8>,Map<2,15>> M;
// ==== Implementation details
template<typename T> struct Identity { typedef T type; };
template<int I, typename A, typename ...B> struct ApplyFunction<I, Function<A,B...> > {
typedef typename
std::conditional <I==A::domain
, Identity<A>
, ApplyFunction<I,Function<B...>> >::type meta;
typedef typename meta::type type;
enum { value = type::range };
};
template<int I, typename A> struct ApplyFunction<I, Function<A>> {
typedef typename
std::conditional <I==A::domain
, Identity<A>
, void>::type meta;
typedef typename meta::type type;
enum { value = type::range };
};
// Linear search by range
template<int I, typename A> struct ApplyFunctionInverse<I, Function<A>> {
typedef typename
std::conditional <I==A::range
, Identity<A>
, void>::type meta;
typedef typename meta::type type;
enum { value = type::domain };
};
template<int I, typename A, typename ...B> struct ApplyFunctionInverse<I, Function<A,B...> > {
typedef typename
std::conditional <I==A::range
, Identity<A>
, ApplyFunctionInverse<I,Function<B...>> >::type meta;
typedef typename meta::type type;
enum { value = type::domain };
};
// ==============================
// Demonstration
#include <iostream>
int main()
{
// Applying function M
std::cout << ApplyFunction<0,M>::value << std::endl;
std::cout << ApplyFunction<1,M>::value << std::endl;
std::cout << ApplyFunction<2,M>::value << std::endl;
// Applying function inverse M
std::cout << ApplyFunctionInverse<4,M>::value << std::endl;
std::cout << ApplyFunctionInverse<8,M>::value << std::endl;
std::cout << ApplyFunctionInverse<15,M>::value << std::endl;
}
Элегантненько.
s: https://stackoverflow.com/questions/26075969/compile-time-map-and-inverse-map-values