test, trial, experiments
修订版 | 9c37f915b2cb0b77686a79274a91847432182283 (tree) |
---|---|
时间 | 2017-03-21 01:11:55 |
作者 | Yamashta Daisuke <yamasdais@gmai...> |
Commiter | Yamashta Daisuke |
Changed abstract classes into Sa-HiLow setting
@@ -3,13 +3,20 @@ | ||
3 | 3 | |
4 | 4 | namespace fmp { |
5 | 5 | |
6 | +template <typename A, typename D> | |
7 | +struct cons; | |
8 | + | |
6 | 9 | namespace detail { |
7 | 10 | |
11 | +template <typename T, T V> | |
12 | +struct val; | |
13 | + | |
14 | +// holder of a template parameter | |
8 | 15 | template <typename T> |
9 | 16 | struct any { |
17 | + using type = any<T>; | |
10 | 18 | using value_type = T; |
11 | 19 | |
12 | - using listp = std::false_type; | |
13 | 20 | }; |
14 | 21 | |
15 | 22 | template <typename T, T V> |
@@ -17,15 +24,37 @@ struct val : public std::integral_constant<T, V> { | ||
17 | 24 | using type = val<T, V>; |
18 | 25 | }; |
19 | 26 | |
27 | +template <typename T, T... V> | |
28 | +struct valary; | |
29 | + | |
30 | +template <typename T, T... V> | |
31 | +struct chary; | |
32 | + | |
33 | +template <typename T, T... V> | |
34 | +struct valary { | |
35 | + using type = valary<T, V...>; | |
36 | + using value_type = T; | |
37 | + constexpr static size_t size = sizeof...(V); | |
38 | + | |
39 | + constexpr static T ary[size] = { V... }; | |
40 | +}; | |
41 | + | |
42 | +template <typename T, T... V> | |
43 | +struct chary { | |
44 | + using type = chary<T, V...>; | |
45 | + using value_type = T; | |
46 | + constexpr static size_t size = sizeof...(V) + 1; | |
47 | + | |
48 | + constexpr static T ary[size] = { V..., static_cast<T>(0) }; | |
49 | +}; | |
50 | + | |
20 | 51 | struct nil_type { |
21 | - using listp = std::true_type; | |
22 | 52 | }; |
23 | 53 | |
24 | 54 | template <> |
25 | 55 | struct any<nil_type> { |
56 | + using type = any<nil_type>; | |
26 | 57 | using value_type = nil_type; |
27 | - | |
28 | - using listp = nil_type::listp; | |
29 | 58 | }; |
30 | 59 | |
31 | 60 | template <typename T, T V> |
@@ -34,21 +63,30 @@ struct any<val<T, V>> { | ||
34 | 63 | using value_type = T; |
35 | 64 | }; |
36 | 65 | |
66 | +template <typename A, typename D> | |
67 | +struct any<cons<A, D>> { | |
68 | + using type = any<cons<A, D>>; | |
69 | + using value_type = cons<A, D>; | |
70 | +}; | |
71 | + | |
37 | 72 | } // detail |
38 | 73 | |
39 | 74 | using nil = detail::nil_type; |
40 | 75 | |
41 | - | |
76 | +// cons cell | |
42 | 77 | template <typename A, typename D = nil> |
43 | 78 | struct cons { |
79 | + using type = cons<A, D>; | |
80 | + using car_type = A; | |
81 | + using cdr_type = D; | |
82 | + | |
44 | 83 | using car = detail::any<A>; |
45 | 84 | using cdr = detail::any<D>; |
46 | 85 | |
47 | - using listp = std::true_type; | |
48 | - | |
49 | 86 | using car_t = typename car::value_type; |
50 | 87 | }; |
51 | 88 | |
89 | + | |
52 | 90 | template <typename T> |
53 | 91 | struct is_t : public std::true_type { }; |
54 | 92 |
@@ -62,43 +100,169 @@ template <> | ||
62 | 100 | struct is_nil<nil> : public std::true_type { }; |
63 | 101 | |
64 | 102 | template <typename T> |
65 | -struct consp : public std::false_type { }; | |
103 | +struct is_cons : public std::false_type { }; | |
66 | 104 | |
67 | 105 | template <typename T0, typename T1> |
68 | -struct consp<cons<T0, T1>> : std::true_type { }; | |
106 | +struct is_cons<cons<T0, T1>> : std::true_type { }; | |
107 | + | |
108 | +template <typename T> | |
109 | +struct is_atom : public std::true_type { }; | |
110 | + | |
111 | +template <typename T0, typename T1> | |
112 | +struct is_atom<cons<T0, T1>> : std::false_type { }; | |
113 | + | |
114 | +template <typename T> | |
115 | +struct is_list : public std::false_type { }; | |
116 | + | |
117 | +template <> | |
118 | +struct is_list<nil> : public std::true_type { }; | |
119 | + | |
120 | +template <typename T0, typename T1> | |
121 | +struct is_list<cons<T0, T1>> : public std::true_type { }; | |
122 | + | |
123 | +namespace detail { | |
124 | + | |
125 | +template <typename... T> | |
126 | +struct list_elem; | |
127 | + | |
128 | +template <typename T0, typename... Trail> | |
129 | +struct list_elem<T0, Trail...> { | |
130 | + using apply = cons<T0, typename list_elem<Trail...>::apply>; | |
131 | +}; | |
132 | + | |
133 | +template <> | |
134 | +struct list_elem<> { | |
135 | + using apply = nil; | |
136 | +}; | |
137 | + | |
138 | +} | |
139 | + | |
140 | +template <typename T> | |
141 | +struct car { | |
142 | + using apply = typename T::car_type; | |
143 | +}; | |
144 | + | |
145 | +template <> | |
146 | +struct car<nil> { | |
147 | + using apply = nil; | |
148 | +}; | |
149 | + | |
150 | +template <typename T> | |
151 | +struct cdr { | |
152 | + using apply = typename T::cdr_type; | |
153 | +}; | |
154 | + | |
155 | +template <> | |
156 | +struct cdr<nil> { | |
157 | + using apply = nil; | |
158 | +}; | |
159 | + | |
160 | +template <typename, typename> | |
161 | +struct eq : public nil { }; | |
162 | + | |
163 | +template <typename T> | |
164 | +struct eq<T, T> : public std::true_type { }; | |
165 | + | |
166 | +template <typename ...T> | |
167 | +struct list { | |
168 | + using type = list<T...>; | |
169 | + using apply = typename detail::list_elem<T...>::apply; | |
170 | +}; | |
171 | + | |
172 | +template <typename Cond, typename IfTrue, typename IfFalse = nil> | |
173 | +struct if_t { | |
174 | + using apply = typename std::conditional< | |
175 | + std::is_base_of<std::true_type, Cond>::value, | |
176 | + IfTrue, IfFalse>::type; | |
177 | +}; | |
69 | 178 | |
70 | 179 | } |
71 | 180 | |
181 | +void test_list() { | |
182 | + using namespace fmp; | |
183 | + using l_0 = list<>::apply; // (list) => nil | |
184 | + using l_int = list<int>::apply; // (list 'int) => (INT) | |
185 | + using l_2 = list<int, char>::apply; | |
186 | + using l_3 = list<int, char, float>::apply; | |
187 | + using l_4 = list<int, char, float, double>::apply; | |
188 | + | |
189 | + // empty list | |
190 | + static_assert(is_nil<l_0>::value, | |
191 | + "list<> == cons<nil, nil>"); | |
192 | + | |
193 | + // 1 node list | |
194 | + static_assert(eq<l_int, fmp::cons<int,fmp::nil>>::value, | |
195 | + "list<int> == cons<int,nil>"); | |
196 | + static_assert(eq<car<l_int>::apply, int>::value, | |
197 | + "car<l_int> == int"); | |
198 | + static_assert(is_nil<cdr<l_int>::apply>::value, | |
199 | + "cdr<l_int> == nil"); | |
200 | + | |
201 | + static_assert(eq<l_2, cons<int,cons<char,nil>>>::value, | |
202 | + "list<int,char> == cons<int,cons<char,nil>>"); | |
203 | + static_assert(eq<l_3, cons<int,cons<char,cons<float,nil>>>>::value, | |
204 | + "list<int, char, float> == cons<int,cons<char,cons<float,nil>>>"); | |
205 | +} | |
206 | + | |
72 | 207 | void test_any() { |
208 | + using namespace fmp; | |
73 | 209 | using any_int = fmp::detail::any<int>; |
74 | 210 | using any_int1 = fmp::detail::val<any_int::value_type, 1>; |
211 | + using c = fmp::cons<int, fmp::nil>; | |
212 | + using any_c = fmp::detail::any<c>; | |
213 | + using ary_int = fmp::detail::valary<int, 4, 5, 6, 42>; | |
214 | + using any_ai = fmp::detail::any<ary_int>; | |
75 | 215 | |
76 | - static_assert(std::is_same<any_int::value_type, int>::value, "any_int == int"); | |
216 | + static_assert(eq<any_int::value_type, int>::value, "any_int == int"); | |
77 | 217 | static_assert(any_int1::value == 1, "any_int<1> == 1"); |
218 | + | |
219 | + // cons | |
220 | + static_assert(eq<c::car_type, int>::value, "cons<int,nil>::car == int"); | |
221 | + static_assert(eq<any_c::value_type::car_type, int>::value, "anycons<int,nil>::car == int"); | |
222 | + static_assert(eq<any_c::value_type::cdr_type, fmp::nil>::value, "anycons<int,nil>::cdr == nil"); | |
223 | + | |
224 | + // array | |
225 | + static_assert(eq<any_ai::value_type, ary_int>::value, | |
226 | + "any<ary_int>::value_type == ary_int"); | |
227 | + static_assert(any_ai::value_type::size == 4, "any<ary_int>::size = 4"); | |
228 | + static_assert(any_ai::value_type::ary[0] == 4, "any<ary_int>::ary[0] = 4"); | |
229 | + static_assert(any_ai::value_type::ary[1] == 5, "any<ary_int>::ary[1] = 5"); | |
230 | + static_assert(any_ai::value_type::ary[2] == 6, "any<ary_int>::ary[2] = 6"); | |
231 | + static_assert(any_ai::value_type::ary[3] == 42, "any<ary_int>::ary[3] = 42"); | |
78 | 232 | } |
79 | 233 | |
80 | 234 | void test0() { |
235 | + using namespace fmp; | |
81 | 236 | using cint = fmp::cons<int>; |
82 | 237 | using int1 = fmp::detail::val<int, 1>; |
83 | 238 | static_assert(fmp::is_nil<fmp::nil>::value, "is_nil<nil> == true"); |
84 | 239 | static_assert(!(fmp::is_nil<fmp::cons<int>::car::value_type>::value), |
85 | 240 | "is_nil == false"); |
86 | 241 | |
87 | - static_assert(std::is_same<int1::value_type, int>::value, "int1 == int"); | |
242 | + static_assert(eq<int1::value_type, int>::value, "int1 == int"); | |
88 | 243 | static_assert(int1::value == 1, "val<int, 1> == 1"); |
89 | - static_assert(!fmp::consp<int>::value, "consp<int> != true"); | |
90 | - static_assert(fmp::consp<cint>::value, "consp<cint> == true"); | |
244 | + static_assert(!fmp::is_cons<int>::value, "is_cons<int> != true"); | |
245 | + static_assert(fmp::is_cons<cint>::value, "is_consp<cint> == true"); | |
91 | 246 | static_assert(fmp::is_nil<fmp::cons<fmp::nil>::car::value_type>::value, |
92 | 247 | "is_nil == true"); |
93 | - static_assert(std::is_same<fmp::cons<int>::cdr::value_type, fmp::nil>::value, | |
248 | + static_assert(eq<fmp::cons<int>::cdr::value_type, fmp::nil>::value, | |
94 | 249 | "single cons::cdr == nil_type"); |
250 | + | |
251 | + using vac = fmp::detail::valary<int, 0, 2, 4, 8>; | |
252 | + auto vals = vac::ary; | |
253 | + std::cout << "vals[1]:" << vals[1] << std::endl; | |
254 | + using cac = fmp::detail::chary<char, 'f', 'o', 'o'>; | |
255 | + const char* cs = cac::ary; | |
256 | + std::cout << "cs:" << cs[3] << std::endl; | |
95 | 257 | } |
96 | 258 | |
97 | 259 | int main(int, char**) { |
98 | 260 | using namespace fmp; |
99 | 261 | |
100 | 262 | using CarT = cons<int>; |
101 | - std::cout << "CarT:" << CarT::car_t() << std::endl; | |
263 | + std::cout << "CarT:" << CarT::car_type{3} << std::endl; | |
102 | 264 | |
265 | + test0(); | |
266 | + | |
103 | 267 | return 0; |
104 | 268 | } |