scm2cpp-learn 0.18.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scm2cpp_learn/__init__.py +3836 -0
- scm2cpp_learn/_classifiers.cp312-win_amd64.pyd +0 -0
- scm2cpp_learn/_compat.py +284 -0
- scm2cpp_learn/_generated/__init__.py +0 -0
- scm2cpp_learn/_generated/_loader.py +41 -0
- scm2cpp_learn/_generated/_loader_accel_cublas.py +173 -0
- scm2cpp_learn/_generated/_loader_classifiers.py +308 -0
- scm2cpp_learn/_generated/_loader_derived_blas.py +29 -0
- scm2cpp_learn/_generated/_loader_derived_cublas.py +29 -0
- scm2cpp_learn/_generated/_loader_derived_loops.py +29 -0
- scm2cpp_learn/_generated/_loader_gpu_cuda.py +313 -0
- scm2cpp_learn/_generated/_loader_gramops_blas.py +692 -0
- scm2cpp_learn/_generated/_loader_gramops_loops.py +711 -0
- scm2cpp_learn/_generated/_loader_nmf_blas.py +29 -0
- scm2cpp_learn/_generated/_loader_nmf_cublas.py +29 -0
- scm2cpp_learn/_generated/_loader_nmf_loops.py +29 -0
- scm2cpp_learn/_generated/accel_cublas/accel.cpp +24 -0
- scm2cpp_learn/_generated/accel_cublas/accel.hpp +1178 -0
- scm2cpp_learn/_generated/accel_cublas/accel_capi.cpp +76 -0
- scm2cpp_learn/_generated/classifiers.cpp +37 -0
- scm2cpp_learn/_generated/classifiers.hpp +3745 -0
- scm2cpp_learn/_generated/classifiers_capi.cpp +115 -0
- scm2cpp_learn/_generated/derived_blas/lasso_design.cpp +5 -0
- scm2cpp_learn/_generated/derived_blas/lasso_design.hpp +156 -0
- scm2cpp_learn/_generated/derived_blas/lasso_design_capi.cpp +19 -0
- scm2cpp_learn/_generated/derived_cublas/lasso_design.cpp +5 -0
- scm2cpp_learn/_generated/derived_cublas/lasso_design.hpp +158 -0
- scm2cpp_learn/_generated/derived_cublas/lasso_design_capi.cpp +19 -0
- scm2cpp_learn/_generated/derived_loops/lasso_design.cpp +5 -0
- scm2cpp_learn/_generated/derived_loops/lasso_design.hpp +179 -0
- scm2cpp_learn/_generated/derived_loops/lasso_design_capi.cpp +19 -0
- scm2cpp_learn/_generated/gpu_cuda/gpu.cpp +37 -0
- scm2cpp_learn/_generated/gpu_cuda/gpu.hpp +3846 -0
- scm2cpp_learn/_generated/gpu_cuda/gpu_capi.cpp +308 -0
- scm2cpp_learn/_generated/gramops_blas/gramops.cpp +82 -0
- scm2cpp_learn/_generated/gramops_blas/gramops.hpp +5411 -0
- scm2cpp_learn/_generated/gramops_blas/gramops_capi.cpp +244 -0
- scm2cpp_learn/_generated/gramops_loops/gramops.cpp +82 -0
- scm2cpp_learn/_generated/gramops_loops/gramops.hpp +6395 -0
- scm2cpp_learn/_generated/gramops_loops/gramops_capi.cpp +250 -0
- scm2cpp_learn/_generated/lasso_cov.cpp +7 -0
- scm2cpp_learn/_generated/lasso_cov.hpp +152 -0
- scm2cpp_learn/_generated/lasso_cov_capi.cpp +25 -0
- scm2cpp_learn/_generated/nmf_blas/nmf_cd.cpp +5 -0
- scm2cpp_learn/_generated/nmf_blas/nmf_cd.hpp +132 -0
- scm2cpp_learn/_generated/nmf_blas/nmf_cd_capi.cpp +19 -0
- scm2cpp_learn/_generated/nmf_cublas/nmf_cd.cpp +5 -0
- scm2cpp_learn/_generated/nmf_cublas/nmf_cd.hpp +136 -0
- scm2cpp_learn/_generated/nmf_cublas/nmf_cd_capi.cpp +19 -0
- scm2cpp_learn/_generated/nmf_loops/nmf_cd.cpp +5 -0
- scm2cpp_learn/_generated/nmf_loops/nmf_cd.hpp +167 -0
- scm2cpp_learn/_generated/nmf_loops/nmf_cd_capi.cpp +19 -0
- scm2cpp_learn/_generated/scm2cpp-blas.hpp +158 -0
- scm2cpp_learn/_generated/scm2cpp-cublas.hpp +155 -0
- scm2cpp_learn/_generated/scm2cpp-cuda.hpp +285 -0
- scm2cpp_learn/_generated/scm2cpp.hpp +1627 -0
- scm2cpp_learn/_gramops_blas.cp312-win_amd64.pyd +0 -0
- scm2cpp_learn/_lasso_cov.cp312-win_amd64.pyd +0 -0
- scm2cpp_learn/_lasso_derived_blas.cp312-win_amd64.pyd +0 -0
- scm2cpp_learn/_libfind.py +153 -0
- scm2cpp_learn/_nmf_blas.cp312-win_amd64.pyd +0 -0
- scm2cpp_learn/batch_capi.cu +428 -0
- scm2cpp_learn-0.18.0.dist-info/DELVEWHEEL +2 -0
- scm2cpp_learn-0.18.0.dist-info/METADATA +1171 -0
- scm2cpp_learn-0.18.0.dist-info/RECORD +72 -0
- scm2cpp_learn-0.18.0.dist-info/WHEEL +5 -0
- scm2cpp_learn-0.18.0.dist-info/top_level.txt +1 -0
- scm2cpp_learn.libs/.load-order-scm2cpp_learn-0.18.0 +4 -0
- scm2cpp_learn.libs/libopenblas-0486735c359a67419d8832e3c40e2837.dll +4 -0
- scm2cpp_learn.libs/msvcp140-73438573e87f9a2fd944b01def13566d.dll +0 -0
- scm2cpp_learn.libs/vcruntime140-052ad6a20d375957e82aa6a3c441ea54.dll +0 -0
- scm2cpp_learn.libs/vcruntime140_1-a198370e11c6e7469d1cf0ef5b3f433d.dll +0 -0
|
@@ -0,0 +1,1627 @@
|
|
|
1
|
+
#ifndef SCM2CPP
|
|
2
|
+
#define SCM2CPP
|
|
3
|
+
|
|
4
|
+
#include <iostream>
|
|
5
|
+
#include <vector>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <list>
|
|
8
|
+
#include <map>
|
|
9
|
+
#include <algorithm>
|
|
10
|
+
#include <limits>
|
|
11
|
+
#include <array>
|
|
12
|
+
#include <cmath>
|
|
13
|
+
#include <cstdarg>
|
|
14
|
+
|
|
15
|
+
// Marks a function compilable for both host and device. Under nvcc it
|
|
16
|
+
// expands to the CUDA qualifiers; everywhere else to nothing, so the
|
|
17
|
+
// same generated text serves both toolchains. The translator applies
|
|
18
|
+
// it only to functions whose bodies stay inside the device-safe subset.
|
|
19
|
+
#if defined(__CUDACC__)
|
|
20
|
+
#define SCM2CPP_FN __host__ __device__
|
|
21
|
+
#else
|
|
22
|
+
#define SCM2CPP_FN
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
//#include <type_traits>
|
|
26
|
+
#include <functional>
|
|
27
|
+
|
|
28
|
+
#ifndef SCM2CPP_MINIMAL // the full-feature runtime: everything a numeric kernel never touches
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#include <boost/function.hpp>
|
|
32
|
+
#include <boost/functional.hpp>
|
|
33
|
+
|
|
34
|
+
//#include <boost/thread.hpp>
|
|
35
|
+
|
|
36
|
+
#include <boost/typeof/typeof.hpp>
|
|
37
|
+
#include <boost/type_traits.hpp>
|
|
38
|
+
#include <boost/utility/result_of.hpp>
|
|
39
|
+
#include <boost/function_types/result_type.hpp>
|
|
40
|
+
#include <boost/function_types/parameter_types.hpp>
|
|
41
|
+
#include <boost/function_types/function_type.hpp>
|
|
42
|
+
|
|
43
|
+
#include <boost/preprocessor.hpp>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
#include <boost/utility/enable_if.hpp>
|
|
47
|
+
|
|
48
|
+
#include <boost/mpl/vector.hpp>
|
|
49
|
+
#include <boost/mpl/contains.hpp>
|
|
50
|
+
#include <boost/mpl/transform.hpp>
|
|
51
|
+
#include <boost/mpl/insert_range.hpp>
|
|
52
|
+
#include <boost/mpl/identity.hpp>
|
|
53
|
+
#include <boost/mpl/logical.hpp>
|
|
54
|
+
|
|
55
|
+
#include <boost/mpl/less.hpp>
|
|
56
|
+
#include <boost/mpl/comparison.hpp>
|
|
57
|
+
#include <boost/mpl/filter_view.hpp>
|
|
58
|
+
#include <boost/mpl/sizeof.hpp>
|
|
59
|
+
#include <boost/mpl/vector.hpp>
|
|
60
|
+
#include <boost/mpl/sort.hpp>
|
|
61
|
+
#include <boost/mpl/equal.hpp>
|
|
62
|
+
#include <boost/mpl/assert.hpp>
|
|
63
|
+
#include <boost/mpl/if.hpp>
|
|
64
|
+
#include <boost/mpl/set.hpp>
|
|
65
|
+
#include <boost/mpl/empty.hpp>
|
|
66
|
+
#include <boost/mpl/unique.hpp>
|
|
67
|
+
|
|
68
|
+
//#include <boost/fusion/iterator.hpp>
|
|
69
|
+
//#include <boost/fusion/include/iterator.hpp>
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#include <boost/fusion/container/vector.hpp>
|
|
73
|
+
#include <boost/fusion/algorithm.hpp>
|
|
74
|
+
#include <boost/fusion/sequence.hpp>
|
|
75
|
+
#include <boost/fusion/include/list.hpp>
|
|
76
|
+
#include <boost/fusion/include/vector.hpp>
|
|
77
|
+
|
|
78
|
+
#include <boost/fusion/container/list/cons.hpp>
|
|
79
|
+
#include <boost/fusion/include/cons.hpp>
|
|
80
|
+
#include <boost/fusion/include/make_cons.hpp>
|
|
81
|
+
#include <boost/fusion/container/generation/make_cons.hpp>
|
|
82
|
+
#include <boost/fusion/container/generation/make_list.hpp>
|
|
83
|
+
#include <boost/fusion/include/make_list.hpp>
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
#include <boost/fusion/iterator/iterator_facade.hpp>
|
|
87
|
+
#include <boost/fusion/include/iterator_facade.hpp>
|
|
88
|
+
|
|
89
|
+
#include <boost/fusion/algorithm/auxiliary/copy.hpp>
|
|
90
|
+
#include <boost/fusion/include/copy.hpp>
|
|
91
|
+
|
|
92
|
+
#include <boost/fusion/algorithm/transformation/push_front.hpp>
|
|
93
|
+
#include <boost/fusion/include/push_front.hpp>
|
|
94
|
+
|
|
95
|
+
#include <boost/fusion/algorithm/transformation/push_back.hpp>
|
|
96
|
+
#include <boost/fusion/include/push_back.hpp>
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
#include <boost/variant.hpp>
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
#define null_P scm2cpp::is_null
|
|
103
|
+
#define eq_P scm2cpp::is_eq
|
|
104
|
+
#define eqv_P scm2cpp::is_eqv
|
|
105
|
+
#define equal_P scm2cpp::is_equal
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
#define CONSED_AS_STD_PAIR 1
|
|
111
|
+
#if CONSED_AS_STD_PAIR
|
|
112
|
+
#define consd std::pair
|
|
113
|
+
#endif
|
|
114
|
+
|
|
115
|
+
// #include <boost/intrusive/slist.hpp>
|
|
116
|
+
// #include <boost/intrusive/list.hpp>
|
|
117
|
+
// #include <boost/intrusive/list_hook.hpp>
|
|
118
|
+
|
|
119
|
+
namespace scm2cpp
|
|
120
|
+
{
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
typedef boost::fusion::nil nil_type;
|
|
127
|
+
typedef boost::fusion::nil nil;
|
|
128
|
+
typedef boost::fusion::nil null_type;
|
|
129
|
+
|
|
130
|
+
//nil_type null;
|
|
131
|
+
nil_type null();
|
|
132
|
+
//nil_type nil();
|
|
133
|
+
//nil_type & nil = null;
|
|
134
|
+
|
|
135
|
+
typedef std::string string_type;
|
|
136
|
+
|
|
137
|
+
struct symbol_type : public string_type
|
|
138
|
+
{ symbol_type(string_type & st) : string_type(st) {}
|
|
139
|
+
symbol_type(char *c) : string_type(c) {} };
|
|
140
|
+
|
|
141
|
+
inline symbol_type string_to_symbol(string_type &st){return symbol_type(st);}
|
|
142
|
+
inline string_type symbol_to_string(symbol_type &st){return st;}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
typedef boost::mpl::vector<char,int,short,long,float,double,bool> c_number_types;
|
|
146
|
+
// Exact rationals, replacing rational: the four
|
|
147
|
+
// operations, normalization with the sign on the numerator, and
|
|
148
|
+
// ordering by cross-multiplication -- what the number-type order
|
|
149
|
+
// and eqv need, and nothing else.
|
|
150
|
+
struct rational {
|
|
151
|
+
int num, den;
|
|
152
|
+
static int gcd_(int a, int b)
|
|
153
|
+
{ while (b) { int t = a % b; a = b; b = t; } return a < 0 ? -a : a; }
|
|
154
|
+
rational(int n = 0, int d = 1) : num(n), den(d) {
|
|
155
|
+
if (den < 0) { num = -num; den = -den; }
|
|
156
|
+
int g = gcd_(num, den); if (g > 1) { num /= g; den /= g; }
|
|
157
|
+
}
|
|
158
|
+
rational operator+(const rational& o) const
|
|
159
|
+
{ return rational(num*o.den + o.num*den, den*o.den); }
|
|
160
|
+
rational operator-(const rational& o) const
|
|
161
|
+
{ return rational(num*o.den - o.num*den, den*o.den); }
|
|
162
|
+
rational operator*(const rational& o) const
|
|
163
|
+
{ return rational(num*o.num, den*o.den); }
|
|
164
|
+
rational operator/(const rational& o) const
|
|
165
|
+
{ return rational(num*o.den, den*o.num); }
|
|
166
|
+
bool operator==(const rational& o) const
|
|
167
|
+
{ return num == o.num && den == o.den; }
|
|
168
|
+
bool operator<(const rational& o) const
|
|
169
|
+
{ return (long long)num*o.den < (long long)o.num*den; }
|
|
170
|
+
explicit operator double() const { return (double)num / den; }
|
|
171
|
+
};
|
|
172
|
+
inline std::ostream& operator<<(std::ostream& os, const rational& r)
|
|
173
|
+
{ return os << r.num << "/" << r.den; }
|
|
174
|
+
|
|
175
|
+
typedef boost::mpl::vector<rational,std::complex<double> > not_c_number_types;
|
|
176
|
+
typedef boost::mpl::insert_range<c_number_types,boost::mpl::end<c_number_types>::type,not_c_number_types>::type number_types;
|
|
177
|
+
|
|
178
|
+
typedef boost::mpl::push_back<number_types,string_type>::type number_string_types;
|
|
179
|
+
typedef boost::mpl::push_back<number_types,symbol_type>::type number_symbol_types;
|
|
180
|
+
typedef boost::mpl::push_back<number_string_types,symbol_type>::type number_string_symbol_types;
|
|
181
|
+
typedef boost::mpl::push_back<not_c_number_types,string_type>::type not_c_number_string_types;
|
|
182
|
+
typedef boost::mpl::push_back<not_c_number_string_types,symbol_type>::type not_c_number_string_symbol_types;
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
template<typename Base
|
|
186
|
+
, class Enable = void
|
|
187
|
+
>
|
|
188
|
+
struct quoted
|
|
189
|
+
: Base
|
|
190
|
+
{ Base & value; quoted(Base & base):Base(base),value(base) {} };
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
template<typename Base
|
|
194
|
+
//, class Enable = void
|
|
195
|
+
//,typename boost::disable_if<boost::is_arithmetic<Base> >::type
|
|
196
|
+
>
|
|
197
|
+
//struct quoted
|
|
198
|
+
struct quoted<Base
|
|
199
|
+
,typename boost::disable_if<boost::is_arithmetic<Base> >::type>
|
|
200
|
+
: Base
|
|
201
|
+
{ Base & value; quoted(Base & base):Base(base),value(base) {} };
|
|
202
|
+
|
|
203
|
+
template<typename Base>
|
|
204
|
+
struct quoted<Base
|
|
205
|
+
,typename boost::enable_if<boost::is_arithmetic<Base> >::type>
|
|
206
|
+
#if 0
|
|
207
|
+
:
|
|
208
|
+
less_than_comparable < quoted<Base>,
|
|
209
|
+
equality_comparable < quoted<Base>,
|
|
210
|
+
less_than_comparable2 < quoted<Base>, Base,
|
|
211
|
+
equality_comparable2 < quoted<Base>, Base,
|
|
212
|
+
addable < quoted<Base>,
|
|
213
|
+
subtractable < quoted<Base>,
|
|
214
|
+
multipliable < quoted<Base>,
|
|
215
|
+
dividable < quoted<Base>,
|
|
216
|
+
addable2 < quoted<Base>, Base,
|
|
217
|
+
subtractable2 < quoted<Base>, Base,
|
|
218
|
+
subtractable2_left < quoted<Base>, Base,
|
|
219
|
+
multipliable2 < quoted<Base>, Base,
|
|
220
|
+
dividable2 < quoted<Base>, Base,
|
|
221
|
+
dividable2_left < quoted<Base>, Base,
|
|
222
|
+
incrementable < quoted<Base>,
|
|
223
|
+
decrementable < quoted<Base>
|
|
224
|
+
> > > > > > > > > > > > > > > >
|
|
225
|
+
#endif
|
|
226
|
+
: boost::operators<quoted<Base> >
|
|
227
|
+
{
|
|
228
|
+
Base value;
|
|
229
|
+
quoted(Base base):value(base) {}
|
|
230
|
+
bool operator<(const quoted<Base>& x) const { return value < x.value; }
|
|
231
|
+
bool operator==(const quoted<Base>& x) const { return value == x.value; }
|
|
232
|
+
quoted<Base>& operator+=(const quoted<Base>& x) { value+=x.value; return *this; }
|
|
233
|
+
quoted<Base>& operator-=(const quoted<Base>& x) { value-=x.value; return *this; }
|
|
234
|
+
quoted<Base>& operator*=(const quoted<Base>& x) { value*=x.value; return *this; }
|
|
235
|
+
quoted<Base>& operator/=(const quoted<Base>& x) { value/=x.value; return *this; }
|
|
236
|
+
quoted<Base>& operator%=(const quoted<Base>& x) { value%=x.value; return *this; }
|
|
237
|
+
quoted<Base>& operator|=(const quoted<Base>& x) { value|=x.value; return *this; }
|
|
238
|
+
quoted<Base>& operator&=(const quoted<Base>& x) { value&=x.value; return *this; }
|
|
239
|
+
quoted<Base>& operator^=(const quoted<Base>& x) { value^=x.value; return *this; }
|
|
240
|
+
quoted<Base>& operator++() { ++value; return *this; }
|
|
241
|
+
quoted<Base>& operator--() { --value; return *this; }
|
|
242
|
+
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
template<typename Base> quoted<Base> quote(Base &base){return quoted<Base>(base); }
|
|
248
|
+
|
|
249
|
+
template<typename Base> quoted<Base>
|
|
250
|
+
quote(Base base,typename boost::enable_if<boost::is_arithmetic<Base>, Base>::type* = 0)
|
|
251
|
+
{return quoted<Base>(base);}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
template<typename Base>
|
|
256
|
+
struct unquoted
|
|
257
|
+
{ Base & value;
|
|
258
|
+
unquoted(Base &base):value(base)
|
|
259
|
+
{} };
|
|
260
|
+
|
|
261
|
+
template<typename Base> unquoted<Base> unquote(Base &base){return unquoted<Base>(base); }
|
|
262
|
+
|
|
263
|
+
template<typename Base>
|
|
264
|
+
struct quasiquoted
|
|
265
|
+
{ Base & value;
|
|
266
|
+
quasiquoted(Base &base):value(base)
|
|
267
|
+
{} };
|
|
268
|
+
|
|
269
|
+
template<typename Base> quasiquoted <Base> quasiquote(Base &base){return quasiquoted<Base>(base); }
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
#if 1
|
|
273
|
+
typedef boost::mpl::transform< number_string_types,quoted<boost::mpl::_1> >::type quoted_number_string_types ;
|
|
274
|
+
typedef boost::mpl::insert_range<quoted_number_string_types,
|
|
275
|
+
boost::mpl::end<quoted_number_string_types>::type,
|
|
276
|
+
number_string_symbol_types>::type value_types;
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
typedef boost::mpl::transform< number_types,quoted<boost::mpl::_1> >::type quoted_number_types ;
|
|
280
|
+
typedef boost::mpl::insert_range<quoted_number_types,
|
|
281
|
+
boost::mpl::end<quoted_number_types>::type,
|
|
282
|
+
number_symbol_types>::type scalar_types;
|
|
283
|
+
|
|
284
|
+
typedef boost::mpl::vector<char,int,short,long> int_types;
|
|
285
|
+
typedef boost::mpl::transform<int_types, quoted<boost::mpl::_1> >::type quoted_int_types ;
|
|
286
|
+
typedef boost::mpl::insert_range<quoted_int_types,
|
|
287
|
+
boost::mpl::end<quoted_int_types>::type,
|
|
288
|
+
int_types>::type int_quote_types;
|
|
289
|
+
#endif
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
/////////////////////////list begin///////////////////////////////////
|
|
294
|
+
|
|
295
|
+
#if CONSED_AS_STD_PAIR
|
|
296
|
+
#else
|
|
297
|
+
template<typename C ,typename D> struct
|
|
298
|
+
consed : std::pair<C,D> {};
|
|
299
|
+
#endif
|
|
300
|
+
#if 0
|
|
301
|
+
template<typename Seqs ,typename Last> struct
|
|
302
|
+
appended : std::pair<Seqs,Last> {};
|
|
303
|
+
#else
|
|
304
|
+
template<typename Seqs> struct
|
|
305
|
+
appended
|
|
306
|
+
{
|
|
307
|
+
Seqs &value;
|
|
308
|
+
appended(const Seqs & seqs):value(seqs){}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
#endif
|
|
312
|
+
|
|
313
|
+
//s8vector signed exact integer in the range -(2^7) to (2^7)-1
|
|
314
|
+
// u8vector unsigned exact integer in the range 0 to (2^8)-1
|
|
315
|
+
// s16vector signed exact integer in the range -(2^15) to (2^15)-1
|
|
316
|
+
// u16vector unsigned exact integer in the range 0 to (2^16)-1
|
|
317
|
+
// s32vector signed exact integer in the range -(2^31) to (2^31)-1
|
|
318
|
+
// u32vector unsigned exact integer in the range 0 to (2^32)-1
|
|
319
|
+
// s64vector signed exact integer in the range -(2^63) to (2^63)-1
|
|
320
|
+
// u64vector unsigned exact integer in the range 0 to (2^64)-1
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
template<typename T> struct is_uniform_sequence :public boost::mpl::false_ {};
|
|
327
|
+
template<> struct is_uniform_sequence<std::string > :public boost::mpl::true_ {};
|
|
328
|
+
template<typename T> struct is_uniform_sequence<std::vector<T> > :public boost::mpl::true_ {};
|
|
329
|
+
template<typename T> struct is_uniform_sequence<std::list<T> > :public boost::mpl::true_ {};
|
|
330
|
+
template<typename T,std::size_t N> struct is_uniform_sequence<std::array<T,N> > :public boost::mpl::true_ {};
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
template<typename T,typename E> struct is_uniform_sequence_of :public boost::mpl::false_ {};
|
|
334
|
+
template<> struct is_uniform_sequence_of<std::string,char> :public boost::mpl::true_ {};
|
|
335
|
+
template<typename T> struct is_uniform_sequence_of<std::vector<T>,T> :public boost::mpl::true_ {};
|
|
336
|
+
template<typename T> struct is_uniform_sequence_of<std::list<T>,T> :public boost::mpl::true_ {};
|
|
337
|
+
template<typename T,std::size_t N> struct is_uniform_sequence_of<std::array<T,N>,T> :public boost::mpl::true_ {};
|
|
338
|
+
|
|
339
|
+
// cons and cdr on a uniform sequence used to answer with a
|
|
340
|
+
// boost::ptr_container view sharing the caller's storage; without
|
|
341
|
+
// boost they answer with a std::list copy, which is the persistent
|
|
342
|
+
// semantics Scheme meant anyway.
|
|
343
|
+
template<typename T> struct uniform_sequence_to_boost_ptr_sequence_view {typedef T type;};
|
|
344
|
+
template<typename T> struct uniform_sequence_to_boost_ptr_sequence_view<std::vector<T> >
|
|
345
|
+
{typedef std::list<T> type; };
|
|
346
|
+
template<typename T,std::size_t N> struct uniform_sequence_to_boost_ptr_sequence_view<std::array<T,N> >
|
|
347
|
+
{typedef std::list<T> type; };
|
|
348
|
+
|
|
349
|
+
template<typename T> struct
|
|
350
|
+
uniform_sequence_value_type
|
|
351
|
+
{typedef typename T::value_type type;};
|
|
352
|
+
template<typename C,typename D> struct
|
|
353
|
+
uniform_sequence_value_type<std::pair<C,D> >
|
|
354
|
+
{typedef C type;};
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
template<typename T> struct
|
|
358
|
+
is_sequence : boost::mpl::or_<
|
|
359
|
+
boost::fusion::traits::is_sequence<T>
|
|
360
|
+
,is_uniform_sequence<T>
|
|
361
|
+
>{};
|
|
362
|
+
|
|
363
|
+
template<typename T> struct is_std_pair : boost::mpl::false_ {};
|
|
364
|
+
template<typename C,typename D> struct is_std_pair<std::pair<C,D> > : boost::mpl::true_ {};
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
template<typename T> struct
|
|
368
|
+
is_pair_type : boost::mpl::or_<
|
|
369
|
+
is_sequence<T>
|
|
370
|
+
,is_std_pair<T>
|
|
371
|
+
>{};
|
|
372
|
+
template<> struct
|
|
373
|
+
is_pair_type<nil_type> : boost::mpl::false_ {};
|
|
374
|
+
template<typename T> bool is_pair(const T& dummy){return is_pair_type<T>::value; }
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
template<typename T> struct
|
|
378
|
+
is_list_type : is_sequence<T> {};
|
|
379
|
+
template<typename C,typename D> struct
|
|
380
|
+
is_list_type<std::pair<C,D> > : is_list_type<D> {};
|
|
381
|
+
template<typename T> bool is_list(const T& dummy){return is_list_type<T>::value;}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
template<typename T> struct
|
|
387
|
+
is_subst_ref_object :public
|
|
388
|
+
boost::mpl::or_<
|
|
389
|
+
boost::is_array<T>
|
|
390
|
+
,boost::fusion::traits::is_sequence<T>
|
|
391
|
+
,is_uniform_sequence<T>
|
|
392
|
+
>{};
|
|
393
|
+
template<typename C,typename D> struct
|
|
394
|
+
is_subst_ref_object<std::pair<C,D> > :public boost::mpl::true_ {};
|
|
395
|
+
template<typename C,typename D> struct
|
|
396
|
+
is_subst_ref_object<std::map<C,D> > :public boost::mpl::true_ {};
|
|
397
|
+
|
|
398
|
+
template<typename T> struct
|
|
399
|
+
is_subst_copy_object :public boost::mpl::not_<is_subst_ref_object<T> > {};
|
|
400
|
+
|
|
401
|
+
template<typename T> struct to_subst_type : boost::mpl::if_<
|
|
402
|
+
is_subst_copy_object<T>
|
|
403
|
+
,boost::mpl::identity<T>
|
|
404
|
+
,boost::add_reference<T>
|
|
405
|
+
>::type {};
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
inline bool is_null(const nil_type & dummy){return true;}
|
|
409
|
+
template<typename T> bool is_null(const std::list<T> & l){return (l.size()==0);}
|
|
410
|
+
template<typename T> bool is_null(const std::vector<T> & l){return (l.size()==0);}
|
|
411
|
+
template<typename T> bool is_null(const T & dummy){return false;}
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
template<typename C, typename D> std::pair<
|
|
416
|
+
typename to_subst_type<C>::type
|
|
417
|
+
,typename to_subst_type<D>::type>
|
|
418
|
+
cons(const C & c,const D & d
|
|
419
|
+
,typename boost::disable_if<boost::mpl::or_<
|
|
420
|
+
boost::fusion::traits::is_sequence<D>
|
|
421
|
+
,is_uniform_sequence_of<D,C>
|
|
422
|
+
> > ::type* =0
|
|
423
|
+
){return std::pair<
|
|
424
|
+
typename to_subst_type<C>::type
|
|
425
|
+
,typename to_subst_type<D>::type
|
|
426
|
+
> (const_cast<C &>(c),const_cast<D &>(d)); }
|
|
427
|
+
#if 1
|
|
428
|
+
template <typename T,typename Sequence>
|
|
429
|
+
boost::fusion::cons<typename to_subst_type<T>::type,Sequence >
|
|
430
|
+
cons(const T & e,
|
|
431
|
+
const Sequence & seq
|
|
432
|
+
,typename boost::enable_if<
|
|
433
|
+
boost::fusion::traits::is_sequence<Sequence>
|
|
434
|
+
> ::type* = 0
|
|
435
|
+
){ return boost::fusion::cons<typename to_subst_type<T>::type,Sequence >(e,seq);}
|
|
436
|
+
#else
|
|
437
|
+
template <typename T,typename Sequence>
|
|
438
|
+
typename boost::fusion::result_of::as_list<
|
|
439
|
+
typename boost::fusion::result_of::push_front<
|
|
440
|
+
Sequence,
|
|
441
|
+
typename to_subst_type<T>::type
|
|
442
|
+
>::type
|
|
443
|
+
>::type
|
|
444
|
+
cons(T & e,
|
|
445
|
+
Sequence &seq
|
|
446
|
+
,typename boost::enable_if<
|
|
447
|
+
boost::fusion::traits::is_sequence<Sequence>
|
|
448
|
+
> ::type* = 0
|
|
449
|
+
){ return boost::fusion::push_front<
|
|
450
|
+
Sequence,
|
|
451
|
+
typename to_subst_type<T>::type
|
|
452
|
+
>(seq, e);}
|
|
453
|
+
#endif
|
|
454
|
+
|
|
455
|
+
template <typename T>
|
|
456
|
+
std::list<T>
|
|
457
|
+
cons(const T & e,const nil_type & seq){
|
|
458
|
+
std::list<T> l;
|
|
459
|
+
l.push_front(e);
|
|
460
|
+
return l;}
|
|
461
|
+
|
|
462
|
+
template<typename C, typename D>
|
|
463
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<D>::type
|
|
464
|
+
cons(C e
|
|
465
|
+
,const D & d
|
|
466
|
+
,typename boost::enable_if<boost::mpl::and_<
|
|
467
|
+
is_subst_copy_object<C>
|
|
468
|
+
,is_uniform_sequence_of<D,C>
|
|
469
|
+
> >::type* = 0
|
|
470
|
+
){typename uniform_sequence_to_boost_ptr_sequence_view<D>::type
|
|
471
|
+
l(d.begin(),d.end()); l.push_front(e); return l;}
|
|
472
|
+
|
|
473
|
+
template<typename C, typename D>
|
|
474
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<D>::type
|
|
475
|
+
cons(C & e
|
|
476
|
+
,const D & d
|
|
477
|
+
,typename boost::enable_if<boost::mpl::and_<
|
|
478
|
+
is_subst_ref_object<C>
|
|
479
|
+
,is_uniform_sequence_of<D,C>
|
|
480
|
+
> >::type* = 0
|
|
481
|
+
){typename uniform_sequence_to_boost_ptr_sequence_view<D>::type
|
|
482
|
+
l(d.begin(),d.end()); l.push_front(e); return l;}
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
template<typename T> std::list<T>
|
|
486
|
+
make_uniform_list(const int n,const T & x)
|
|
487
|
+
{return std::list<T>(n,x);}
|
|
488
|
+
|
|
489
|
+
template<typename T> std::vector<T>
|
|
490
|
+
make_uniform_vector(const int n,const T & x)
|
|
491
|
+
{return std::vector<T>(n,x) ;}
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
template<typename T> const T* cdr(const T l[]){return l+1;}
|
|
495
|
+
|
|
496
|
+
template<typename C, typename D> D
|
|
497
|
+
cdr(const std::pair<C,D> & seq){return seq.second;}
|
|
498
|
+
|
|
499
|
+
template<typename Seq>
|
|
500
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<Seq>::type
|
|
501
|
+
cdr(const Seq & seq
|
|
502
|
+
,typename boost::enable_if<is_uniform_sequence<Seq> >::type* = 0 ){
|
|
503
|
+
typename Seq::const_iterator i=seq.begin();i++;
|
|
504
|
+
return
|
|
505
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<Seq>::type(i,seq.end());
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
template <typename Sequence>
|
|
510
|
+
typename Sequence::cdr_type
|
|
511
|
+
//boost::fusion::cons<Sequence>::cdr_type
|
|
512
|
+
cdr( Sequence & seq
|
|
513
|
+
,typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence> >::type* = 0
|
|
514
|
+
){return seq.cdr; }
|
|
515
|
+
|
|
516
|
+
#if 0
|
|
517
|
+
///////dummy for list_ref
|
|
518
|
+
template <typename Sequence> Sequence
|
|
519
|
+
cdr(const Sequence & seq
|
|
520
|
+
,typename boost::disable_if<boost::mpl::or_<
|
|
521
|
+
boost::fusion::traits::is_sequence<Sequence>
|
|
522
|
+
,is_uniform_sequence<Sequence> >
|
|
523
|
+
>::type* = 0
|
|
524
|
+
){ return seq;}
|
|
525
|
+
#endif
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
template<typename L, typename T> void
|
|
529
|
+
set_cdr(const L & l, const T & t){&cdr(l)=t;}
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
template<typename T> const T* car_pointer(const T l[]){return l;}
|
|
533
|
+
template<typename C, typename D> const C* car_pointer(const std::pair<C,D> & seq){return &seq.first;}
|
|
534
|
+
template <typename Sequence> typename Sequence::const_iterator
|
|
535
|
+
//typename boost::enable_if< is_uniform_sequence<Sequence>, typename Sequence::iterator>::type
|
|
536
|
+
car_pointer(const Sequence & seq
|
|
537
|
+
,typename boost::enable_if<is_uniform_sequence<Sequence> >::type* = 0
|
|
538
|
+
){return seq.begin();}
|
|
539
|
+
template <typename Sequence> typename boost::fusion::result_of::begin<Sequence const>::type
|
|
540
|
+
car_pointer(const Sequence & seq
|
|
541
|
+
,typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence> >::type* = 0
|
|
542
|
+
){return boost::fusion::begin(seq);}
|
|
543
|
+
|
|
544
|
+
template<typename T> T car(const T l[]){return l[0];}
|
|
545
|
+
template<typename C, typename D> const C car(const std::pair<C,D> & seq){return seq.first;}
|
|
546
|
+
template <typename Sequence> typename Sequence::iterator::value_type
|
|
547
|
+
car(Sequence & seq
|
|
548
|
+
,typename boost::enable_if<is_uniform_sequence<Sequence> >::type* = 0
|
|
549
|
+
){return *seq.begin();}
|
|
550
|
+
// A const-reference overload so that temporaries can be passed. ptr_list
|
|
551
|
+
// has value_type T*, so use iterator::value_type as the non-const one does.
|
|
552
|
+
template <typename Sequence> typename Sequence::iterator::value_type
|
|
553
|
+
car(const Sequence & seq
|
|
554
|
+
,typename boost::enable_if<is_uniform_sequence<Sequence> >::type* = 0
|
|
555
|
+
){return *seq.begin();}
|
|
556
|
+
template <typename Sequence>
|
|
557
|
+
//typename Sequence::car_type
|
|
558
|
+
typename boost::fusion::result_of::value_of<typename boost::fusion::result_of::begin<Sequence const>::type>::type
|
|
559
|
+
car(const Sequence & seq
|
|
560
|
+
,typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence> >::type* = 0
|
|
561
|
+
){
|
|
562
|
+
//return seq.car;
|
|
563
|
+
return boost::fusion::deref(boost::fusion::begin(seq));
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
#if 0
|
|
567
|
+
///////dummy for list_ref
|
|
568
|
+
template <typename Sequence> Sequence
|
|
569
|
+
car(const Sequence & seq
|
|
570
|
+
,typename boost::disable_if<boost::mpl::or_<
|
|
571
|
+
boost::fusion::traits::is_sequence<Sequence>
|
|
572
|
+
,is_uniform_sequence<Sequence> >
|
|
573
|
+
>::type* = 0
|
|
574
|
+
){ return seq;}
|
|
575
|
+
#endif
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
template<typename L, typename T> void
|
|
579
|
+
set_car(const L & l, const T & t){*car_pointer(l)=t;}
|
|
580
|
+
|
|
581
|
+
template<typename T> const T* list_ref_pointer(const T l[] ,int n ){return l+n;}
|
|
582
|
+
template<typename T> T list_ref(const T l[] ,int n ){return l[n];}
|
|
583
|
+
template<typename T> T list_ref(const std::vector<T> & l ,const int &n ){ return l[n];}
|
|
584
|
+
#if 0
|
|
585
|
+
template <typename Sequence> typename Sequence::iterator
|
|
586
|
+
list_ref_pointer(Sequence & seq,std::size_t n
|
|
587
|
+
,typename boost::enable_if<is_uniform_sequence<Sequence> >::type* = 0){
|
|
588
|
+
typename Sequence ::iterator it = seq.begin();
|
|
589
|
+
std::advance(it, n);
|
|
590
|
+
return it;}
|
|
591
|
+
template <typename Sequence> typename Sequence::iterator::value_type
|
|
592
|
+
list_ref(Sequence & seq,std::size_t n
|
|
593
|
+
,typename boost::enable_if<is_uniform_sequence<Sequence> >::type* = 0)
|
|
594
|
+
{return *list_ref_pointer(seq,n);}
|
|
595
|
+
#else
|
|
596
|
+
template<typename T>
|
|
597
|
+
typename std::list<T>::const_iterator
|
|
598
|
+
list_ref_pointer(const std::list<T> & l ,const int & n ){
|
|
599
|
+
typename std::list<T>::const_iterator it = l.begin();
|
|
600
|
+
std::advance(it, n);return it;}
|
|
601
|
+
template<typename T> T
|
|
602
|
+
list_ref(const std::list<T> & l ,const int &n ){
|
|
603
|
+
return *list_ref_pointer(l ,n );}
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
template<typename T>
|
|
607
|
+
typename std::vector<T>::const_iterator
|
|
608
|
+
list_ref_pointer(const std::vector<T> & l ,const int & n ){
|
|
609
|
+
typename std::vector<T>::const_iterator it = l.begin();
|
|
610
|
+
std::advance(it, n);
|
|
611
|
+
return it;}
|
|
612
|
+
#endif
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
#if 0
|
|
617
|
+
#if 0
|
|
618
|
+
template <typename Ret,typename Sequence> Ret
|
|
619
|
+
car_ret_type_chk(const Sequence & seq
|
|
620
|
+
,typename boost::enable_if<boost::is_same<Ret, BOOST_TYPEOF_TML(car(seq)) > >::type* = 0
|
|
621
|
+
){return car(seq);}
|
|
622
|
+
template <typename Ret,typename Sequence> Ret
|
|
623
|
+
car_ret_type_chk(const Sequence & seq
|
|
624
|
+
,typename boost::disable_if<boost::is_same<Ret, BOOST_TYPEOF_TML(car(seq)) > >::type* = 0
|
|
625
|
+
){return Ret();}
|
|
626
|
+
#endif
|
|
627
|
+
|
|
628
|
+
template <typename Ret,typename Sequence> Ret
|
|
629
|
+
list_ref(const Sequence & seq, int n
|
|
630
|
+
//,typename boost::disable_if<boost::fusion::traits::is_sequence<Sequence> >::type* = 0
|
|
631
|
+
,typename boost::disable_if<boost::mpl::or_<
|
|
632
|
+
boost::fusion::traits::is_sequence<Sequence>
|
|
633
|
+
,is_uniform_sequence<Sequence> >
|
|
634
|
+
>::type* = 0
|
|
635
|
+
){
|
|
636
|
+
if(n<=0){ return
|
|
637
|
+
car(seq)
|
|
638
|
+
//car_ret_type_chk<Ret>(seq)
|
|
639
|
+
;}
|
|
640
|
+
else{ return list_ref<Ret>(cdr(seq), n-1);}}
|
|
641
|
+
#endif
|
|
642
|
+
|
|
643
|
+
template<typename V>
|
|
644
|
+
struct fusion_at_n_functor
|
|
645
|
+
{
|
|
646
|
+
mutable int i;
|
|
647
|
+
int n;
|
|
648
|
+
mutable V value;
|
|
649
|
+
fusion_at_n_functor(int _n):i(0),n(_n){}
|
|
650
|
+
void operator()(const V & t) const
|
|
651
|
+
{ if(i==n){value=t;} i++;}
|
|
652
|
+
template<typename T>
|
|
653
|
+
void operator()(const T & t) const
|
|
654
|
+
{ i++;}
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
template <typename First,typename Last,typename AtN > void
|
|
658
|
+
list_ref_fusion_impl(First i,Last last,AtN &atn,boost::mpl::true_ ){}
|
|
659
|
+
template <typename First,typename Last,typename AtN > void
|
|
660
|
+
list_ref_fusion_impl(First i,Last last,AtN &atn,boost::mpl::false_ ){
|
|
661
|
+
//std::cout << atn.i << "," <<atn.n << ":" ;
|
|
662
|
+
if(atn.i == atn.n ){atn(boost::fusion::deref(i));}
|
|
663
|
+
else{
|
|
664
|
+
atn(boost::fusion::deref(i));
|
|
665
|
+
list_ref_fusion_impl(boost::fusion::next(i),last,atn,
|
|
666
|
+
boost::fusion::result_of::equal_to<
|
|
667
|
+
typename boost::fusion::result_of::next<First>::type,Last>());}}
|
|
668
|
+
|
|
669
|
+
template <typename Ret,typename Sequence> Ret
|
|
670
|
+
list_ref(Sequence & seq, int n
|
|
671
|
+
,typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence> >::type* = 0
|
|
672
|
+
){
|
|
673
|
+
fusion_at_n_functor<Ret> atn(n);
|
|
674
|
+
#if 0
|
|
675
|
+
//dbug
|
|
676
|
+
boost::fusion::for_each(seq, atn);
|
|
677
|
+
#else
|
|
678
|
+
list_ref_fusion_impl(boost::fusion::begin(seq),boost::fusion::end(seq) ,atn,
|
|
679
|
+
boost::fusion::result_of::equal_to<
|
|
680
|
+
typename boost::fusion::result_of::begin<Sequence>::type,
|
|
681
|
+
typename boost::fusion::result_of::end<Sequence>::type>());
|
|
682
|
+
#endif
|
|
683
|
+
return atn.value;}
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
#if 1
|
|
687
|
+
//////////////////////////////////
|
|
688
|
+
template <typename Ret,typename C,typename D> Ret
|
|
689
|
+
list_ref(std::pair<C,D> & seq,int n
|
|
690
|
+
//,typename boost::enable_if<typename boost::mpl::contains <value_types,D>::type >::type* =0
|
|
691
|
+
,typename boost::disable_if<boost::mpl::or_<
|
|
692
|
+
is_sequence<D>
|
|
693
|
+
,is_std_pair<D>
|
|
694
|
+
> >::type* =0
|
|
695
|
+
){
|
|
696
|
+
if(n<=0){ return
|
|
697
|
+
car(seq);
|
|
698
|
+
}else{
|
|
699
|
+
return seq.second;
|
|
700
|
+
}}
|
|
701
|
+
//////////////////////////////////
|
|
702
|
+
|
|
703
|
+
template <typename Ret,typename C,typename D> Ret
|
|
704
|
+
list_ref(const std::pair<C,D> & seq, int n)
|
|
705
|
+
{
|
|
706
|
+
if(n<=0){ return
|
|
707
|
+
car(seq)
|
|
708
|
+
;}
|
|
709
|
+
else{ return list_ref<Ret>(cdr(seq), n-1);}}
|
|
710
|
+
#else
|
|
711
|
+
|
|
712
|
+
template <typename Ret,typename AtN> void
|
|
713
|
+
list_ref_pair_impl(std::pair<double,double> & seq,AtN &atn
|
|
714
|
+
){
|
|
715
|
+
if(atn.i == atn.n ){
|
|
716
|
+
atn(seq.first);
|
|
717
|
+
}
|
|
718
|
+
else{
|
|
719
|
+
atn(seq.second);
|
|
720
|
+
}}
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
template <typename Ret,typename C,typename D,typename AtN> void
|
|
724
|
+
list_ref_pair_impl(std::pair<C,D> & seq,AtN &atn
|
|
725
|
+
//,typename boost::enable_if<typename boost::mpl::contains <value_types,D>::type >::type* =0
|
|
726
|
+
){
|
|
727
|
+
if(atn.i == atn.n ){
|
|
728
|
+
atn(seq.first);
|
|
729
|
+
}
|
|
730
|
+
else{
|
|
731
|
+
atn(seq.second);
|
|
732
|
+
}}
|
|
733
|
+
|
|
734
|
+
template <typename Ret,typename C,typename D,typename AtN> void
|
|
735
|
+
list_ref_pair_impl(std::pair<C,D> & seq,AtN &atn
|
|
736
|
+
,typename boost::enable_if<is_sequence<D> >::type* = 0
|
|
737
|
+
){
|
|
738
|
+
if(atn.i == atn.n ){
|
|
739
|
+
atn(seq.first);
|
|
740
|
+
}
|
|
741
|
+
else{
|
|
742
|
+
atn(seq.first);
|
|
743
|
+
atn.value=list_ref<Ret>(seq.second,atn.n - atn.i );
|
|
744
|
+
}}
|
|
745
|
+
|
|
746
|
+
template <typename Ret,typename C,typename D,typename AtN> void
|
|
747
|
+
list_ref_pair_impl(std::pair<C,D> & seq,AtN &atn
|
|
748
|
+
,typename boost::enable_if<is_std_pair<D> >::type* = 0
|
|
749
|
+
){
|
|
750
|
+
if(atn.i == atn.n ){
|
|
751
|
+
atn(seq.first);
|
|
752
|
+
}
|
|
753
|
+
else{
|
|
754
|
+
atn(seq.first);
|
|
755
|
+
list_ref_pair_impl<Ret>(seq.second,atn);
|
|
756
|
+
}}
|
|
757
|
+
|
|
758
|
+
template <typename Ret,typename C,typename D> Ret
|
|
759
|
+
list_ref(const std::pair<C,D> & seq, int n)
|
|
760
|
+
{
|
|
761
|
+
fusion_at_n_functor<Ret> atn(n);
|
|
762
|
+
list_ref_pair_impl<Ret>(seq,atn);
|
|
763
|
+
return atn.value;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
#endif
|
|
767
|
+
|
|
768
|
+
#if 0
|
|
769
|
+
template<typename C, typename D>
|
|
770
|
+
std::map<C,D>
|
|
771
|
+
append(const std::pair<C,D> &l1,const std::pair<C,D> &l2)
|
|
772
|
+
{
|
|
773
|
+
std::map<C,D> ll;
|
|
774
|
+
ll.insert(l1);
|
|
775
|
+
ll.insert(l2);
|
|
776
|
+
return ll;
|
|
777
|
+
}
|
|
778
|
+
#endif
|
|
779
|
+
|
|
780
|
+
#if 1
|
|
781
|
+
template<typename Seq>
|
|
782
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<Seq>::type
|
|
783
|
+
append(const Seq & l1, const Seq & l2
|
|
784
|
+
,typename boost::enable_if<is_uniform_sequence<Seq> >::type* = 0 ){
|
|
785
|
+
typedef typename Seq::iterator::value_type value_type;
|
|
786
|
+
typename Seq::const_reverse_iterator ir=l1.rbegin();
|
|
787
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<Seq>::type ll(l2.begin(),l2.end());
|
|
788
|
+
for(std::size_t i=0;i<l1.size();i++){ll.push_front(new value_type(*ir++));}
|
|
789
|
+
return ll;
|
|
790
|
+
}
|
|
791
|
+
#else
|
|
792
|
+
template<typename Seq>
|
|
793
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<Seq>::type
|
|
794
|
+
append(const Seq & l1, const Seq & l2
|
|
795
|
+
,typename boost::enable_if<is_uniform_sequence<Seq> >::type* = 0 ){
|
|
796
|
+
Seq ll(l1);
|
|
797
|
+
ll.insert(l1.end(), l2.begin(),l2.end() );
|
|
798
|
+
return ll;
|
|
799
|
+
}
|
|
800
|
+
#endif
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
#if 1
|
|
804
|
+
template<typename Seq1,typename Seq2>
|
|
805
|
+
boost::fusion::joint_view<Seq1,Seq2>
|
|
806
|
+
append(Seq1 & l1, Seq2 & l2
|
|
807
|
+
,typename boost::enable_if<boost::mpl::and_<
|
|
808
|
+
boost::fusion::traits::is_sequence<Seq1>
|
|
809
|
+
,boost::fusion::traits::is_sequence<Seq2> >
|
|
810
|
+
>::type* = 0
|
|
811
|
+
){
|
|
812
|
+
Seq1 l1b;
|
|
813
|
+
boost::fusion::copy(l1b,l1);
|
|
814
|
+
boost::fusion::joint_view<Seq1,Seq2> ll(l1b,l2);
|
|
815
|
+
return ll;
|
|
816
|
+
}
|
|
817
|
+
#endif
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
#if 0
|
|
821
|
+
template<typename Seq1,typename Seq2>
|
|
822
|
+
typename boost::fusion::result_of::as_list<
|
|
823
|
+
typename boost::fusion::result_of::push_back<
|
|
824
|
+
//seq1a_type
|
|
825
|
+
typename boost::fusion::result_of::as_list<
|
|
826
|
+
typename boost::fusion::result_of::erase<
|
|
827
|
+
Seq1,
|
|
828
|
+
typename boost::fusion::result_of::advance<
|
|
829
|
+
typename boost::fusion::result_of::begin<Seq1>::type,
|
|
830
|
+
boost::mpl::plus<
|
|
831
|
+
boost::fusion::result_of::size<Seq1>
|
|
832
|
+
,boost::mpl::int_<-1> > >::type
|
|
833
|
+
>::type
|
|
834
|
+
>::type
|
|
835
|
+
,
|
|
836
|
+
//result_back_type &
|
|
837
|
+
//Seq2
|
|
838
|
+
BOOST_TYPEOF(cons(boost::fusion::back(Seq1()),Seq2())) &
|
|
839
|
+
//BOOST_TYPEOF(cons(Seq1(),Seq2()))
|
|
840
|
+
>::type
|
|
841
|
+
>::type
|
|
842
|
+
append(Seq1 & seq1, Seq2 & seq2
|
|
843
|
+
,typename boost::enable_if<
|
|
844
|
+
boost::mpl::and_<
|
|
845
|
+
boost::fusion::traits::is_sequence<Seq1>
|
|
846
|
+
,boost::mpl::not_<
|
|
847
|
+
boost::fusion::traits::is_sequence<Seq2> > > >::type* = 0
|
|
848
|
+
){
|
|
849
|
+
//Seq1 ll;boost::fusion::copy(ll,seq1);//Seq1 ll(seq1);
|
|
850
|
+
typedef
|
|
851
|
+
#if 0
|
|
852
|
+
boost::fusion::result_of::as_list<
|
|
853
|
+
boost::fusion::result_of::erase<
|
|
854
|
+
Seq1,
|
|
855
|
+
boost::fusion::result_of::advance<
|
|
856
|
+
boost::fusion::result_of::begin<Seq1>::type,
|
|
857
|
+
boost::mpl::plus<
|
|
858
|
+
boost::fusion::result_of::size<Seq1>
|
|
859
|
+
,boost::mpl::int_<-1> > >::type
|
|
860
|
+
>::type>::type
|
|
861
|
+
#else
|
|
862
|
+
typename boost::fusion::result_of::as_list<
|
|
863
|
+
typename boost::fusion::result_of::erase<
|
|
864
|
+
Seq1,
|
|
865
|
+
typename boost::fusion::result_of::advance<
|
|
866
|
+
typename boost::fusion::result_of::begin<Seq1>::type,
|
|
867
|
+
boost::mpl::plus<
|
|
868
|
+
boost::fusion::result_of::size<Seq1>
|
|
869
|
+
,boost::mpl::int_<-1> > >::type >::type>::type
|
|
870
|
+
#endif
|
|
871
|
+
seq1a_type;
|
|
872
|
+
seq1a_type ll(seq1);
|
|
873
|
+
//typedef boost::fusion::result_of::back<Seq1> seq1_back_type;
|
|
874
|
+
//typedef boost::result_of<cons(seq1_back_type,Seq2)>::type result_back_type;
|
|
875
|
+
//BOOST_TYPEOF(cons(boost::fusion::back(seq1),seq2));
|
|
876
|
+
//BOOST_TYPEOF(cons(seq1_back_type(),Seq2()));
|
|
877
|
+
//boost::type_of
|
|
878
|
+
//boost::fusion::erase(ll, back(vec));
|
|
879
|
+
//boost::fusion::back(ll)=cons(boost::fusion::back(seq1),seq2 );
|
|
880
|
+
return
|
|
881
|
+
boost::fusion::push_back(ll,cons(boost::fusion::back(seq1),seq2 ) );
|
|
882
|
+
//return ll;
|
|
883
|
+
}
|
|
884
|
+
#endif
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
#if 0
|
|
888
|
+
template<typename Seq1,typename Seq2>
|
|
889
|
+
appended<Seq1,Seq2>
|
|
890
|
+
append(Seq1 & l1, Seq2 & l2
|
|
891
|
+
//,typename boost::enable_if<boost::mpl::and_<
|
|
892
|
+
//boost::fusion::traits::is_sequence<Seq1>
|
|
893
|
+
//,is_uniform_sequence<Seq2> >
|
|
894
|
+
//>::type* = 0
|
|
895
|
+
){
|
|
896
|
+
return appended<Seq1,Seq2>(l1,l2);
|
|
897
|
+
}
|
|
898
|
+
#endif
|
|
899
|
+
|
|
900
|
+
#if 0
|
|
901
|
+
template<typename Seq>
|
|
902
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<
|
|
903
|
+
typename Seq::iterator::value_type
|
|
904
|
+
>::type
|
|
905
|
+
//typename Seq::iterator::value_type
|
|
906
|
+
append(Seq & ll
|
|
907
|
+
,typename boost::enable_if<
|
|
908
|
+
boost::mpl::and_<
|
|
909
|
+
is_uniform_sequence<Seq>
|
|
910
|
+
,is_uniform_sequence<
|
|
911
|
+
typename Seq::iterator::value_type
|
|
912
|
+
> >
|
|
913
|
+
>::type* = 0
|
|
914
|
+
)
|
|
915
|
+
{
|
|
916
|
+
//typedef typename Seq::iterator::value_type value_type;
|
|
917
|
+
typename Seq::const_reverse_iterator ir=ll.rbegin();
|
|
918
|
+
typename uniform_sequence_to_boost_ptr_sequence_view<
|
|
919
|
+
typename Seq::iterator::value_type
|
|
920
|
+
>::type
|
|
921
|
+
l((*ir).begin(),(*ir).end());
|
|
922
|
+
ir++;
|
|
923
|
+
for(std::size_t i=1;i<ll.size();i++){
|
|
924
|
+
l=append(*ir++,l);
|
|
925
|
+
}
|
|
926
|
+
return l;
|
|
927
|
+
}
|
|
928
|
+
#endif
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
#if 0
|
|
932
|
+
template<typename T>
|
|
933
|
+
boost::ptr_list<T, boost::view_clone_allocator>
|
|
934
|
+
append(std::list<T> &l1,std::list<T> &l2)
|
|
935
|
+
{
|
|
936
|
+
boost::ptr_list<T, boost::view_clone_allocator> ll(l2.begin(),l2.end());
|
|
937
|
+
//std::list<T>::const_iterator i
|
|
938
|
+
typename std::list<T>::reverse_iterator ir=l1.rbegin();
|
|
939
|
+
for(int i=0;i<l1.size();i++){
|
|
940
|
+
ll.push_front(
|
|
941
|
+
//&(*ir++)
|
|
942
|
+
//*ir++
|
|
943
|
+
//std::auto_ptr<T>(&(*ir++))
|
|
944
|
+
new T(*ir++)
|
|
945
|
+
//ptr_r2lvalue(*ir++)
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
return ll;
|
|
949
|
+
}
|
|
950
|
+
#endif
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
template<typename Seq>
|
|
954
|
+
boost::fusion::reverse_view<Seq>
|
|
955
|
+
reverse(Seq & seq
|
|
956
|
+
,typename boost::enable_if<boost::fusion::traits::is_sequence<Seq> >::type* = 0){
|
|
957
|
+
return boost::fusion::reverse(seq) ;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
/////////////////////////list end ///////////////////////////////////
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
//template<typename Base> quoted<Base> quote(Base &base){return quoted<Base>(base); }
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
typedef std::basic_ofstream<char> stream_type;
|
|
978
|
+
|
|
979
|
+
typedef boost::mpl::vector<std::basic_ofstream<char>
|
|
980
|
+
,std::streambuf
|
|
981
|
+
,std::ostream,std::istream
|
|
982
|
+
,std::ifstream,std::ofstream
|
|
983
|
+
,std::stringstream
|
|
984
|
+
,std::istream,std::ostream
|
|
985
|
+
,std::string
|
|
986
|
+
> stream_types;
|
|
987
|
+
|
|
988
|
+
#if 0
|
|
989
|
+
typedef boost::mpl::transform< number_string_types,quoted<boost::mpl::_1> >::type quoted_number_string_types ;
|
|
990
|
+
typedef boost::mpl::insert_range<quoted_number_string_types,
|
|
991
|
+
boost::mpl::end<quoted_number_string_types>::type,
|
|
992
|
+
number_string_symbol_types>::type value_types;
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
typedef boost::mpl::transform< number_types,quoted<boost::mpl::_1> >::type quoted_number_types ;
|
|
996
|
+
typedef boost::mpl::insert_range<quoted_number_types,
|
|
997
|
+
boost::mpl::end<quoted_number_types>::type,
|
|
998
|
+
number_symbol_types>::type scalar_types;
|
|
999
|
+
|
|
1000
|
+
typedef boost::mpl::vector<char,int,short,long> int_types;
|
|
1001
|
+
typedef boost::mpl::transform<int_types, quoted<boost::mpl::_1> >::type quoted_int_types ;
|
|
1002
|
+
typedef boost::mpl::insert_range<quoted_int_types,
|
|
1003
|
+
boost::mpl::end<quoted_int_types>::type,
|
|
1004
|
+
int_types>::type int_quote_types;
|
|
1005
|
+
#endif
|
|
1006
|
+
|
|
1007
|
+
inline bool is_eq(symbol_type & x, symbol_type & y) {return x==y;}
|
|
1008
|
+
//bool is_eq(string_type & x, string_type & y) {return (& x)==(& y);}
|
|
1009
|
+
template<typename T> bool is_eq(T x, T y,typename boost::enable_if<boost::is_integral<T>, T>::type* = 0) {return x==y;}
|
|
1010
|
+
template<typename T> bool is_eq(quoted<T> &x, quoted<T> &y,typename boost::enable_if<boost::is_integral<T>, T>::type* = 0) {return x.value==y.value;}
|
|
1011
|
+
template<typename T> bool is_eq(quoted<T> &x, T y,typename boost::enable_if<boost::is_integral<T>, T>::type* = 0) {return x.value==y;}
|
|
1012
|
+
template<typename T> bool is_eq(T x, quoted<T> &y,typename boost::enable_if<boost::is_integral<T>, T>::type* = 0) {return x==y.value;}
|
|
1013
|
+
template<typename T> bool is_eq(T & x, T & y,typename boost::disable_if<typename boost::mpl::contains <int_quote_types,T>::type >::type* =0) {return (&x)==(&y);}
|
|
1014
|
+
template<typename T1,typename T2> bool is_eq(T1 x, T2 y){return false;}
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
//bool is_eqv(string_type & x, string_type & y) {return x==y;}
|
|
1018
|
+
inline bool is_eqv(symbol_type & x, symbol_type & y) {return x==y;}
|
|
1019
|
+
inline bool is_eqv(rational & x, rational & y) {return x==y;}
|
|
1020
|
+
inline bool is_eqv(quoted<rational > & x, rational & y) {return x.value==y;}
|
|
1021
|
+
inline bool is_eqv(rational & x, quoted<rational > & y) {return x==y.value;}
|
|
1022
|
+
inline bool is_eqv(quoted<rational > & x, quoted<rational > & y) {return x.value==y.value;}
|
|
1023
|
+
template<typename T> bool is_eqv(T x, T y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x==y;}
|
|
1024
|
+
template<typename T> bool is_eqv(quoted<T> &x, quoted<T> &y ,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x.value==y.value;}
|
|
1025
|
+
template<typename T> bool is_eqv(quoted<T> &x, T y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x.value==y;}
|
|
1026
|
+
template<typename T> bool is_eqv(T x, quoted<T> &y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x==y.value;}
|
|
1027
|
+
template<typename T> bool is_eqv(T & x, T & y,typename boost::disable_if<typename boost::mpl::contains <scalar_types,T>::type >::type* =0) {return (&x)==(&y);}
|
|
1028
|
+
template<typename T1,typename T2> bool is_eqv(T1 x, T2 y){return false;}
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
template<typename T1,typename T2> bool is_equal(const T1 & x, const T2 & y){return false;}
|
|
1032
|
+
template<typename T> bool is_equal(const T & x,const T & y){return ( ( x ) == ( y ) );}
|
|
1033
|
+
template<typename T> bool is_equal(const quoted<T> &x, const quoted<T> &y) {return is_equal(x.value,y.value);} ////////////
|
|
1034
|
+
//template<> bool is_equal(string_type & x, string_type & y) {return x==y;}
|
|
1035
|
+
//template<> bool is_equal(symbol_type & x, symbol_type & y) {return x==y;}
|
|
1036
|
+
|
|
1037
|
+
// //bool is_equal(quoted<symbol_type> & x, quoted<symbol_type> & y) {return x.value==y.value;}
|
|
1038
|
+
// template<typename T> bool is_equal(T x, T y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x==y;}
|
|
1039
|
+
|
|
1040
|
+
// //template<typename T> bool is_equal(T &x, T &y,typename boost::disable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x==y;}
|
|
1041
|
+
//template<typename T> bool is_equal(quoted<T> &x, T y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x.value==y;}
|
|
1042
|
+
//template<typename T> bool is_equal(T x, quoted<T> &y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x==y.value;}
|
|
1043
|
+
// //template<typename T> bool is_equal(quoted<T> &x, quoted<T> &y,typename boost::enable_if<boost::is_arithmetic<T>, T>::type* = 0) {return x.value==y.value;}
|
|
1044
|
+
template<typename T> bool is_equal(const quoted<T> &x,const T & y
|
|
1045
|
+
,typename boost::enable_if<typename boost::mpl::contains <
|
|
1046
|
+
//not_c_number_string_types
|
|
1047
|
+
number_string_types
|
|
1048
|
+
,T>::type >::type* =0) {return x.value==y;}
|
|
1049
|
+
template<typename T> bool is_equal(const T & x,const quoted<T> &y
|
|
1050
|
+
,typename boost::enable_if<typename boost::mpl::contains <
|
|
1051
|
+
//not_c_number_string_types
|
|
1052
|
+
number_string_types
|
|
1053
|
+
,T>::type >::type* =0) {return x==y.value;}
|
|
1054
|
+
// // template<typename T> bool is_equal(quoted<T> & x, quoted<T> &y
|
|
1055
|
+
// // ,typename boost::enable_if<typename boost::mpl::contains <not_c_number_string_types,T>::type >::type* =0) {return x.value==y.value;}
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
// // template<typename T> bool is_equal(quoted<T> &x, quoted<T> &y
|
|
1059
|
+
// // ,typename boost::disable_if<typename boost::mpl::contains <value_types,T>::type >::type* =0)
|
|
1060
|
+
// // {return is_equal(x.value,y.value);}
|
|
1061
|
+
// // template<typename T> bool is_equal(T &x, quoted<T> &y
|
|
1062
|
+
// // ,typename boost::disable_if<typename boost::mpl::contains <value_types,T>::type >::type* =0)
|
|
1063
|
+
// // {return is_equal(x,y.value);}
|
|
1064
|
+
|
|
1065
|
+
// // template<typename T> bool is_equal(quoted<T> &x, T &y
|
|
1066
|
+
// // ,typename boost::disable_if<typename boost::mpl::contains <value_types,T>::type >::type* =0)
|
|
1067
|
+
// // {return is_equal(x.value,y);}
|
|
1068
|
+
// // template<typename T1,typename T2> bool is_equal(quoted<T1> &x, quoted<T2> &y
|
|
1069
|
+
// // ,typename boost::disable_if<typename boost::mpl::contains <value_types,T1>::type >::type* =0
|
|
1070
|
+
// // ,typename boost::disable_if<typename boost::mpl::contains <value_types,T2>::type >::type* =0
|
|
1071
|
+
// // )
|
|
1072
|
+
// // {return is_equal(x.value,y.value);}
|
|
1073
|
+
// template<typename T> bool is_equal(T & x, T & y
|
|
1074
|
+
// ,typename boost::disable_if<typename boost::mpl::contains <value_types,T>::type >::type* =0)
|
|
1075
|
+
// {return x==y;}
|
|
1076
|
+
// //number_string_symbol_types
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
///////variant shrink begin
|
|
1082
|
+
|
|
1083
|
+
//typedef boost::mpl::vector<int,rational,float,double,long double,std::complex<double> >::type scheme_ordered_number_types;
|
|
1084
|
+
//typedef scheme_ordered_number_types ordered_number_types;
|
|
1085
|
+
typedef boost::mpl::vector<int,rational,float,double,std::complex<double> >::type default_type_order;
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
////////////mpl general util begin
|
|
1090
|
+
|
|
1091
|
+
template<typename TypeVec>
|
|
1092
|
+
struct is_mpl_sequence_single :
|
|
1093
|
+
boost::is_same<
|
|
1094
|
+
typename boost::mpl::size<TypeVec>::type
|
|
1095
|
+
,typename boost::mpl::long_<1> >
|
|
1096
|
+
{};
|
|
1097
|
+
|
|
1098
|
+
template<typename TypeVec>
|
|
1099
|
+
struct mpl_sequence_if_single_then_element_else_variant : public
|
|
1100
|
+
boost::mpl::if_<
|
|
1101
|
+
typename is_mpl_sequence_single<TypeVec>::type
|
|
1102
|
+
,
|
|
1103
|
+
typename
|
|
1104
|
+
boost::mpl::front<TypeVec>//::type
|
|
1105
|
+
//,typename TypeVec::type
|
|
1106
|
+
//,TypeVec
|
|
1107
|
+
,typename boost::make_variant_over<TypeVec>
|
|
1108
|
+
>::type
|
|
1109
|
+
{};
|
|
1110
|
+
|
|
1111
|
+
template<typename TypeVec,typename IsLess>
|
|
1112
|
+
struct max_in_mpl_sequence_given_is_less_lambda : public
|
|
1113
|
+
boost::mpl::fold<
|
|
1114
|
+
TypeVec
|
|
1115
|
+
,typename boost::mpl::front<TypeVec>::type
|
|
1116
|
+
,boost::mpl::if_<
|
|
1117
|
+
boost::mpl::bind2<IsLess,boost::mpl::_1 , boost::mpl::_2 >
|
|
1118
|
+
//typename boost::mpl::apply<IsLess,boost::mpl::_1 , boost::mpl::_2 >//::type
|
|
1119
|
+
//typename IsLess::apply< boost::mpl::_1 , boost::mpl::_2 >
|
|
1120
|
+
//boost::mpl::true_
|
|
1121
|
+
,boost::mpl::_2 , boost::mpl::_1 >
|
|
1122
|
+
>
|
|
1123
|
+
{};
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
template<typename TypeVec,typename TypeOrder>
|
|
1127
|
+
struct mpl_vector_contains_filter : boost::mpl::filter_view<
|
|
1128
|
+
TypeVec
|
|
1129
|
+
,boost::mpl::contains<TypeOrder,boost::mpl::_1>
|
|
1130
|
+
>
|
|
1131
|
+
{};
|
|
1132
|
+
|
|
1133
|
+
template<typename TypeVec,typename TypeOrder>
|
|
1134
|
+
struct mpl_vector_not_contains_filter : boost::mpl::filter_view<
|
|
1135
|
+
TypeVec
|
|
1136
|
+
,boost::mpl::not_<boost::mpl::contains<TypeOrder,boost::mpl::_1> >
|
|
1137
|
+
>
|
|
1138
|
+
{};
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
////////////mpl general util end
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
template<typename T1,typename T2,typename TypeOrder>
|
|
1147
|
+
struct is_less_in_orderd_mpl_sequence :
|
|
1148
|
+
boost::is_same <
|
|
1149
|
+
typename boost::mpl::find<
|
|
1150
|
+
typename boost::mpl::iterator_range<
|
|
1151
|
+
typename boost::mpl::find<TypeOrder,T2>::type ,
|
|
1152
|
+
typename boost::mpl::end<TypeOrder>::type
|
|
1153
|
+
>::type ,
|
|
1154
|
+
T1 >::type,
|
|
1155
|
+
typename boost::mpl::end<TypeOrder>::type >
|
|
1156
|
+
{};
|
|
1157
|
+
|
|
1158
|
+
typedef boost::mpl::lambda<is_less_in_orderd_mpl_sequence<boost::mpl::_1 , boost::mpl::_2 , default_type_order> >::type is_less_over_default_type_order_mpl_lambda;
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
template<typename T1,typename TBase,typename TypeOrder>
|
|
1162
|
+
struct is_generalizable_to_using_generaize_order_sequence :
|
|
1163
|
+
boost::mpl::if_<
|
|
1164
|
+
typename
|
|
1165
|
+
boost::mpl::contains<TypeOrder,T1>::type
|
|
1166
|
+
,
|
|
1167
|
+
typename
|
|
1168
|
+
boost::mpl::if_<
|
|
1169
|
+
typename
|
|
1170
|
+
boost::mpl::contains<TypeOrder,TBase>::type
|
|
1171
|
+
,
|
|
1172
|
+
//typename
|
|
1173
|
+
is_less_in_orderd_mpl_sequence<T1,TBase,TypeOrder> //::type
|
|
1174
|
+
,
|
|
1175
|
+
//typename
|
|
1176
|
+
boost::mpl::false_ //::type
|
|
1177
|
+
>::type
|
|
1178
|
+
,
|
|
1179
|
+
//typename
|
|
1180
|
+
boost::mpl::false_ //::type
|
|
1181
|
+
> ::type
|
|
1182
|
+
{};
|
|
1183
|
+
|
|
1184
|
+
template<typename TypeOrder>
|
|
1185
|
+
struct generate_mpl_lambda_is_generalizable_to_from_type_order_sequence
|
|
1186
|
+
{ typedef typename boost::mpl::lambda<is_generalizable_to_using_generaize_order_sequence<boost::mpl::_1 , boost::mpl::_2 , TypeOrder> >::type type;
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
//typedef boost::mpl::lambda<is_generalizable_to_using_generaize_order_sequence<boost::mpl::_1 , boost::mpl::_2 , default_type_order> >::type is_generalizable_using_default_type_order_mpl_lambda;
|
|
1190
|
+
|
|
1191
|
+
typedef generate_mpl_lambda_is_generalizable_to_from_type_order_sequence<default_type_order>::type is_generalizable_using_default_type_order_mpl_lambda;
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
//template<typename TypeVec,typename Greater>
|
|
1195
|
+
template<typename TypeVec,typename TypeBase,typename IsGeneralizable>
|
|
1196
|
+
struct generalize_type_sequence_to_base :
|
|
1197
|
+
boost::mpl::transform<
|
|
1198
|
+
TypeVec
|
|
1199
|
+
,boost::mpl::if_<
|
|
1200
|
+
boost::mpl::bind2<IsGeneralizable,boost::mpl::_1 , TypeBase >
|
|
1201
|
+
,TypeBase
|
|
1202
|
+
,boost::mpl::_1>
|
|
1203
|
+
>
|
|
1204
|
+
{};
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
template<typename TypeVec,typename IsGeneralizable>
|
|
1208
|
+
struct generaize_type_sequence_using_is_generalizable_to :
|
|
1209
|
+
boost::mpl::fold<
|
|
1210
|
+
TypeVec
|
|
1211
|
+
,TypeVec
|
|
1212
|
+
,
|
|
1213
|
+
//typename
|
|
1214
|
+
generalize_type_sequence_to_base<boost::mpl::_1,boost::mpl::_2,IsGeneralizable > //::type
|
|
1215
|
+
>::type
|
|
1216
|
+
{};
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
template<typename TypeVec,typename IsGeneralizable=is_generalizable_using_default_type_order_mpl_lambda >
|
|
1220
|
+
struct make_variant_shrink_over : public
|
|
1221
|
+
//mpl_sequence_if_single_to_element
|
|
1222
|
+
mpl_sequence_if_single_then_element_else_variant<
|
|
1223
|
+
typename
|
|
1224
|
+
boost::mpl::unique<
|
|
1225
|
+
typename
|
|
1226
|
+
generaize_type_sequence_using_is_generalizable_to<TypeVec,IsGeneralizable>::type
|
|
1227
|
+
,boost::is_same<boost::mpl::_1,boost::mpl::_2>
|
|
1228
|
+
>::type
|
|
1229
|
+
>//::type
|
|
1230
|
+
{};
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
|
1235
|
+
typename max_in_mpl_sequence_given_is_less_lambda<
|
|
1236
|
+
typename
|
|
1237
|
+
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >::types
|
|
1238
|
+
,is_generalizable_using_default_type_order_mpl_lambda>::type
|
|
1239
|
+
get_number(boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& x)
|
|
1240
|
+
{
|
|
1241
|
+
return boost::get<
|
|
1242
|
+
typename max_in_mpl_sequence_given_is_less_lambda<
|
|
1243
|
+
typename
|
|
1244
|
+
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >::types
|
|
1245
|
+
,is_generalizable_using_default_type_order_mpl_lambda>::type
|
|
1246
|
+
>(x);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
template<typename T>
|
|
1252
|
+
T & get_number(boost::optional<T &> x) { return *x;}
|
|
1253
|
+
|
|
1254
|
+
template<typename T>
|
|
1255
|
+
T & get_number(boost::optional<const T &> x) { return *x;}
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
template<typename T>
|
|
1259
|
+
T get_number(boost::optional<T > x) { return *x;}
|
|
1260
|
+
|
|
1261
|
+
template<typename T>
|
|
1262
|
+
T get_number(T x)
|
|
1263
|
+
{
|
|
1264
|
+
return x;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
template<typename T> boost::optional<T &>
|
|
1270
|
+
optional_attach(T &x) { boost::optional<T &> y(x); return y; }
|
|
1271
|
+
|
|
1272
|
+
template<typename T> boost::optional<T &>
|
|
1273
|
+
optional_attach(const T &x)
|
|
1274
|
+
{ boost::optional<T &> y(const_cast<T &>(x)); return y; }
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
// template<typename Seq,typename X>
|
|
1281
|
+
// struct mpl_adjoin_copy_vector : public
|
|
1282
|
+
// boost::mpl::fold<
|
|
1283
|
+
// //typename TypeVec::type ,
|
|
1284
|
+
// Seq ,
|
|
1285
|
+
// //typename Seq::type ,
|
|
1286
|
+
// boost::mpl::vector1<X> ,
|
|
1287
|
+
// //boost::mpl::insert<boost::mpl::_1,boost::mpl::_2>
|
|
1288
|
+
// boost::mpl::push_back<boost::mpl::_1,boost::mpl::_2> //::type
|
|
1289
|
+
// //boost::mpl::push_front<boost::mpl::_1 , boost::mpl::_2 >
|
|
1290
|
+
// >
|
|
1291
|
+
// {};
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
///////variant shrink end
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
#if CONSED_AS_STD_PAIR
|
|
1304
|
+
#undef consd
|
|
1305
|
+
#endif
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
//template<class T>void Func(T arg1, typename ::boost::enable_if_c< ::boost::is_same<T, int>::value >::type* =0) { ... }
|
|
1313
|
+
|
|
1314
|
+
//template<class T>void Func(T arg1, typename ::boost::enable_if_c< ::boost::is_same<T, string>::value >::type* =0) { ... }
|
|
1315
|
+
|
|
1316
|
+
template<typename F,typename ResultType>
|
|
1317
|
+
struct promise
|
|
1318
|
+
{
|
|
1319
|
+
//need partial specialization or enable_if
|
|
1320
|
+
//typedef typename boost::function_types::result_type<F>::type result_type;
|
|
1321
|
+
//typedef typename F::result_type result_type;
|
|
1322
|
+
typedef ResultType result_type;
|
|
1323
|
+
result_type result;
|
|
1324
|
+
bool is_evaled;
|
|
1325
|
+
F f;
|
|
1326
|
+
promise(F & _f):f(_f),is_evaled(false){}
|
|
1327
|
+
inline result_type operator()(){
|
|
1328
|
+
if(is_evaled)
|
|
1329
|
+
return result;
|
|
1330
|
+
else{
|
|
1331
|
+
result=f();
|
|
1332
|
+
is_evaled=true;
|
|
1333
|
+
return result;
|
|
1334
|
+
}}
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
#ifdef BOOST_NO_DECLTYPE
|
|
1341
|
+
|
|
1342
|
+
template<typename F> promise<F,typename boost::function_types::result_type<F>::type> make_promise(F &f){ return promise<F,typename boost::function_types::result_type<F>::type>(f);}
|
|
1343
|
+
template<typename ResultType,typename F> promise<F,ResultType> make_promise(F f){ return promise<F,ResultType>(f);}
|
|
1344
|
+
#else
|
|
1345
|
+
|
|
1346
|
+
template<typename F> auto make_promise(F f) -> promise<F,decltype(f())>{return promise<F,decltype(f())>(f);}
|
|
1347
|
+
|
|
1348
|
+
#endif
|
|
1349
|
+
|
|
1350
|
+
template<typename F> promise<boost::function<F>,typename boost::function<F>::result_type> make_promise(boost::function<F> &f){ return promise<boost::function<F>,typename boost::function<F>::result_type>(f);}
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
#ifdef BOOST_NO_DECLTYPE
|
|
1354
|
+
#else
|
|
1355
|
+
// By reference: a promise memoises into itself, so forcing a copy computes
|
|
1356
|
+
// the value again and leaves the original still unevaluated. Taking it by
|
|
1357
|
+
// value made (force p) twice run the body twice, which is exactly what a
|
|
1358
|
+
// promise is for not doing. The const overload serves promises reached
|
|
1359
|
+
// through a const reference; those cannot memoise, but they still yield
|
|
1360
|
+
// the right value.
|
|
1361
|
+
template<typename PromiseType>
|
|
1362
|
+
auto force(PromiseType & promise) -> decltype(promise())
|
|
1363
|
+
{
|
|
1364
|
+
return promise();
|
|
1365
|
+
}
|
|
1366
|
+
template<typename PromiseType>
|
|
1367
|
+
auto force(const PromiseType & promise) -> decltype(PromiseType(promise)())
|
|
1368
|
+
{
|
|
1369
|
+
PromiseType copy(promise);
|
|
1370
|
+
return copy();
|
|
1371
|
+
}
|
|
1372
|
+
#endif
|
|
1373
|
+
|
|
1374
|
+
//////////////////////////////////////////////////////////////////////////
|
|
1375
|
+
// Delayed streams as a nominal type whose recursion is erased through
|
|
1376
|
+
// std::function. Expanding the type structurally yields an infinite type and
|
|
1377
|
+
// the occurs check rejects it; naming it lets unification compare element
|
|
1378
|
+
// types in a single step, so inference terminates.
|
|
1379
|
+
namespace scm2cpp {
|
|
1380
|
+
|
|
1381
|
+
template<typename T> struct stream_cell {
|
|
1382
|
+
typedef T value_type;
|
|
1383
|
+
T head;
|
|
1384
|
+
std::function<stream_cell<T>()> tail;
|
|
1385
|
+
stream_cell(){}
|
|
1386
|
+
stream_cell(const T& h, const std::function<stream_cell<T>()>& t)
|
|
1387
|
+
: head(h), tail(t) {}
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
// Corresponds to (cons a (delay b)); wraps b without evaluating it.
|
|
1391
|
+
template<typename T, typename F>
|
|
1392
|
+
stream_cell<T> make_stream(const T& h, F f) {
|
|
1393
|
+
return stream_cell<T>(h, std::function<stream_cell<T>()>(f));
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
template<typename T> T car(const stream_cell<T>& s) { return s.head; }
|
|
1397
|
+
template<typename T> std::function<stream_cell<T>()> cdr(const stream_cell<T>& s) { return s.tail; }
|
|
1398
|
+
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
//////////////////////////////////////////////////////////////////////////
|
|
1402
|
+
#endif // SCM2CPP_MINIMAL
|
|
1403
|
+
|
|
1404
|
+
// An n-dimensional summed-area table. Built once over a flat row-major
|
|
1405
|
+
// array, it answers the sum over any axis-aligned box in O(2^n) additions
|
|
1406
|
+
// by inclusion-exclusion, instead of O(volume) by looping. The table is a
|
|
1407
|
+
// representation an inferencer may choose for an array whose only reads
|
|
1408
|
+
// are box sums; the choice is valid only if every write precedes the
|
|
1409
|
+
// first query, which build() makes explicit.
|
|
1410
|
+
namespace scm2cpp {
|
|
1411
|
+
|
|
1412
|
+
// A (vector e ...) literal: the arity is the array's extent, so the
|
|
1413
|
+
// whole thing is one fixed-size value. Elements are cast to the first
|
|
1414
|
+
// element's type, mirroring the inference rule that types the literal
|
|
1415
|
+
// from its first element.
|
|
1416
|
+
template<typename T>
|
|
1417
|
+
inline std::array<T, 1> make_array(T e0)
|
|
1418
|
+
{ std::array<T, 1> a = {{ e0 }}; return a; }
|
|
1419
|
+
template<typename T, typename... Es>
|
|
1420
|
+
inline std::array<T, 1 + sizeof...(Es)> make_array(T e0, Es... es)
|
|
1421
|
+
{ std::array<T, 1 + sizeof...(Es)> a = {{ e0, static_cast<T>(es)... }}; return a; }
|
|
1422
|
+
|
|
1423
|
+
// (make-vector N v) with a literal extent: one fixed-size value with
|
|
1424
|
+
// every element v. What boost::assign::list_of used to spell.
|
|
1425
|
+
template<typename T, std::size_t N>
|
|
1426
|
+
inline std::array<T, N> filled_array(T v)
|
|
1427
|
+
{ std::array<T, N> a; a.fill(v); return a; }
|
|
1428
|
+
|
|
1429
|
+
// Dynamic-extent array parameters as views. A span is one pointer:
|
|
1430
|
+
// host code converts to it implicitly from std::vector or std::array,
|
|
1431
|
+
// device code from a raw device pointer, and the callee indexes it
|
|
1432
|
+
// the same either way. Writes go to the caller's memory -- what the
|
|
1433
|
+
// reference parameter meant, without the container crossing into
|
|
1434
|
+
// device code. The generated subset never resizes or measures a
|
|
1435
|
+
// parameter, so a pointer is the whole interface.
|
|
1436
|
+
// n is the length when the span was made from a container (or given
|
|
1437
|
+
// one), 0 when only a pointer was; the --cuda back end needs it to copy
|
|
1438
|
+
// the elements, nothing else reads it.
|
|
1439
|
+
template<typename T> struct span {
|
|
1440
|
+
T* p;
|
|
1441
|
+
std::size_t n;
|
|
1442
|
+
SCM2CPP_FN span(T* p) : p(p), n(0) {}
|
|
1443
|
+
SCM2CPP_FN span(T* p, std::size_t n) : p(p), n(n) {}
|
|
1444
|
+
span(std::vector<T>& v) : p(v.data()), n(v.size()) {}
|
|
1445
|
+
template<std::size_t N> span(std::array<T, N>& a) : p(a.data()), n(N) {}
|
|
1446
|
+
SCM2CPP_FN T& operator[](std::size_t i) const { return p[i]; }
|
|
1447
|
+
T* data() const { return p; }
|
|
1448
|
+
std::size_t size() const { return n; }
|
|
1449
|
+
};
|
|
1450
|
+
template<typename T> struct cspan {
|
|
1451
|
+
const T* p;
|
|
1452
|
+
std::size_t n;
|
|
1453
|
+
SCM2CPP_FN cspan(const T* p) : p(p), n(0) {}
|
|
1454
|
+
SCM2CPP_FN cspan(const T* p, std::size_t n) : p(p), n(n) {}
|
|
1455
|
+
cspan(span<T> s) : p(s.p), n(s.n) {}
|
|
1456
|
+
cspan(const std::vector<T>& v) : p(v.data()), n(v.size()) {}
|
|
1457
|
+
template<std::size_t N> cspan(const std::array<T, N>& a) : p(a.data()), n(N) {}
|
|
1458
|
+
SCM2CPP_FN const T& operator[](std::size_t i) const { return p[i]; }
|
|
1459
|
+
const T* data() const { return p; }
|
|
1460
|
+
std::size_t size() const { return n; }
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
// A memo for a pure call: (memo-call M E KEY ...) is
|
|
1464
|
+
// memo_get(M, memo_key().add(KEY)...str(), [&]() { return E; })
|
|
1465
|
+
// M a hash table from the key's bytes to E's value (the translator's
|
|
1466
|
+
// (make-hash), an std::unordered_map<std::string, V>), so E runs once
|
|
1467
|
+
// per distinct key. A key is scalars by value and, through
|
|
1468
|
+
// add_range, the first N elements of an array -- the index set a
|
|
1469
|
+
// gather read, say. The bytes are the values' object representation,
|
|
1470
|
+
// so 0.0 and -0.0 are different keys (a miss, never a wrong hit).
|
|
1471
|
+
struct memo_key {
|
|
1472
|
+
std::string b;
|
|
1473
|
+
template<typename T> memo_key& add(const T& v) {
|
|
1474
|
+
b.append(reinterpret_cast<const char*>(&v), sizeof(T));
|
|
1475
|
+
return *this;
|
|
1476
|
+
}
|
|
1477
|
+
template<typename V> memo_key& add_range(const V& v, long n) {
|
|
1478
|
+
add(n);
|
|
1479
|
+
for (long i = 0; i < n; ++i) add(v[i]);
|
|
1480
|
+
return *this;
|
|
1481
|
+
}
|
|
1482
|
+
const std::string& str() const { return b; }
|
|
1483
|
+
};
|
|
1484
|
+
template<typename M, typename F>
|
|
1485
|
+
inline typename M::mapped_type memo_get(M& m, const std::string& k, F f) {
|
|
1486
|
+
auto it = m.find(k);
|
|
1487
|
+
if (it != m.end()) return it->second;
|
|
1488
|
+
typename M::mapped_type v = f();
|
|
1489
|
+
m.emplace(k, v);
|
|
1490
|
+
return v;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
template<typename T, int N> struct integral_image {
|
|
1494
|
+
std::vector<T> table; // padded with a zero border: dim[k]+1 per axis
|
|
1495
|
+
int dim[N]; // extents of the source array
|
|
1496
|
+
int stride[N]; // strides of the padded table, innermost last
|
|
1497
|
+
|
|
1498
|
+
integral_image() { for (int k = 0; k < N; ++k) { dim[k] = 0; stride[k] = 0; } }
|
|
1499
|
+
|
|
1500
|
+
// src is the flat row-major source; dims its extents, slowest axis first.
|
|
1501
|
+
template<typename Src>
|
|
1502
|
+
void build(const Src& src, const int (&dims)[N]) {
|
|
1503
|
+
std::size_t total = 1;
|
|
1504
|
+
for (int k = N; k-- > 0; ) {
|
|
1505
|
+
dim[k] = dims[k];
|
|
1506
|
+
stride[k] = int(total);
|
|
1507
|
+
total *= std::size_t(dims[k] + 1);
|
|
1508
|
+
}
|
|
1509
|
+
table.assign(total, T(0));
|
|
1510
|
+
// Fill: table[i0+1,..] = src[i0,..], then prefix-sum along each axis.
|
|
1511
|
+
std::size_t count = 1;
|
|
1512
|
+
for (int k = 0; k < N; ++k) count *= std::size_t(dim[k]);
|
|
1513
|
+
for (std::size_t s = 0; s < count; ++s) {
|
|
1514
|
+
std::size_t rem = s, t = 0;
|
|
1515
|
+
for (int k = N; k-- > 0; ) {
|
|
1516
|
+
int i = int(rem % std::size_t(dim[k])); rem /= std::size_t(dim[k]);
|
|
1517
|
+
t += std::size_t(i + 1) * std::size_t(stride[k]);
|
|
1518
|
+
}
|
|
1519
|
+
table[t] = src[s];
|
|
1520
|
+
}
|
|
1521
|
+
for (int k = 0; k < N; ++k)
|
|
1522
|
+
for (std::size_t t = 0; t < total; ++t)
|
|
1523
|
+
if (int(t / std::size_t(stride[k])) % (dim[k] + 1) != 0)
|
|
1524
|
+
table[t] += table[t - std::size_t(stride[k])];
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// Sum of the source over the closed box [lo[k], hi[k]] on every axis.
|
|
1528
|
+
T query(const int (&lo)[N], const int (&hi)[N]) const {
|
|
1529
|
+
T acc = T(0);
|
|
1530
|
+
for (unsigned corner = 0; corner < (1u << N); ++corner) {
|
|
1531
|
+
std::size_t t = 0; int sign = 1;
|
|
1532
|
+
for (int k = 0; k < N; ++k) {
|
|
1533
|
+
int edge = (corner >> k) & 1 ? lo[k] : hi[k] + 1; // 0..dim[k]
|
|
1534
|
+
if ((corner >> k) & 1) sign = -sign;
|
|
1535
|
+
t += std::size_t(edge) * std::size_t(stride[k]);
|
|
1536
|
+
}
|
|
1537
|
+
acc += sign > 0 ? table[t] : T(0) - table[t];
|
|
1538
|
+
}
|
|
1539
|
+
return acc;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
// The two-dimensional case, spelled out for the generated code.
|
|
1543
|
+
T query2(int i0, int i1, int j0, int j1) const {
|
|
1544
|
+
const int lo[2] = { i0, j0 }, hi[2] = { i1, j1 };
|
|
1545
|
+
return query(lo, hi);
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
// Operator tags for monoid_table: the fold's operation as a type, so
|
|
1551
|
+
// the loop bodies inline with no function-pointer indirection.
|
|
1552
|
+
template<typename T> struct mt_add { static T op(T a, T b) { return a + b; } };
|
|
1553
|
+
template<typename T> struct mt_mul { static T op(T a, T b) { return a * b; } };
|
|
1554
|
+
template<typename T> struct mt_min { static T op(T a, T b) { return a < b ? a : b; } };
|
|
1555
|
+
template<typename T> struct mt_max { static T op(T a, T b) { return a < b ? b : a; } };
|
|
1556
|
+
|
|
1557
|
+
// The integral image generalised to a commutative monoid: the same
|
|
1558
|
+
// padded table, the borders holding the identity instead of zero, the
|
|
1559
|
+
// axis scans folding with OP. What is answerable shrinks with the
|
|
1560
|
+
// structure: prefix() reads an origin-anchored box straight out of the
|
|
1561
|
+
// table and needs nothing but associativity and an identity, which is
|
|
1562
|
+
// why -I can take any catalogued operator through here; the
|
|
1563
|
+
// inclusion-exclusion query of integral_image needs subtraction and
|
|
1564
|
+
// stays with the additive group.
|
|
1565
|
+
template<typename T, int N, typename OP> struct monoid_table {
|
|
1566
|
+
std::vector<T> table;
|
|
1567
|
+
int dim[N];
|
|
1568
|
+
int stride[N];
|
|
1569
|
+
|
|
1570
|
+
monoid_table() { for (int k = 0; k < N; ++k) { dim[k] = 0; stride[k] = 0; } }
|
|
1571
|
+
|
|
1572
|
+
template<typename Src>
|
|
1573
|
+
void build(const Src& src, const int (&dims)[N], T id) {
|
|
1574
|
+
std::size_t total = 1;
|
|
1575
|
+
for (int k = N; k-- > 0; ) {
|
|
1576
|
+
dim[k] = dims[k];
|
|
1577
|
+
stride[k] = int(total);
|
|
1578
|
+
total *= std::size_t(dims[k] + 1);
|
|
1579
|
+
}
|
|
1580
|
+
table.assign(total, id);
|
|
1581
|
+
std::size_t count = 1;
|
|
1582
|
+
for (int k = 0; k < N; ++k) count *= std::size_t(dim[k]);
|
|
1583
|
+
for (std::size_t s = 0; s < count; ++s) {
|
|
1584
|
+
std::size_t rem = s, t = 0;
|
|
1585
|
+
for (int k = N; k-- > 0; ) {
|
|
1586
|
+
int i = int(rem % std::size_t(dim[k])); rem /= std::size_t(dim[k]);
|
|
1587
|
+
t += std::size_t(i + 1) * std::size_t(stride[k]);
|
|
1588
|
+
}
|
|
1589
|
+
table[t] = src[s];
|
|
1590
|
+
}
|
|
1591
|
+
for (int k = 0; k < N; ++k)
|
|
1592
|
+
for (std::size_t t = 0; t < total; ++t)
|
|
1593
|
+
if (int(t / std::size_t(stride[k])) % (dim[k] + 1) != 0)
|
|
1594
|
+
table[t] = OP::op(table[t - std::size_t(stride[k])], table[t]);
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
// The fold of the source over the origin-anchored box [0, hi[k]] on
|
|
1598
|
+
// every axis: one table read, no inverse anywhere.
|
|
1599
|
+
T prefix(const int (&hi)[N]) const {
|
|
1600
|
+
std::size_t t = 0;
|
|
1601
|
+
for (int k = 0; k < N; ++k)
|
|
1602
|
+
t += std::size_t(hi[k] + 1) * std::size_t(stride[k]);
|
|
1603
|
+
return table[t];
|
|
1604
|
+
}
|
|
1605
|
+
};
|
|
1606
|
+
|
|
1607
|
+
// (integral-image v n m) in the generated code: build a rank-2 table.
|
|
1608
|
+
template<typename T, typename Src>
|
|
1609
|
+
integral_image<T,2> make_integral_image2(const Src& src, int n, int m) {
|
|
1610
|
+
integral_image<T,2> ii;
|
|
1611
|
+
const int dims[2] = { n, m };
|
|
1612
|
+
ii.build(src, dims);
|
|
1613
|
+
return ii;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
#endif
|
|
1619
|
+
|
|
1620
|
+
//Copyright (C) 2011-2026 Hirotaka Niitsuma
|
|
1621
|
+
//
|
|
1622
|
+
//This header is part of Scm2Cpp and is distributed under the MIT License.
|
|
1623
|
+
//See the LICENSE file in the project root for the full text.
|
|
1624
|
+
//
|
|
1625
|
+
//Note: this header is included into the C++ that Scm2Cpp generates, and so
|
|
1626
|
+
//becomes part of the user's program. The MIT terms were chosen so that this
|
|
1627
|
+
//imposes no obligation on that program beyond preserving this notice.
|