generative_tests.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 286 行
HPP
286 行
#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/test/minimal.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_ASSIGNtemplate <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_ASSIGNtemplate <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>int 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()); } } return boost::exit_success;}template <typename ArrayModifier>int 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); return boost::exit_success;}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::exit_success;}#endif // GENERATIVE_TESTS_RG072001_HPP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?