123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- #ifndef GENERATIVE_TESTS_RG072001_HPP
- #define GENERATIVE_TESTS_RG072001_HPP
- // Copyright 2002 The Trustees of Indiana University.
- // Use, modification and distribution is subject to the Boost Software
- // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Boost.MultiArray Library
- // Authors: Ronald Garcia
- // Jeremy Siek
- // Andrew Lumsdaine
- // See http://www.boost.org/libs/multi_array for documentation.
- //
- // generative-tests.hpp - Framework for running tests on all the types
- // of multi_array
- //
- // In order to create a set of tests, you must define the following two
- // function signatures:
- // template <typename Array>
- // void access(Array& A, const mutable_array_tag&);
- //
- // template <typename Array>
- // void access(Array& A, const const_array_tag&);
- //
- // The framework will always pass 2x3x4 arrays into these functions.
- // The const_array_tag version of access must NOT attempt to modify
- // the array. Assume that the passed array has constness in this case.
- //
- // The mutable_array_tag version of access should pass the array to the
- // assign() function in order to set its values before running tests.
- //
- // If you wish to write your own code to assign data to the array
- // (ie. test the iterators by assigning data with them), you must
- // #define MULTIARRAY_TEST_ASSIGN before including this file.
- // assign() will call this function.
- //
- // If you wish to know how many tests were run, you must increment
- // the global variable 'tests_run' somewhere in your test code.
- //
- // Since generative-tests uses the Boost.Test framework, you must
- // define at least the following:
- //
- // int test_main(int,char*[]) { return run_generative_tests(); }
- //
- #include <boost/multi_array.hpp>
- #include <boost/core/lightweight_test.hpp>
- #include <boost/config.hpp> /* BOOST_NO_SFINAE */
- #include <algorithm>
- #include <iostream>
- #include <vector>
- namespace {
- unsigned int tests_run = 0;
- } // empty namespace
- struct mutable_array_tag { };
- struct const_array_tag { };
- template <typename Array>
- void assign_if_not_const(Array&, const const_array_tag&) {
- // do nothing
- }
- template <typename Array>
- void assign_if_not_const(Array& A, const mutable_array_tag&);
- #ifndef MULTIARRAY_TEST_ASSIGN
- template <typename Array>
- void assign_if_not_const(Array& A, const mutable_array_tag&) {
- typedef typename Array::index index;
- const index idx0 = A.index_bases()[0];
- const index idx1 = A.index_bases()[1];
- const index idx2 = A.index_bases()[2];
- int num = 0;
- for (index i = idx0; i != idx0 + 2; ++i)
- for (index j = idx1; j != idx1 + 3; ++j)
- for (index k = idx2; k != idx2 + 4; ++k)
- A[i][j][k] = num++;
- }
- #endif // MULTIARRAY_TEST_ASSIGN
- template <typename Array>
- void assign(Array& A) {
- assign_if_not_const(A,mutable_array_tag());
- }
- template <typename Array>
- void access(Array& A, const mutable_array_tag&);
- template <typename Array>
- void access(Array& A, const const_array_tag&);
- template <typename StorageOrder3,typename StorageOrder4,typename Modifier>
- void run_configuration(const StorageOrder3& so3,
- const StorageOrder4& so4,
- const Modifier& modifier) {
- // multi_array
- {
- typedef boost::multi_array<int,3> array;
- typename array::extent_gen extents;
- {
- array A(extents[2][3][4],so3);
- modifier.modify(A);
- access(A,mutable_array_tag());
- }
- }
- // multi_array_ref
- {
- typedef boost::multi_array_ref<int,3> array_ref;
- typename array_ref::extent_gen extents;
- {
- int local[24];
- array_ref A(local,extents[2][3][4],so3);
- modifier.modify(A);
- access(A,mutable_array_tag());
- }
- }
- // const_multi_array_ref
- {
- typedef boost::multi_array_ref<int,3> array_ref;
- typedef boost::const_multi_array_ref<int,3> const_array_ref;
- typename array_ref::extent_gen extents;
- {
- int local[24];
- array_ref A(local,extents[2][3][4],so3);
- modifier.modify(A);
- assign(A);
- const_array_ref B = A;
- access(B,const_array_tag());
- }
- }
- // sub_array
- {
- typedef boost::multi_array<int,4> array;
- typename array::extent_gen extents;
- {
- array A(extents[2][2][3][4],so4);
- modifier.modify(A);
- typename array::template subarray<3>::type B = A[1];
- access(B,mutable_array_tag());
- }
- }
- // const_sub_array
- {
- typedef boost::multi_array<int,4> array;
- typename array::extent_gen extents;
- {
- array A(extents[2][2][3][4],so4);
- modifier.modify(A);
- typename array::template subarray<3>::type B = A[1];
- assign(B);
- typename array::template const_subarray<3>::type C = B;
- access(C,const_array_tag());
- }
- }
- // array_view
- {
- typedef boost::multi_array<int,3> array;
- typedef typename array::index_range range;
- typename array::index_gen indices;
- typename array::extent_gen extents;
- {
- typedef typename array::index index;
- array A(extents[4][5][6],so3);
- modifier.modify(A);
- const index idx0 = A.index_bases()[0];
- const index idx1 = A.index_bases()[1];
- const index idx2 = A.index_bases()[2];
- typename array::template array_view<3>::type B =A[
- indices[range(idx0+1,idx0+3)]
- [range(idx1+1,idx1+4)]
- [range(idx2+1,idx2+5)]
- ];
- access(B,mutable_array_tag());
- }
- }
- // const_array_view
- {
- typedef boost::multi_array<int,3> array;
- typedef typename array::index_range range;
- typename array::index_gen indices;
- typename array::extent_gen extents;
- {
- typedef typename array::index index;
- array A(extents[4][5][6],so3);
- modifier.modify(A);
- const index idx0 = A.index_bases()[0];
- const index idx1 = A.index_bases()[1];
- const index idx2 = A.index_bases()[2];
- typename array::template array_view<3>::type B =A[
- indices[range(idx0+1,idx0+3)]
- [range(idx1+1,idx1+4)]
- [range(idx2+1,idx2+5)]
- ];
- assign(B);
- typename array::template const_array_view<3>::type C = B;
- access(C,const_array_tag());
- }
- }
- }
- template <typename ArrayModifier>
- void run_storage_tests(const ArrayModifier& modifier) {
- run_configuration(boost::c_storage_order(),
- boost::c_storage_order(),modifier);
- run_configuration(boost::fortran_storage_order(),
- boost::fortran_storage_order(),modifier);
-
- std::size_t ordering[] = {2,0,1,3};
- bool ascending[] = {false,true,true,true};
- run_configuration(boost::general_storage_order<3>(ordering,ascending),
- boost::general_storage_order<4>(ordering,ascending),
- modifier);
- }
- struct null_modifier {
- template <typename Array>
- void modify(Array&) const { }
- };
- struct set_index_base_modifier {
- template <typename Array>
- void modify(Array& A) const {
- #ifdef BOOST_NO_SFINAE
- typedef boost::multi_array_types::index index;
- A.reindex(index(1));
- #else
- A.reindex(1);
- #endif
- }
- };
- struct reindex_modifier {
- template <typename Array>
- void modify(Array& A) const {
- boost::array<int,4> bases = {{1,2,3,4}};
- A.reindex(bases);
- }
- };
- struct reshape_modifier {
- template <typename Array>
- void modify(Array& A) const {
- typedef typename Array::size_type size_type;
- std::vector<size_type> old_shape(A.num_dimensions());
- std::vector<size_type> new_shape(A.num_dimensions());
- std::copy(A.shape(),A.shape()+A.num_dimensions(),old_shape.begin());
- std::copy(old_shape.rbegin(),old_shape.rend(),new_shape.begin());
- A.reshape(new_shape);
- A.reshape(old_shape);
- }
- };
- int run_generative_tests() {
- run_storage_tests(null_modifier());
- run_storage_tests(set_index_base_modifier());
- run_storage_tests(reindex_modifier());
- run_storage_tests(reshape_modifier());
- std::cout << "Total Tests Run: " << tests_run << '\n';
- return boost::report_errors();
- }
- #endif // GENERATIVE_TESTS_RG072001_HPP
|