Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/multi_array/test/generative_tests.hpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 7.7 KB
Line 
1#ifndef GENERATIVE_TESTS_RG072001_HPP
2#define GENERATIVE_TESTS_RG072001_HPP
3
4// Copyright 2002 The Trustees of Indiana University.
5
6// Use, modification and distribution is subject to the Boost Software
7// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10//  Boost.MultiArray Library
11//  Authors: Ronald Garcia
12//           Jeremy Siek
13//           Andrew Lumsdaine
14//  See http://www.boost.org/libs/multi_array for documentation.
15
16//
17// generative-tests.hpp - Framework for running tests on all the types
18//   of multi_array
19//
20//  In order to create a set of tests, you must define the following two
21//  function signatures:
22//   template <typename Array>
23//   void access(Array& A, const mutable_array_tag&);
24//
25//   template <typename Array>
26//   void access(Array& A, const const_array_tag&);
27//
28//  The framework will always pass 2x3x4 arrays into these functions.
29//  The const_array_tag version of access must NOT attempt to modify
30//  the array.  Assume that the passed array has constness in this case.
31//
32//  The mutable_array_tag version of access should pass the array to the
33//  assign() function in order to set its values before running tests.
34//
35//  If you wish to write your own code to assign data to the array
36//  (ie. test the iterators by assigning data with them), you must
37//  #define MULTIARRAY_TEST_ASSIGN before including this file.
38//  assign() will call this function.
39//
40//  If you wish to know how many tests were run, you must increment
41//  the global variable 'tests_run' somewhere in your test code.
42//
43//  Since generative-tests uses the Boost.Test framework, you must
44//  define at least the following:
45//
46//  int test_main(int,char*[]) { return run_generative_tests(); }
47//
48#include "boost/multi_array.hpp"
49
50#include "boost/test/minimal.hpp"
51
52#include <algorithm>
53#include <iostream>
54#include <vector>
55
56namespace {
57  unsigned int tests_run = 0;
58} // empty namespace
59
60struct mutable_array_tag { };
61struct const_array_tag { };
62
63template <typename Array>
64void assign_if_not_const(Array&, const const_array_tag&) {
65  // do nothing
66}
67
68template <typename Array>
69void assign_if_not_const(Array& A, const mutable_array_tag&);
70
71#ifndef MULTIARRAY_TEST_ASSIGN
72template <typename Array>
73void assign_if_not_const(Array& A, const mutable_array_tag&) {
74
75  typedef typename Array::index index;
76
77  const index idx0 = A.index_bases()[0];
78  const index idx1 = A.index_bases()[1];
79  const index idx2 = A.index_bases()[2];
80
81
82  int num = 0;
83  for (index i = idx0; i != idx0 + 2; ++i)
84    for (index j = idx1; j != idx1 + 3; ++j)
85      for (index k = idx2; k != idx2 + 4; ++k) 
86        A[i][j][k] = num++;
87}
88#endif // MULTIARRAY_TEST_ASSIGN
89
90template <typename Array>
91void assign(Array& A) {
92  assign_if_not_const(A,mutable_array_tag());
93}
94
95template <typename Array>
96void access(Array& A, const mutable_array_tag&);
97
98template <typename Array>
99void access(Array& A, const const_array_tag&);
100
101template <typename StorageOrder3,typename StorageOrder4,typename Modifier>
102int run_configuration(const StorageOrder3& so3,
103                      const StorageOrder4& so4,
104                      const Modifier& modifier) {
105  // multi_array
106  {
107    typedef boost::multi_array<int,3> array;
108    typename array::extent_gen extents;
109    {
110      array A(extents[2][3][4],so3);
111      modifier.modify(A);
112      access(A,mutable_array_tag());
113    }
114  }
115  // multi_array_ref
116  {
117    typedef boost::multi_array_ref<int,3> array_ref;
118    typename array_ref::extent_gen extents;
119    {
120      int local[24];
121      array_ref A(local,extents[2][3][4],so3);
122      modifier.modify(A);
123      access(A,mutable_array_tag());
124    }
125  }
126  // const_multi_array_ref
127  {
128    typedef boost::multi_array_ref<int,3> array_ref;
129    typedef boost::const_multi_array_ref<int,3> const_array_ref;
130    typename array_ref::extent_gen extents;
131    {
132      int local[24];
133      array_ref A(local,extents[2][3][4],so3);
134      modifier.modify(A);
135      assign(A);
136
137      const_array_ref B = A;
138      access(B,const_array_tag());
139    }
140  }
141  // sub_array
142  {
143    typedef boost::multi_array<int,4> array;
144    typename array::extent_gen extents;
145    {
146      array A(extents[2][2][3][4],so4);
147      modifier.modify(A);
148      typename array::template subarray<3>::type B = A[1];
149      access(B,mutable_array_tag());
150    }
151  }
152  // const_sub_array
153  {
154    typedef boost::multi_array<int,4> array;
155    typename array::extent_gen extents;
156    {
157      array A(extents[2][2][3][4],so4);
158      modifier.modify(A);
159      typename array::template subarray<3>::type B = A[1];
160      assign(B);
161
162      typename array::template const_subarray<3>::type C = B;
163      access(C,const_array_tag());
164    }
165  }
166  // array_view
167  {
168    typedef boost::multi_array<int,3> array;
169    typedef typename array::index_range range;
170    typename array::index_gen indices;
171    typename array::extent_gen extents;
172    {
173      typedef typename array::index index;
174
175      array A(extents[4][5][6],so3);
176      modifier.modify(A);
177      const index idx0 = A.index_bases()[0];
178      const index idx1 = A.index_bases()[1];
179      const index idx2 = A.index_bases()[2];
180
181      typename array::template array_view<3>::type B =A[
182        indices[range(idx0+1,idx0+3)]
183               [range(idx1+1,idx1+4)]
184               [range(idx2+1,idx2+5)]
185      ];
186      access(B,mutable_array_tag());
187    }
188  }
189  // const_array_view
190  {
191    typedef boost::multi_array<int,3> array;
192    typedef typename array::index_range range;
193    typename array::index_gen indices;
194    typename array::extent_gen extents;
195    {
196      typedef typename array::index index;
197
198      array A(extents[4][5][6],so3);
199      modifier.modify(A);
200      const index idx0 = A.index_bases()[0];
201      const index idx1 = A.index_bases()[1];
202      const index idx2 = A.index_bases()[2];
203
204      typename array::template array_view<3>::type B =A[
205        indices[range(idx0+1,idx0+3)]
206               [range(idx1+1,idx1+4)]
207               [range(idx2+1,idx2+5)]
208      ];
209      assign(B);
210
211      typename array::template const_array_view<3>::type C = B;
212      access(C,const_array_tag());
213    }
214  }
215  return boost::exit_success;
216}
217
218template <typename ArrayModifier>
219int run_storage_tests(const ArrayModifier& modifier) {
220  run_configuration(boost::c_storage_order(),
221                    boost::c_storage_order(),modifier);
222  run_configuration(boost::fortran_storage_order(),
223                    boost::fortran_storage_order(),modifier);
224 
225  std::size_t ordering[] = {2,0,1,3};
226  bool ascending[] = {false,true,true,true};
227  run_configuration(boost::general_storage_order<3>(ordering,ascending),
228                    boost::general_storage_order<4>(ordering,ascending),
229                    modifier); 
230
231  return boost::exit_success;
232}
233
234struct null_modifier {
235  template <typename Array>
236  void modify(Array&) const { }
237};
238
239struct set_index_base_modifier {
240  template <typename Array>
241  void modify(Array& A) const { A.reindex(1); }
242};
243
244struct reindex_modifier {
245  template <typename Array>
246  void modify(Array& A) const {
247    boost::array<int,4> bases = {{1,2,3,4}};
248    A.reindex(bases);
249 }
250};
251
252struct reshape_modifier {
253  template <typename Array>
254  void modify(Array& A) const {
255    typedef typename Array::size_type size_type;
256    std::vector<size_type> old_shape(A.num_dimensions());
257    std::vector<size_type> new_shape(A.num_dimensions());
258
259    std::copy(A.shape(),A.shape()+A.num_dimensions(),old_shape.begin());
260    std::copy(old_shape.rbegin(),old_shape.rend(),new_shape.begin());
261
262    A.reshape(new_shape);
263    A.reshape(old_shape);
264  }
265};
266
267int run_generative_tests() {
268
269  run_storage_tests(null_modifier());
270  run_storage_tests(set_index_base_modifier());
271  run_storage_tests(reindex_modifier());
272  run_storage_tests(reshape_modifier());
273  std::cout << "Total Tests Run: " << tests_run << '\n';
274  return boost::exit_success;
275}
276
277#endif // GENERATIVE_TESTS_RG072001_HPP
Note: See TracBrowser for help on using the repository browser.