Sender: rochcock (chen3feng), letter area: programming Title: CFC :: Array, a multi-dimensional number group 发 信 站: BBS Shuimu Tsinghua Station (WED May 29 10:46:42 2002)
Cfc :: Array Boost provides boost :: array, but that is just a one-dimensional array, this support of this support of one-dimensional, two-dimensional and three-dimensional arrays, there is no support above three-dimensional, I think you will probably don't usually use it. Is it? :) Use the standard STL container Vector to implement the multi-dimensional array, the space is discontinuous, with Boost :: Array to implement the multi-dimensional array, the space is continuous, but the Array of Boost has no base interface. I provide the number of groups to support me This supported one-dimensional, two-dimensional, and 3D array provides all arrays of the base class_base, one-dimensional array base class array_1d_base, two-dimensional array base class Array_2d_base, three-dimensional array base class Array_3d_base, this is solved The parameters of the multi-dimensional array pass the problem. This template class implements the STL interface, which can be used as using the STL container. Because I know the STL, the implementation may not be good, welcome to do it, do not realize [] and () Operators, the reason for the implementation () operator is that it is more than the array of [] to be efficient. Use () reason is the influence of the Basic language for each dimensional group itself and base class I have provided different versions of implementation, such as in base class array_2d_base, I use multiplication (), and in Array_2D, I am implemented in the original array [], it seems to be contrary to the base class non-virtual function The principle, it is not, because the overload in the derived class is done with the exact same action in the base category, but it is an optimized version, and the version of the base class is not very low, there is no need to use virtual functions, because This may slower and not convincing. The only reason for this is for efficiency. It should also be noted that because the MSVC template is not implemented, some features are not applicable, such as the definition of array in template It is considered a mistake because it treats the size of the array as 0, and the pointer is fine. I haven't solved it yet. I also wrote a Dynamic_Array class, derived from Array_1D_Base, array_2d_base, array_3d_base Haven't tried it yet, wait, and this article is not being spurred by everyone in Post. There is Share_Array ... Ten turnover, let's talk later. All classes are defined in Namespace CFC, Meams Chen Feng's Class Libraries You will see Boost :: Function and Boost :: Array's Shadow in my source code, thank you boost! Template class is very simple: #include "cfc / array.h" Using namespace cfc; void foo (array_1d_base & a) { A [0] = 10;} int main () {Array a1; // One-dimensional array array a2; // 2D array array A3; //2D array A1 [0] = 10; A1 (0) = 10; // Basic style A3 [0] (1, 1) = 10; A3 [0] [0] (0) = 10; foo (a1); foo (A2 [0]); FOO (A3 [0] [0]);} This is the source program:
The method of selecting a base class according to the template parameter can be instantiated to generate a generic class, :) file: //Array.h, array class and its implementation #ifndef _Array_H_ #define _Array_h_ #ifdef _msc_ver #define cfc_static_const (type, assign) enum {assign} #else #define static const type assign #endif #include "arrays.h" namespace cfc {namespace detail {namespace array {template struct real_get_impl {}; template <> struct real_get_impl <1> {Template Struct Dimensions {type_1d type;};}; template <> struct real_get_impl <2> { Template Struct Dimensions {TypedEf Array_2D Type;};}; Template <> Struct REAL_GET_IMPL <3> {Template Struct Dimensions {typedef Array_3D TYPE;
};}; Template Struct get_impl {cfc_static_const (int, value = int (d2! = - 1) INT (D3! = - 1) 1); typedef typeename Real_get_impl :: Template Dimensions :: Type Type;};}} template Class Array: public Detail :: Array :: Get_Impl :: Type {TYPEDEF TYPENAME DETAIL:: ARRAY:: GET_IMPL :: TYPE BASE_TYPE; PUBLIC: array () {}};} #endif file: // _ ARRAY_H_ // array_base.h #ifndef _ARRAY_BASE_H_ #define _ARRAY_BASE_H_ #include #include #include #include namespace cfc {template class array_base {public: typedef T value_type; typedef T * iterator; typedef const T * const_iterator; typedef T & reference; typedef const T & const_reference; typedef / * std * / :: size_t size_type;
typedef / * std * / :: ptrdiff_t difference_type; #ifdef _MSC_VER typedef std :: reverse_iterator reverse_iterator; typedef std :: reverse_iterator const_reverse_iterat or; #else typedef std :: reverse_iterator reverse_iterator ; typedef std :: reverse_iterator const_reverse_iterator; #endif public: iterator begin () {return pdata;} const_iterator begin () const {return pdata;} iterator end () {return pdata size ();} const_iterator end ( ) const {return pdata size ();} reverse_iterator rbegin () {return reverse_iterator (end ());} const_reverse_iterator rbegin () const {return const_reverse_iterator (end ());} reverse_iterator rend () {return reverse_iterator (begin ( ));} Const_reverse_iterator rend () const {return const_reverse_iterator (begin ());} // at () with Range Check Refere NCE AT (SIZE_TYPE I) {RangeCheck (i); Return PDATA [I];} const_reference at (SIZE_TYPE I) Const {RangeCheck (i); Return Elems [i];} //font () and back () Reference Front () {RETURN PDATA [0];} const_reference front () const {return pdata [0];} Reference back () {Return PData [Size () - 1];} const_reference back () const {return pdata [size ) -1];} // size is constant bool empty () {return pData! = 0;} size_type max_size () {return size ();} // swap (NOTE: linear complexity) file: // void swap Array & Y) {// std :: swap_rangers (begin (), end (), y.begin ());
File: //} // Direct Access To Data Const T * Data () const {return pdata;} size_type size () const {int sum = 1; for (int i = 0; i & y) {ix (size () ! = y.Size ()) throw std :: longth_error ("array"); std :: swap_ranges (begin (), end (), y.begin ());} template Array_Base & Operator = (const array_base & rhs) {std :: copy (rhs.begin (), rhs.end (), begin (); return * this;} size_t get_dims (size_t index) {Return DIMS [i } Void rangecheck (size_type i) {If (i> = size ()) {throw std :: range_error ("array");}}}}}}}} protected: array_base () {} protected: t * pdata; int Dim_count; Int Dims [3]; array_base (int D) : DIM_COUNT (D) {}}; // Comparisons Template BOOL Operator == (Const Array_Base & x, Const Array_Base & Y) {Return std :: Equal (x .begin (), x.end (), y.begin ());} template Bool Operator <
(const array_base & x, const array_base & y) {return std :: lexicographical_compare (x.begin (), x.end (), y.BEGI n (), y.end ()) Template Bool Operator! = (Const array_base & x, const array_base & y) {return! (X == y);} Template Bool Operator> (const array_base & x, const array_base & y) {return y bool operator <= (const array_base & x, const array_base & Y) {Return! (Y Bool Operator> = (Const Array_Base & X, Const Array_base & Y) {Return! (X inline void swap (array_base & x, array_base & y) {x.swap (y);} template Class array_1d_base: pu blic array_base {public: const_reference operator [] (size_type index) const {return pdata [index];} reference operator [] (size_type index) {return pdata [index];} const_reference operator () (size_type index) const {Return PDATA [INDEX];
} Reference operator () (size_type index) {return pdata [index];} public: array_1d_base (T * pd, size_type d1) {dim_count = 1; pdata = pd; dims [0] = d1;} protected: array_1d_base () {dim_count = 1;}}; template class array_2d_base: public array_base {public: const array_1d_base operator [] (size_type index) const {return array_1d_base (pdata index * dims [ 1], DIMS [1]);} Array_1D_Base Operator [] (SIZE_TYPE INDEX) {Return Array_1D_Base (PDATA INDEX * DIMS [1], DIMS [1]);} // // Basic Style Access const_reference Operator () () () size_type index1, size_type inde x2) cconst {return pdata [index1 * dims [1] index2];} reference operator () (size_type index1, size_type index2) {return pdata [index1 * dims [1] index2];} public : Array_2d_base (T * PD, SIZE_TYPE D1, SIZE_TYPE D2) {DIM_COUNT = 2; PDATA = Pd; DIMS [0] = D1; DIMS [1] = D2;
} Protected: array_2d_base () {dim_count = 2;}}; template class array_3d_base: public array_base {public: const array_2d_base operator [] (size_type index) const {return array_2d_base ( PDATA INDEX * DIMS [1] * DIMS [2], DIMS [1], DIMS [2]); 1] * DIMS [2], DIMS [1], DIMS [2]); // // Basic style access / * const_reference operator () (size_type index1, size_type index2, size_type index3) const {return pdata [index1 * dims [1] * dims [2] index2 * dims [2] index3];
} * / Reference operator () (size_type index1, size_type index2, size_type index3) {return pdata [index1 * dims [1] * dims [2] index2 * dims [2] index3];} protected: array_3d_base () { dim_count = 3;}};} #endif file: // _ ARRAY_BASE_H_ /// // arrays.h, array_1d, array_2d, array_3d implementation #ifndef _ARRAYS_H_ #define _ARRAYS_H_ #include "array_base.h" namespace cfc {template Class Array_1d: public array_1d_base {public: cfc_static_const (size_type, static_size = dim1); const_reference operator [] (size_type index) const { return data [index];} reference operator [] (size_type index) {return data [index];} // // const_reference operator () (size_type index) const {return data [index];} reference operator () (size_type Index) {return data [index];} protected: array_1d () {pData = & data [0]; DIMS [0] = DIM1;
} Protected: t data [Dim1];}; // // 2D template Class Array_2d: public array_2d_base {#ifndef _msc_ver file: // msc doesn't support ref to a template array private: typedef T (& index_type) [dim2]; typedef T const (& const_index_type) [dim2]; public: const_index_type operator [] (size_type index) const {return data [index];} index_type operator [] (size_type index) {return data [index];} #endif public: CFC_STATIC_CONST (size_type, static_size = dim1 * dim2); const_reference operator () (size_type index1, size_type index 2) coonst {return data [index1] [index2];} reference Operator () (SIZE_TYP e index1, size_type index2) {return data [index1] [index2];} protected: array_2d () {pdata = & data [0] [0]; DIMS [0] = DIM1; DIMS [1] = DIM2;} private: T Data [DIM1] [DIM2];}; /// // 3D Template Class Array_3d: public array_3d_base {#ifndef_MSC_VER PRIVATE: TYPEDEF T (& INDEX_TYPE) [DIM2] [DIM3]; TypeDef T Const (&)
const_index_type) [dim2] [dim3]; public: const_index_type operator [] (size_type index) const {return data [index];} index_type operator [] (size_type index) {return data [index];} #endif public: CFC_STATIC_CONST ( size_type, static_size = dim1 * dim2 * dim3); const_reference operator () (size_type in dex1 size_type in dex2 size_type in dex3) const {return data [index1] [index2] [index2];} reference operator () (size_type index1, size_ty PE index2, size_type index3) {return data [index1] [index2] [index3];} protected: array_3d () {pData = & data [0] [0] [0]; DIMS [0] = dim1; DIMS [1] = DIM2; DIMS [2] = DIM3;} private: t data [DIM1] [DIM2] [DIM3];};} #ENDIF / / / _ ARRAYS_H_ // The end. :) - Namespace CFC {Class Dummy {}; }