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 + -
显示快捷键?