// Made by David su33 // # include "stdafx. H "# include <boost/config. HPP> # include <boost/multi_array/extent_gen.hpp> # include <boost/multi_array.hpp> # include <boost/pool. HPP> # include <boost/pool/pool_alloc.hpp> # include <boost/array. HPP> # include <boost/lambda/Lambda. HPP> # include <boost/assign. HPP> # include <boost/typeof. HPP> # include <iostream> # include <cassert> # include <vector> # In Clude <algorithm> using namespace STD; typedef boost: pair <double> fastpoolallocator; typedef boost: multi_array <double, 3, struct> multi3array; void mult_array_access (multi3array & mult3 ); void show_dims (multi3array & mult3); void sub_view (multi3array & mult3); Template <class T> bool check_ptr (T & V1, T & V2); void test_multi_array () {// using namespace boost; // You can also set the storage sequence of dimensions. // multi3array Mult3array (boost: multi_array_types: extent_gen: extents () [3] [4] [5]); // multi3array mult3array (boost :: extents [3] [4] [5]); // right usage // Why cannot I directly write boost: detail: multi_array: extent_gen <3> extentgen3 = boost :: detail: multi_array: extent_gen <0> () [3] [4] [5]; // multi3array mult3array (extentgen3); // right usage //??? // The relation of operator order cannot be written, because the operator order of () is high, so // boost: detail: multi_array: extent_gen <0> () [...], [...] no first parsing // multi3array mult3array (boost: detail: multi_array: extent_gen <0> () [3] [4] [5]); // error usagemulti3array mult3array (boost: detail: multi_array: extent_gen <0> () [3] [4] [5]); // right usageint ndims = mult3array. num_dimensions (); Assert (mult3array. num_dimensions () = 3); Assert (mult3array. num_elements () = 3*4 * 5); int SZ = mult3array. size (); // boost: array <unsigned, 3> dimarray = {3, 4, 5}; multi3array mutl3array2 (dimarray); Assert (mutl3array2. num_elements () = mult3array. num_elements (); mult_array_access (mult3array); show_dims (mult3array); sub_view (mult3array);} void mult_array_access (multi3array & mult3) {boost: array <long, 3> idx = {0, 0, 0}; Assert (mult3 [0] [0] [0] = mult3 (idx )); mult3 [0] [0] [0] = 100; Assert (mult3 (idx) = 100); int I = 0; double * pdata = mult3.data (); STD: for_each (pdata, pdata + mult3.num _ elements (), boost: Lambda: _ 1 = boost: Lambda: VAR (I) ++); I = 0; // reset I = 0; Boost: array <int, 3> idx3; Assert (mult3 [0] [0] [0] = 0 ); for (INT x = 0; x <3; ++ X) {for (INT y = 0; y <4; ++ y) {for (INT z = 0; z <5; ++ Z) {idx3 = boost: Assign: list_of (x) (y) (z); Assert (mult3 (idx3) = I ++) ;}}}cout <"test passed" <Endl ;} Void show_dims (multi3array & mult3) {typedef multi3array: size_type msizetype; For (INT I = 0; I <mult3.num _ dimensions (); ++ I) {STD :: cout <"dims [" <I <"]" <"=" <mult3.shape () [I] <Endl ;} const msizetype * oldshape = mult3.shape (); vector <msizetype> V3 (3, 0); STD: Copy (oldshape, oldshape + mult3.num _ dimensions (), v3.begin ()); boost: array <int, 3> arr3 = {1, 1, 4}; // mult3.reshape (arr3); // shape must keep size Consta NT, if size is same, use this; mult3.resize (arr3); // If multi_array's num_numbers () is not same use this; for (INT I = 0; I <mult3.num _ dimensions (); ++ I) {assert (mult3.shape () [I] = arr3 [I]);} // boost_auto (shapelist, mult3.shape (); const msizetype * shapelist = mult3.shape (); cout <* mult3.shape () <Endl; // reset to old for testingmult3.resize (V3 ); // right usage // mult3.resize (oldshape); // error usage // You cannot directly assign values like this. Otherwise, the following error is reported. // The cause is that the value passed in by resize will be checked by the container. // H: \ boost \ boost_1_56_0 \ boost \ concept_check.hpp (1061 ): error c2825: 'C': Must be a class or namespace when followed by ':' // 1> H: \ boost \ boost_000056_0 \ boost \ concept_check.hpp (1040 ): see reference to class template instantiation 'boost :: collection <C> 'being compiled // 1> with // 1> [// 1> C = const unsigned int * // 1>] // 1> H: \ boost \ boost_000056_0 \ boost \ concept \ Detail \ has_constraints.hpp (42): see reference to class template instantiation 'boost :: collectionconcept <C> 'being compiled // 1> with // 1> [// 1> C = const unsigned int * // 1>] // 1> H: \ boost \ boost_000056_0 \ boost \ concept \ detail \ msvc. HPP (58): see reference to class template instantiation 'boost: Concepts :: not_satisfied <model> 'being compiled // 1> with // 1> [// 1> model = boost: collectionconcept <const u Nsigned int *> // 1>] // 1> H: \ boost \ boost_000056_0 \ boost \ concept_check.hpp (51): see reference to class template instantiation 'boost: Concepts :: require <model> 'being compiled // 1> with // 1> [// 1> model = boost :: collectionconcept <const unsigned int *> // 1>] // 1> H: \ boost \ boost_000056_0 \ boost \ multi_array.hpp (386): see reference to function template instantiation 'void boost:: function_requires <boost: c Ollectionconcept <C> (Model *) 'being compiled // 1> with // 1> [// 1> C = const unsigned int *, // 1> model = boost: collectionconcept <const unsigned int *> // 1>] // 1> H: \ boost_dev_spaces \ boost \ boost1 \ boost1.cpp (116 ): see reference to function template instantiation 'boost: multi_array <t, numdims, Allocator> & boost: multi_array <t, numdims, Allocator> :: resize <const unsigned int *> (const extentlist &) 'being Compiled // 1> with // 1> [// 1> T = double, // 1> numdims = 3, // 1> Allocator = fastpoolallocator, // 1> extentlist = const unsigned int * // 1>] // 1> H: \ boost \ boost_1_56_0 \ boost \ concept_check.hpp (1061): Error c2039: 'value _ type': is not a member of ''global namespace ''// 1> H: \ boost \ boost_1_56_0 \ boost \ concept_check.hpp (1061): Error c2146: syntax error: Missing '; 'before identifier' value _ type' // 1> H: \ boost \ Boost_000056_0 \ boost \ concept_check.hpp (1061): Error c2602: 'boost: collection <C >:: value_type 'is not a member of a base class of 'boost :: collection <C> '// 1> with // 1> [// 1> C = const unsigned int * // 1>] // 1> H: \ boost \ boost_000056_0 \ boost \ concept_check.hpp (1061): See Declaration of 'boost: collection <C> :: value_type '// 1> with // 1> [// 1> C = const unsigned int * // 1>] // 1> H: \ boost \ boost_1_56_0 \ boost \ Concept_check.hpp (1061): Error c2868: 'boost: collection <C >:: value_type ': Illegal syntax for using-Declaration; expected qualified-name // 1> with // 1> [// 1> C = const unsigned int * // 1>]} // ====== issame ============== template <class t, class U> struct missame; Template <class T, Class U> struct missame {boost_static_constant (bool, value = false) ;}; template <class T> struct missame <t, t> {boost_static_constant (Bool, value = true) ;}; // ======== staticassert ====== template <bool> struct mstaticassert; template <> struct mstaticassert <true >{}; // ==== staticassertmarco ====#define mstatic_assert_marco (Cond) do {mstaticassert <cond> SA; sa = sa;} while (0) // when the macro is defined and divided into multiple rows, \ must not contain delimiters and annotations. // for disable warning 4101, unreferenced local variable // do {} while (0) for user to add last ';' // # define sub_arrayviewvoid sub_view (Mult I3array & mult3) {// # If defined (_ msc_ver) // # pragma message ("XXX") control information output display // # If defined (sub_arrayview) // # pragma message ("sub_arrayview is defined! ") // # Endif # define sub_arrayview (x) typedef multi3array: array_view <X >:: type arrayview # X; sub_arrayview (3); sub_arrayview (2 ); sub_arrayview (1); // three indexrange statements: typedef multi3array: index_range indexrange; typedef boost: multi_array_types: index_range indexrangetype; typedef boost: detail: multi_array :: index_range <ptrdiff_t, unsigned> indexrangetype2; // bool isok = missame <indexrange, indexrangetype>: VA Lue; mstatic_assert_marco (missame <indexrange, indexrangetype >:: value); // mstatic_assert_marco (missame <int, double >:: value )); // compile mstatic_assert_marco (missame <indexrangetype, indexrangetype2>: Value); // mstatic_assert_marco (missame <int, indexrangetype2>: value )); // The compiled typedef multi3array: size_type msizetype; vector <msizetype> V (mult3.num _ dimensions (), 0); copy (mult3.shape (), mult3.shape () + Mult 3. num_dimensions (), V. begin (); copy (v. begin (), V. end (), STD: ostream_iterator <msizetype> (cout, ";"); cout <Endl; // The obtained subview is the original reference for accessing arrayview3 aview3 = mult3 [boost: indices [indexrange ()] [indexrange (1, 2)] [indexrange (3, (5)]; const msizetype * theshape = aview3.shape (); cout <"mult3-shape:"; copy (mult3.shape (), mult3.shape () + mult3.num _ dimensions (), STD:: ostream_iterator <int> (STD: cout); cout <Endl; cout <<"Aview3-shape:"; copy (aview3.shape (), aview3.shape () + mult3.num _ dimensions (), STD: ostream_iterator <int> (STD: cout )); cout <Endl; // arrayview cannot modify the size of the shape. // This location requires an index. // It cannot be written as aview3 [0] [1] [3]. subtract the starting offset {0, 1, 3} aview3 [0] [0] [0] = 10; Assert (mult3 [0] [1] [3] = 10 ); mult3 [0] [1] [3] = 1000; Assert (aview3 [0] [0] [0] = 1000); // boost :: array <msizetype, 3> idx3 = {0, 0, 0}; Boost: array <msizetype, 3> idx32 = {0, 1, 3}; Avi Ew3 (idx3) = 10; Assert (mult3 (idx32) = 10); mult3 (idx32) = 1000; Assert (aview3 (idx3) = 1000 ); // obtain the 2D view, which is equivalent to the first index always 0arrayview2 aview21 = mult3 [boost: indices [0] [indexrange ()] [indexrange (3, 5)]; arrayview2 aview22 = mult3 [boost: indices [1] [indexrange (1, 2)] [indexrange (3, 5)]; arrayview2 aview23 = mult3 [boost :: indices [2] [indexrange (1, 2)] [indexrange (3, 5)]; Assert (2 = aview21.num _ dimensions (); Assert (2 = aview22.num _ dimensions (); Assert (2 = aview23.num _ dimensions ()); // 2 = 2 is bool // 2 = (true/false) Cause error // assert (2 = 2 = 2 = 2 ); // must be falseint xoffset = 1, yoffset = 3; Boost: array <msizetype, 2> idx2 = {0, 0}; Boost: array <msizetype, 3> idx21 = {0, 0 + xoffset, 0 + yoffset}; Boost: array <msizetype, 3> idx22 = {1, 0 + xoffset, 0 + yoffset }; boost: array <msizetype, 3> idx23 = {2, 0 + xoffset, 0 + yoffset}; Check_ptr (aview21 (idx2), mult3 (idx21); check_ptr (aview22 (idx2), mult3 (idx22); check_ptr (aview23 (idx2), mult3 (idx23 )); cout <"sub-view test all passed" <Endl; # UNDEF sub_arrayview} template <class T> bool check_ptr (T & V1, T & V2) {assert (V1 = V2); Return (& V1 = & V2 );} // usage of multi_array_ref // It can be converted to one-dimensional arrays. // Most multi_array functions are available, except that resize/multi_array is derived from multi_array_ref and void multi_array_ref_usage () {boost:: Rray <double, 24> darray; For (unsigned I = 0; I <darray. size (); ++ I) {darray [I] = I + 1;} // convert to multi_array_refconst int Ndim = 3; typedef boost: multi_array_ref <double, ndim> multiarray3dimsref; typedef multiarray3dimsref: size_type partial; typedef boost: array <struct, Ndim> barray3; multiarray3dimsref REF (& darray [0], boost: direction :: extent_gen () [2] [3] [4]); multiarray3dimsref Ref2 (& darray [0], boost: extents [2] [3] [4]); barray3 barray3 = {2, 3, 4 }; multiarray3dimsref ref3 (& darray [0], barray3); Assert (Ref [0] [0] [0] = 1 ); assert (ref2 [0] [0] [0] = 1); Assert (ref3 [0] [0] [0] = 1); typedef boost :: array <mdimrefsizetype, 2> barray2; barray3 idx = {0, 0, 0}; Ref (idx) = 100; Assert (ref2 (idx) = 100 ); assert (ref3 (idx) = 100); // sub-viewtypedef boost: multi_array_types: index_range indexrange; Boost_auto (subview1, Ref [boost: indices [0] [indexrange (2, 3)] [indexrange (2, 4)]); multiarray3dimsref: array_view <2> :: type subview2 = Ref [boost: indices [0] [indexrange (2, 3)] [indexrange (2, 4)]; Assert (subview2 = subview1 ); assert (subview1 [0] [0] = Ref [0] [2] [2]); cout <"multi_array_ref test all passed! "<Endl ;}// change the base index address void reindex_multi_array () {const unsigned Ndim = 3; typedef boost: multi_array <double, Ndim, boost :: struct <double> multiarrayfastalloc; typedef multiarrayfastalloc: extent_range range; typedef boost: multi_array_types: extent_range mrange; typedef multiarrayfastalloc: size_type marraysizetype; // extents [extent_range | const_int] // extent_range can be set to change the base address. // const_int can be used to specify the index range. The index starts from 0 to multiarfastalloc Mafa (boost :: extents [mrange (1, 5)] [4] [mrange (-3, 6)]); Mafa [1] [0] [-3] = 100; // change the index boost: array <marraysizetype, 3> idx = {1, 0,-3}; Assert (Mafa (idx) = 100 ); const marraysizetype * shapelist = Mafa. SHAPE (); const marraysizetype extens [3] = {(5-1), 4, (6-(-3)}; Assert (STD: equal (shapelist, shapelist + Ndim, extens); typedef boost: multi_array_types: Index; const Index * bases = Mafa. index_bases (); Boost: array <index, 3> aindex = {1, 0,-3}; Assert (STD: equal (bases, bases + Mafa. num_dimensions (), & aindex [0]);} // a flexible sub-view. The logical expression can be used to control the range of void flexible_sub_view () {const unsigned ndims = 3; typedef boost: multi_array <double, ndims> multiarray3dims; multiarray3dims Ma (boost: multi_array_types: extent_gen: extents () [7] [8] [9]); typedef boost: multi_array_types: index_range indexrange; boost_auto (Indice, boost: indices [indexrange () <4] [2 <= indexrange () <= 6] [3 <indexrange () <= 5]); boost_auto (subview, ma [Indice]); multiarray3dims: array_view <3> :: type sb2 = ma [Indice]; Assert (sb2 = subview); const boost: multi_array_types: Index * bases = sb2.index _ bases (); Boost: array <unsigned, 3> A3 = {0, 2, 4}; STD: equal (bases, bases + sb2.num _ dimensions (), & A3 [0]);} int _ tmain (INT argc, _ tchar * argv []) {test_multi_array (); multi_array_ref_usage (); reindex_multi_array (); flexible_sub_view (); getchar (); Return 0 ;}
Boost. multi_array learning-subview usage (3)