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.
Files changed (72) hide show
  1. scm2cpp_learn/__init__.py +3836 -0
  2. scm2cpp_learn/_classifiers.cp312-win_amd64.pyd +0 -0
  3. scm2cpp_learn/_compat.py +284 -0
  4. scm2cpp_learn/_generated/__init__.py +0 -0
  5. scm2cpp_learn/_generated/_loader.py +41 -0
  6. scm2cpp_learn/_generated/_loader_accel_cublas.py +173 -0
  7. scm2cpp_learn/_generated/_loader_classifiers.py +308 -0
  8. scm2cpp_learn/_generated/_loader_derived_blas.py +29 -0
  9. scm2cpp_learn/_generated/_loader_derived_cublas.py +29 -0
  10. scm2cpp_learn/_generated/_loader_derived_loops.py +29 -0
  11. scm2cpp_learn/_generated/_loader_gpu_cuda.py +313 -0
  12. scm2cpp_learn/_generated/_loader_gramops_blas.py +692 -0
  13. scm2cpp_learn/_generated/_loader_gramops_loops.py +711 -0
  14. scm2cpp_learn/_generated/_loader_nmf_blas.py +29 -0
  15. scm2cpp_learn/_generated/_loader_nmf_cublas.py +29 -0
  16. scm2cpp_learn/_generated/_loader_nmf_loops.py +29 -0
  17. scm2cpp_learn/_generated/accel_cublas/accel.cpp +24 -0
  18. scm2cpp_learn/_generated/accel_cublas/accel.hpp +1178 -0
  19. scm2cpp_learn/_generated/accel_cublas/accel_capi.cpp +76 -0
  20. scm2cpp_learn/_generated/classifiers.cpp +37 -0
  21. scm2cpp_learn/_generated/classifiers.hpp +3745 -0
  22. scm2cpp_learn/_generated/classifiers_capi.cpp +115 -0
  23. scm2cpp_learn/_generated/derived_blas/lasso_design.cpp +5 -0
  24. scm2cpp_learn/_generated/derived_blas/lasso_design.hpp +156 -0
  25. scm2cpp_learn/_generated/derived_blas/lasso_design_capi.cpp +19 -0
  26. scm2cpp_learn/_generated/derived_cublas/lasso_design.cpp +5 -0
  27. scm2cpp_learn/_generated/derived_cublas/lasso_design.hpp +158 -0
  28. scm2cpp_learn/_generated/derived_cublas/lasso_design_capi.cpp +19 -0
  29. scm2cpp_learn/_generated/derived_loops/lasso_design.cpp +5 -0
  30. scm2cpp_learn/_generated/derived_loops/lasso_design.hpp +179 -0
  31. scm2cpp_learn/_generated/derived_loops/lasso_design_capi.cpp +19 -0
  32. scm2cpp_learn/_generated/gpu_cuda/gpu.cpp +37 -0
  33. scm2cpp_learn/_generated/gpu_cuda/gpu.hpp +3846 -0
  34. scm2cpp_learn/_generated/gpu_cuda/gpu_capi.cpp +308 -0
  35. scm2cpp_learn/_generated/gramops_blas/gramops.cpp +82 -0
  36. scm2cpp_learn/_generated/gramops_blas/gramops.hpp +5411 -0
  37. scm2cpp_learn/_generated/gramops_blas/gramops_capi.cpp +244 -0
  38. scm2cpp_learn/_generated/gramops_loops/gramops.cpp +82 -0
  39. scm2cpp_learn/_generated/gramops_loops/gramops.hpp +6395 -0
  40. scm2cpp_learn/_generated/gramops_loops/gramops_capi.cpp +250 -0
  41. scm2cpp_learn/_generated/lasso_cov.cpp +7 -0
  42. scm2cpp_learn/_generated/lasso_cov.hpp +152 -0
  43. scm2cpp_learn/_generated/lasso_cov_capi.cpp +25 -0
  44. scm2cpp_learn/_generated/nmf_blas/nmf_cd.cpp +5 -0
  45. scm2cpp_learn/_generated/nmf_blas/nmf_cd.hpp +132 -0
  46. scm2cpp_learn/_generated/nmf_blas/nmf_cd_capi.cpp +19 -0
  47. scm2cpp_learn/_generated/nmf_cublas/nmf_cd.cpp +5 -0
  48. scm2cpp_learn/_generated/nmf_cublas/nmf_cd.hpp +136 -0
  49. scm2cpp_learn/_generated/nmf_cublas/nmf_cd_capi.cpp +19 -0
  50. scm2cpp_learn/_generated/nmf_loops/nmf_cd.cpp +5 -0
  51. scm2cpp_learn/_generated/nmf_loops/nmf_cd.hpp +167 -0
  52. scm2cpp_learn/_generated/nmf_loops/nmf_cd_capi.cpp +19 -0
  53. scm2cpp_learn/_generated/scm2cpp-blas.hpp +158 -0
  54. scm2cpp_learn/_generated/scm2cpp-cublas.hpp +155 -0
  55. scm2cpp_learn/_generated/scm2cpp-cuda.hpp +285 -0
  56. scm2cpp_learn/_generated/scm2cpp.hpp +1627 -0
  57. scm2cpp_learn/_gramops_blas.cp312-win_amd64.pyd +0 -0
  58. scm2cpp_learn/_lasso_cov.cp312-win_amd64.pyd +0 -0
  59. scm2cpp_learn/_lasso_derived_blas.cp312-win_amd64.pyd +0 -0
  60. scm2cpp_learn/_libfind.py +153 -0
  61. scm2cpp_learn/_nmf_blas.cp312-win_amd64.pyd +0 -0
  62. scm2cpp_learn/batch_capi.cu +428 -0
  63. scm2cpp_learn-0.18.0.dist-info/DELVEWHEEL +2 -0
  64. scm2cpp_learn-0.18.0.dist-info/METADATA +1171 -0
  65. scm2cpp_learn-0.18.0.dist-info/RECORD +72 -0
  66. scm2cpp_learn-0.18.0.dist-info/WHEEL +5 -0
  67. scm2cpp_learn-0.18.0.dist-info/top_level.txt +1 -0
  68. scm2cpp_learn.libs/.load-order-scm2cpp_learn-0.18.0 +4 -0
  69. scm2cpp_learn.libs/libopenblas-0486735c359a67419d8832e3c40e2837.dll +4 -0
  70. scm2cpp_learn.libs/msvcp140-73438573e87f9a2fd944b01def13566d.dll +0 -0
  71. scm2cpp_learn.libs/vcruntime140-052ad6a20d375957e82aa6a3c441ea54.dll +0 -0
  72. 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.