1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 #ifndef itkArray_h
19 #define itkArray_h
20
21 #include "itkMacro.h"
22
23 #include "vxl_version.h"
24 #include "vnl/vnl_vector.h"
25
26 namespace itk
27 {
28 /** \class Array
29 * \brief Array class with size defined at construction time.
30 *
31 * This class derives from the vnl_vector<> class.
32 * Its size is assigned at construction time (run time) and can
33 * not be changed afterwards except by using assignment to another
34 * Array.
35 *
36 * The class is templated over the type of the elements.
37 *
38 * Template parameters for class Array:
39 *
40 * - TValue = Element type stored at each location in the array.
41 *
42 * \ingroup DataRepresentation
43 * \ingroup ITKCommon
44 */
45 template< typename TValue >
46 class ITK_TEMPLATE_EXPORT Array : public vnl_vector< TValue >
47 {
48 public:
49
50 /** The element type stored at each location in the Array. */
51 using ValueType = TValue;
52 using Self = Array;
53 using VnlVectorType = vnl_vector< TValue >;
54 using SizeValueType = typename vnl_vector< TValue>::size_type;
55
56 public:
57
58 /** Default constructor. It is created with an empty array
59 * it has to be allocated later by assignment */
60 Array();
61
62 /** Copy constructor. Uses VNL copy construtor with correct
63 * setting for memory management. */
64 Array(const Array&);
65
66 /** Constructor with size. Size can only be changed by assignment */
67 explicit Array(SizeValueType dimension);
68
69 /** Constructor that initializes array with contents from a user supplied
70 * buffer. The pointer to the buffer and the length is specified. By default,
71 * the array does not manage the memory of the buffer. It merely points to
72 * that location and it is the user's responsibility to delete it.
73 * If "LetArrayManageMemory" is true, then this class will free the
74 * memory when this object is destroyed. */
75 Array(ValueType *data, SizeValueType sz, bool LetArrayManageMemory = false);
76
77 #if defined ( ITK_LEGACY_REMOVE )
78 /** Constructor that initializes array with contents from a user supplied
79 * const buffer. The pointer to the buffer and the length is specified. By default,
80 * the array does a deep copy of the const pointer data, so the array class also
81 * manages memory. */
82 Array(const ValueType *datain, SizeValueType sz);
83
84 #else // defined ( ITK_LEGACY_REMOVE )
85 /** Constructor that initializes array with contents from a user supplied
86 * buffer. The pointer to the buffer and the length is specified. By default,
87 * the array does not manage the memory of the buffer. It merely points to
88 * that location and it is the user's responsibility to delete it.
89 * If "LetArrayManageMemory" is true, then this class will free the
90 * memory when this object is destroyed. */
91 Array(const ValueType *data, SizeValueType sz,
92 bool LetArrayManageMemory = false);
93 #endif
94
95 /** Constructor to initialize an array from another of any data type */
96 template< typename TArrayValue >
Array(const Array<TArrayValue> & r)97 Array(const Array< TArrayValue > & r)
98 {
99 this->m_LetArrayManageMemory = true;
100 this->SetSize( r.GetSize() );
101 for( SizeValueType i=0; i<r.GetSize(); i++ )
102 {
103 this->operator[](i) = static_cast< TValue >( r[i] );
104 }
105 }
106
107 /** Set the all the elements of the array to the specified value */
Fill(TValue const & v)108 void Fill(TValue const & v)
109 {
110 this->fill(v);
111 }
112
113 /** Copy opertor */
114 const Self & operator=(const Self & rhs);
115
116 const Self & operator=(const VnlVectorType & rhs);
117
118 /** Return the number of elements in the Array */
Size()119 SizeValueType Size() const
120 { return static_cast<SizeValueType >( this->size() ); }
GetNumberOfElements()121 unsigned int GetNumberOfElements() const
122 { return static_cast<SizeValueType >( this->size() ); }
123
124 /** Get one element */
GetElement(SizeValueType i)125 const TValue & GetElement(SizeValueType i) const
126 { return this->operator[](i); }
127
128 /** Set one element */
SetElement(SizeValueType i,const TValue & value)129 void SetElement(SizeValueType i, const TValue & value)
130 { this->operator[](i) = value; }
131
132 /** Destructively set the size to that given. Will lose data. */
133 void SetSize(SizeValueType sz);
134
GetSize()135 SizeValueType GetSize() const
136 { return static_cast< SizeValueType >( this->size() ); }
137
138 /** Set the pointer from which the data is imported.
139 * If "LetArrayManageMemory" is false, then the application retains
140 * the responsibility of freeing the memory for this data. If
141 * "LetArrayManageMemory" is true, then this class will free the
142 * memory when this object is destroyed.
143 * NOTE: This signature requires that internal array is being
144 * replaced by data array of exactly the same size
145 */
146 void SetDataSameSize(TValue *data, bool LetArrayManageMemory = false);
147
148 /** Similar to the previous method. In the above method, the size must be
149 * separately set prior to using user-supplied data. This introduces an
150 * unnecessary allocation step to be performed. This method avoids it
151 * and should be used to import data wherever possible to avoid this.
152 * Set the pointer from which the data is imported.
153 * If "LetArrayManageMemory" is false, then the application retains
154 * the responsibility of freeing the memory for this data. If
155 * "LetArrayManageMemory" is true, then this class will free the
156 * memory when this object is destroyed. */
157 void SetData(TValue *data, SizeValueType sz, bool LetArrayManageMemory = false);
158
159 #ifdef __INTEL_COMPILER
160 #pragma warning disable 444 //destructor for base class "itk::Array<>" is not virtual
161 #endif
162 /** This destructor is not virtual for performance reasons. However, this
163 * means that subclasses cannot allocate memory. */
164 ~Array();
165
166 #if ! defined ( ITK_LEGACY_REMOVE )
swap(Array & other)167 void swap(Array &other)
168 {
169 this->Swap(other);
170 }
171 #endif
172
Swap(Array & other)173 void Swap(Array &other)
174 {
175 using std::swap;
176 this->VnlVectorType::swap(other);
177 swap(this->m_LetArrayManageMemory, other.m_LetArrayManageMemory);
178 }
179
180 private:
181
182 bool m_LetArrayManageMemory;
183 };
184
185 template< typename TValue >
186 std::ostream & operator<<(std::ostream & os, const Array< TValue > & arr)
187 {
188 os << "[";
189 const unsigned int length = arr.size();
190 if ( length >= 1 )
191 {
192 const unsigned int last = length - 1;
193 for ( unsigned int i = 0; i < last; ++i )
194 {
195 os << arr[i] << ", ";
196 }
197 os << arr[last];
198 }
199 os << "]";
200 return os;
201 }
202
203 // declaration of specialization
204 template<> ITKCommon_EXPORT std::ostream & operator<< <double> (std::ostream & os, const Array< double > & arr);
205 template<> ITKCommon_EXPORT std::ostream & operator<< <float> (std::ostream & os, const Array< float > & arr);
206
207
208 template<typename T>
swap(Array<T> & a,Array<T> & b)209 inline void swap( Array<T> &a, Array<T> &b )
210 {
211 a.Swap(b);
212 }
213
214 } // namespace itk
215
216 #ifndef ITK_MANUAL_INSTANTIATION
217 #include "itkArray.hxx"
218 #endif
219
220 #endif
221