Salome HOME
24e01f6f4de74070d319e48e15af00309547d036
[modules/smesh.git] / src / MEDWrapper / Base / MED_SliceArray.hxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #ifndef MED_SliceArray_HeaderFile
23 #define MED_SliceArray_HeaderFile
24
25 #ifdef WIN32 // for correctly compiling "valarray" in modules, which includes this file
26   #undef max
27   #undef min
28 #endif
29
30 #include <valarray>
31 #include <stdexcept>
32
33 //#if defined(_DEBUG_)
34 #  define MED_TCSLICE_CHECK_RANGE
35 //#endif
36
37 namespace MED
38 {
39   //---------------------------------------------------------------
40   //! This class intends to provide a uniform way to handle multidimensional data (const version)
41   /*! 
42     It just contains a pointer to real sequence and implement proper calculation of its indexes.
43     This class deals with constant pointer to the sources data and provides const method to
44     read them (data).
45    */
46   template<class TValueType> 
47   class TCSlice
48   {
49     const TValueType* myCValuePtr; //!< Reference to source multidimensional data
50     size_t mySourceSize; //!< Size of the source multidimensional data
51     std::slice mySlice; //!< Defines algorithm of index calculation
52
53   protected:
54     void
55     check_id(size_t theId) const
56     {
57       long int anId = -1;
58       if(theId < mySlice.size()){
59         anId = mySlice.start() + theId*mySlice.stride();
60         if(anId < (long int)mySourceSize)
61           return;
62       }
63       throw std::out_of_range("TCSlice::check_id");
64     }
65
66     //! Calculate internal index to get proper element from the source multidimensional data
67     size_t
68     calculate_id(size_t theId) const
69     {
70       return mySlice.start() + theId*mySlice.stride();
71     }
72     
73     size_t
74     get_id(size_t theId) const
75     {
76 #ifdef MED_TCSLICE_CHECK_RANGE
77       check_id(theId);
78 #endif
79       return calculate_id(theId);
80     }
81     
82     size_t
83     get_id_at(size_t theId) const
84     {
85       check_id(theId);
86       return calculate_id(theId);
87     }
88
89   public:
90     typedef TValueType value_type;
91
92     //! Construct the class from bare pointer
93     TCSlice(const value_type* theValuePtr,
94             size_t theSourceSize,
95             const std::slice& theSlice): 
96       myCValuePtr(theValuePtr),
97       mySourceSize(theSourceSize),
98       mySlice(theSlice)
99     {}
100     
101     //! Construct the class from corresponding container
102     TCSlice(const TVector<value_type>& theContainer,
103             const std::slice& theSlice): 
104       myCValuePtr(&theContainer[0]),
105       mySourceSize(theContainer.size()),
106       mySlice(theSlice)
107     {}
108     
109     //! Default constructor (dangerous)
110     TCSlice():
111       myCValuePtr(NULL)
112     {}
113
114     //! Get element by its number (const version)
115     const value_type& 
116     operator[](size_t theId) const
117     {
118       return *(myCValuePtr + get_id(theId));
119     }
120     
121     const value_type& 
122     at(size_t theId) const
123     {
124       return *(myCValuePtr + get_id_at(theId));
125     }
126     
127     //! Get range of the order numbers
128     size_t
129     size() const
130     {
131       return mySlice.size();
132     }
133   };
134   
135
136   //---------------------------------------------------------------
137   //! This class extends TCSlice functionality for non-constant case
138   template<class TValueType> 
139   class TSlice: public TCSlice<TValueType>
140   {
141     TValueType* myValuePtr;
142     
143   public:
144     typedef TValueType value_type;
145     typedef TCSlice<TValueType> TSupperClass;
146
147     //! Construct the class from bare pointer
148     TSlice(value_type* theValuePtr,
149            size_t theSourceSize,
150            const std::slice& theSlice): 
151       TSupperClass(theValuePtr, theSourceSize, theSlice),
152       myValuePtr(theValuePtr)
153     {}
154     
155     //! Construct the class from corresponding container
156     TSlice(TVector<value_type>& theContainer,
157            const std::slice& theSlice): 
158       TSupperClass(theContainer, theSlice),
159       myValuePtr(&theContainer[0])
160     {}
161     
162     //! Default constructor (dangerous)
163     TSlice():
164       myValuePtr(NULL)
165     {}
166
167     //! Get element by its number
168     value_type& 
169     operator[](size_t theId)
170     {
171       return *(myValuePtr + this->get_id(theId));
172     }
173
174     value_type& 
175     at(size_t theId)
176     {
177       return *(myValuePtr + this->get_id_at(theId));
178     }
179   };
180
181 }
182
183 #undef MED_TCSLICE_CHECK_RANGE
184
185 #endif