-
Notifications
You must be signed in to change notification settings - Fork 1
/
purempl.h
131 lines (110 loc) · 2.42 KB
/
purempl.h
1
2
3
4
5
6
7
8
9
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
#include "pure.h"
#ifdef PURE_USE_BOOST
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/map.hpp>
namespace pure
{
namespace mpl
{
using namespace boost::mpl;
}
}
#else
#error boost required currently.
#endif
namespace pure
{
namespace mpl
{
// counter
template <int...> struct seq{};
template <int N, int ...S>
struct count : count<N-1, N-1, S...> {};
template <int ... S>
struct count<0, S...>
{
typedef seq<S...> type;
};
template <int ... A, int ... B>
seq<A..., B...> seq_cat(seq<A...>, seq<B...>)
{
return seq<A..., B...>();
}
//
template <int ...> struct find;
template <int N, int P>
struct find<N, P>
{
//static_assert(false, "not exists");
};
template <int N, int P, int F, int ... S>
struct find<N, P, F, S...>
{
static const int value =
if_c<N==F,
int_<P>,
find<N, P+1, S...>
>::type::value;
};
template <int N, typename T>
struct find_seq;
template <int N, int ... S>
struct find_seq<N, seq<S...>>
{
static const int value = find<N, 0, S...>::value;
};
template <int N, typename T>
struct seq_contains;
template <int N>
struct seq_contains<N, seq<>>
{
static const bool value = false;
};
template <int N, int F, int ... S>
struct seq_contains<N, seq<F, S...>>
{
static const bool value = if_c<N==F, bool_<true>,seq_contains<N,seq<S...>>>::type::value;
};
template <int N, typename T>
struct seq_insert_one;
template <int N, int ...S>
struct seq_insert_one<N, seq<S...>>
{
typedef seq<N, S...> type;
};
template <int N, typename T>
struct seq_remove_one;
template <int N>
struct seq_remove_one<N, seq<>>
{
typedef seq<> type;
};
template <int N, int F, int ... S>
struct seq_remove_one<N, seq<F, S...>>
{
typedef typename if_c<N==F,
seq<S...>,
typename seq_insert_one<F, typename seq_remove_one<N, seq<S...>>::type>::type>::type type;
};
template <typename A, typename B>
struct seq_diff;
template <typename A>
struct seq_diff<A, seq<>>
{
typedef A type;
};
template <typename A, int N, int ... D>
struct seq_diff<A, seq<N, D...>>
{
typedef typename seq_diff<typename seq_remove_one<N, A>::type, seq<D...>>::type type;
};
template <typename A, typename B>
struct seq_and
{
typedef typename seq_diff<A, typename seq_diff<A,B>::type>::type type;
};
}
}