Ticket #9684: testi.cpp

File testi.cpp, 4.7 KB (added by ilja.j.honkonen@…, 9 years ago)
Line 
1#include "array"
2#include "boost/array.hpp"
3#include "boost/coroutine/all.hpp"
4#include "functional"
5#include "iostream"
6
7namespace detail {
8
9template <
10 template <class Value_T, size_t Length> class Container_T,
11 class Value_T,
12 size_t Length,
13 size_t Index
14> class print_impl
15{
16public:
17 static void print(const Container_T<Value_T, Length>& current)
18 {
19 print_impl<Container_T, Value_T, Length, Index - 1>::print(current);
20 std::cout << current[Index] << " ";
21 }
22};
23
24template <
25 template <class Value_T, size_t Length> class Container_T,
26 class Value_T,
27 size_t Length
28> class print_impl<Container_T, Value_T, Length, 0>
29{
30public:
31 static void print(const Container_T<Value_T, Length>& current)
32 {
33 std::cout << current[0] << " ";
34 }
35};
36
37} // namespace detail
38
39
40template <
41 template <class Value_T, size_t Length> class Container_T,
42 class Value_T,
43 size_t Length
44> void print(const Container_T<Value_T, Length>& current)
45{
46 detail::print_impl<
47 Container_T,
48 Value_T,
49 Length,
50 Length - 1
51 >::print(current);
52 std::cout << std::endl;
53}
54
55
56namespace detail {
57
58//! iterates over values in dimension Index
59template <
60 template <class Value_T, size_t Length> class Container_T,
61 class Value_T,
62 size_t Length,
63 size_t Index
64> class volume_iterator_impl
65{
66public:
67 static void iterate(
68 typename boost::coroutines::coroutine<
69 Container_T<Value_T, Length>
70 >::push_type& sink,
71 Container_T<Value_T, Length>& current,
72 const Container_T<Value_T, Length>& start,
73 const Container_T<Value_T, Length>& end,
74 const Container_T<Value_T, Length>& increment
75 ) {
76 for(
77 current[Index] = start[Index] + increment[Index] / Value_T(2);
78 current[Index] < end[Index];
79 current[Index] += increment[Index]
80 ) {
81 volume_iterator_impl<
82 Container_T,
83 Value_T,
84 Length,
85 Index - 1
86 >::iterate(
87 sink,
88 current,
89 start,
90 end,
91 increment
92 );
93 }
94 }
95};
96
97//! iterates over values of the last dimension
98template <
99 template <class Value_T, size_t Length> class Container_T,
100 class Value_T,
101 size_t Length
102> class volume_iterator_impl<Container_T, Value_T, Length, 0>
103{
104public:
105 static void iterate(
106 typename boost::coroutines::coroutine<
107 Container_T<Value_T, Length>
108 >::push_type& sink,
109 Container_T<Value_T, Length>& current,
110 const Container_T<Value_T, Length>& start,
111 const Container_T<Value_T, Length>& end,
112 const Container_T<Value_T, Length>& increment
113 ) {
114 for(
115 current[0] = start[0] + increment[0] / Value_T(2);
116 current[0] < end[0];
117 current[0] += increment[0]
118 ) {
119 sink(current);
120 }
121 }
122};
123
124} // namespace detail
125
126
127template <
128 template <class Value_T, size_t Length> class Container_T,
129 class Value_T,
130 size_t Length
131> typename boost::coroutines::coroutine<
132 Container_T<Value_T, Length>
133>::pull_type volume_iterator(
134 const Container_T<Value_T, Length>& start,
135 const Container_T<Value_T, Length>& end,
136 const size_t samples
137) {
138 Container_T<Value_T, Length> increment;
139
140 for (size_t i = 0; i < Length; i++) {
141 increment[i] = (end[i] - start[i]) / samples;
142 }
143
144 return
145 typename boost::coroutines::coroutine<
146 Container_T<Value_T, Length>
147 >::pull_type(
148 std::bind(
149 &detail::volume_iterator_impl<
150 Container_T,
151 Value_T,
152 Length,
153 Length - 1
154 >::iterate,
155 std::placeholders::_1,
156 Container_T<Value_T, Length>(),
157 start,
158 end,
159 increment
160 )
161 );
162}
163
164int main()
165{
166 const size_t samples = 2;
167 std::cout << "Number of samples per dimension: " << samples
168 << std::endl << std::endl;
169
170 std::cout << "std::array<double, 1>:" << std::endl;
171 {
172 std::array<double, 1> start, end;
173
174 for (size_t i = 0; i < start.size(); i++) {
175 end[i] = (i + 1);
176 start[i] = -end[i];
177 }
178
179 std::cout << "start: ";
180 print(start);
181 std::cout << "end: ";
182 print(end);
183
184 std::cout << "iteration:" << std::endl;
185 for (const auto& i: volume_iterator(start, end, samples)) {
186 print(i);
187 }
188
189 std::cout << std::endl;
190 }
191
192 std::cout << "std::array<double, 3>:" << std::endl;
193 {
194 std::array<double, 3> start, end;
195
196 for (size_t i = 0; i < start.size(); i++) {
197 end[i] = 2 * (i + 1);
198 start[i] = -end[i];
199 }
200
201 std::cout << "start: ";
202 print(start);
203 std::cout << "end: ";
204 print(end);
205
206 std::cout << "iteration:" << std::endl;
207 for (const auto& i: volume_iterator(start, end, samples)) {
208 print(i);
209 }
210
211 std::cout << std::endl;
212 }
213
214 std::cout << "boost::array<double, 2>:" << std::endl;
215 {
216 boost::array<double, 2> start, end;
217
218 for (size_t i = 0; i < start.size(); i++) {
219 end[i] = (i + 2) * (i + 2);
220 start[i] = -end[i];
221 }
222
223 std::cout << "start: ";
224 print(start);
225 std::cout << "end: ";
226 print(end);
227
228 std::cout << "iteration:" << std::endl;
229 for (const auto& i: volume_iterator(start, end, samples)) {
230 print(i);
231 }
232
233 std::cout << std::endl;
234 }
235
236 return 0;
237}