Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/multi_array/test/generative_tests.hpp @ 29

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

updated boost from 1_33_1 to 1_34_1

File size: 7.9 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 <boost/config.hpp> /* BOOST_NO_SFINAE */
53#include <algorithm>
54#include <iostream>
55#include <vector>
56
57namespace {
58  unsigned int tests_run = 0;
59} // empty namespace
60
61struct mutable_array_tag { };
62struct const_array_tag { };
63
64template <typename Array>
65void assign_if_not_const(Array&, const const_array_tag&) {
66  // do nothing
67}
68
69template <typename Array>
70void assign_if_not_const(Array& A, const mutable_array_tag&);
71
72#ifndef MULTIARRAY_TEST_ASSIGN
73template <typename Array>
74void assign_if_not_const(Array& A, const mutable_array_tag&) {
75
76  typedef typename Array::index index;
77
78  const index idx0 = A.index_bases()[0];
79  const index idx1 = A.index_bases()[1];
80  const index idx2 = A.index_bases()[2];
81
82
83  int num = 0;
84  for (index i = idx0; i != idx0 + 2; ++i)
85    for (index j = idx1; j != idx1 + 3; ++j)
86      for (index k = idx2; k != idx2 + 4; ++k) 
87        A[i][j][k] = num++;
88}
89#endif // MULTIARRAY_TEST_ASSIGN
90
91template <typename Array>
92void assign(Array& A) {
93  assign_if_not_const(A,mutable_array_tag());
94}
95
96template <typename Array>
97void access(Array& A, const mutable_array_tag&);
98
99template <typename Array>
100void access(Array& A, const const_array_tag&);
101
102template <typename StorageOrder3,typename StorageOrder4,typename Modifier>
103int run_configuration(const StorageOrder3& so3,
104                      const StorageOrder4& so4,
105                      const Modifier& modifier) {
106  // multi_array
107  {
108    typedef boost::multi_array<int,3> array;
109    typename array::extent_gen extents;
110    {
111      array A(extents[2][3][4],so3);
112      modifier.modify(A);
113      access(A,mutable_array_tag());
114    }
115  }
116  // multi_array_ref
117  {
118    typedef boost::multi_array_ref<int,3> array_ref;
119    typename array_ref::extent_gen extents;
120    {
121      int local[24];
122      array_ref A(local,extents[2][3][4],so3);
123      modifier.modify(A);
124      access(A,mutable_array_tag());
125    }
126  }
127  // const_multi_array_ref
128  {
129    typedef boost::multi_array_ref<int,3> array_ref;
130    typedef boost::const_multi_array_ref<int,3> const_array_ref;
131    typename array_ref::extent_gen extents;
132    {
133      int local[24];
134      array_ref A(local,extents[2][3][4],so3);
135      modifier.modify(A);
136      assign(A);
137
138      const_array_ref B = A;
139      access(B,const_array_tag());
140    }
141  }
142  // sub_array
143  {
144    typedef boost::multi_array<int,4> array;
145    typename array::extent_gen extents;
146    {
147      array A(extents[2][2][3][4],so4);
148      modifier.modify(A);
149      typename array::template subarray<3>::type B = A[1];
150      access(B,mutable_array_tag());
151    }
152  }
153  // const_sub_array
154  {
155    typedef boost::multi_array<int,4> array;
156    typename array::extent_gen extents;
157    {
158      array A(extents[2][2][3][4],so4);
159      modifier.modify(A);
160      typename array::template subarray<3>::type B = A[1];
161      assign(B);
162
163      typename array::template const_subarray<3>::type C = B;
164      access(C,const_array_tag());
165    }
166  }
167  // array_view
168  {
169    typedef boost::multi_array<int,3> array;
170    typedef typename array::index_range range;
171    typename array::index_gen indices;
172    typename array::extent_gen extents;
173    {
174      typedef typename array::index index;
175
176      array A(extents[4][5][6],so3);
177      modifier.modify(A);
178      const index idx0 = A.index_bases()[0];
179      const index idx1 = A.index_bases()[1];
180      const index idx2 = A.index_bases()[2];
181
182      typename array::template array_view<3>::type B =A[
183        indices[range(idx0+1,idx0+3)]
184               [range(idx1+1,idx1+4)]
185               [range(idx2+1,idx2+5)]
186      ];
187      access(B,mutable_array_tag());
188    }
189  }
190  // const_array_view
191  {
192    typedef boost::multi_array<int,3> array;
193    typedef typename array::index_range range;
194    typename array::index_gen indices;
195    typename array::extent_gen extents;
196    {
197      typedef typename array::index index;
198
199      array A(extents[4][5][6],so3);
200      modifier.modify(A);
201      const index idx0 = A.index_bases()[0];
202      const index idx1 = A.index_bases()[1];
203      const index idx2 = A.index_bases()[2];
204
205      typename array::template array_view<3>::type B =A[
206        indices[range(idx0+1,idx0+3)]
207               [range(idx1+1,idx1+4)]
208               [range(idx2+1,idx2+5)]
209      ];
210      assign(B);
211
212      typename array::template const_array_view<3>::type C = B;
213      access(C,const_array_tag());
214    }
215  }
216  return boost::exit_success;
217}
218
219template <typename ArrayModifier>
220int run_storage_tests(const ArrayModifier& modifier) {
221  run_configuration(boost::c_storage_order(),
222                    boost::c_storage_order(),modifier);
223  run_configuration(boost::fortran_storage_order(),
224                    boost::fortran_storage_order(),modifier);
225 
226  std::size_t ordering[] = {2,0,1,3};
227  bool ascending[] = {false,true,true,true};
228  run_configuration(boost::general_storage_order<3>(ordering,ascending),
229                    boost::general_storage_order<4>(ordering,ascending),
230                    modifier); 
231
232  return boost::exit_success;
233}
234
235struct null_modifier {
236  template <typename Array>
237  void modify(Array&) const { }
238};
239
240struct set_index_base_modifier {
241  template <typename Array>
242  void modify(Array& A) const {
243#ifdef BOOST_NO_SFINAE
244    typedef boost::multi_array_types::index index;
245    A.reindex(index(1));
246#else
247    A.reindex(1);
248#endif
249  }
250};
251
252struct reindex_modifier {
253  template <typename Array>
254  void modify(Array& A) const {
255    boost::array<int,4> bases = {{1,2,3,4}};
256    A.reindex(bases);
257 }
258};
259
260struct reshape_modifier {
261  template <typename Array>
262  void modify(Array& A) const {
263    typedef typename Array::size_type size_type;
264    std::vector<size_type> old_shape(A.num_dimensions());
265    std::vector<size_type> new_shape(A.num_dimensions());
266
267    std::copy(A.shape(),A.shape()+A.num_dimensions(),old_shape.begin());
268    std::copy(old_shape.rbegin(),old_shape.rend(),new_shape.begin());
269
270    A.reshape(new_shape);
271    A.reshape(old_shape);
272  }
273};
274
275int run_generative_tests() {
276
277  run_storage_tests(null_modifier());
278  run_storage_tests(set_index_base_modifier());
279  run_storage_tests(reindex_modifier());
280  run_storage_tests(reshape_modifier());
281  std::cout << "Total Tests Run: " << tests_run << '\n';
282  return boost::exit_success;
283}
284
285#endif // GENERATIVE_TESTS_RG072001_HPP
Note: See TracBrowser for help on using the repository browser.