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 itkVariableLengthVector_h
19 #define itkVariableLengthVector_h
20 
21 #include <cassert>
22 #include <algorithm>
23 #include "itkNumericTraits.h"
24 #include "itkStaticAssert.h"
25 #include "itkMetaProgrammingLibrary.h"
26 #include "itkEnableIf.h"
27 #include "itkIsBaseOf.h"
28 #include "itkIsNumber.h"
29 #include "itkPromoteType.h"
30 #include "itkBinaryOperationConcept.h"
31 
32 namespace itk
33 {
34 
35 template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
36 struct VariableLengthVectorExpression;
37 
38 /** \class VariableLengthVector
39  * \brief Represents an array whose length can be defined at run-time.
40  *
41  * This class is templated over the data type. This data-type is meant
42  * to be a scalar, such as float, double etc...
43  *
44  * \note
45  * ITK itself provides several classes that can serve as \c Arrays.
46  * \li FixedArray - Compile time fixed length arrays that's intended to
47  * represent an enumerated collection of \c n entities.
48  *
49  * \li Array - Run time resizeable array that is intended to hold a
50  * collection of \c n entities
51  *
52  * \li Vector - Compile time fixed length array that is intended to hold
53  * a collection of \c n data types. A vector usually has a mathematical meaning.
54  * It should only be used when mathematical operations such as addition,
55  * multiplication by a scalar, product etc make sense.
56  *
57  * \li VariableLengthVector - Run time array that is intended to hold a collection
58  * of scalar data types. Again, it should be used only when mathematical
59  * operations on it are relevant. If not, use an Array.
60  *
61  * \li Point - Represents the spatial coordinates of a spatial location. Operators
62  * on Point reflect geometrical concepts.
63  *
64  * \par For the reasons listed above, you cannot instantiate
65  * \code VariableLengthVector< bool > \endcode.
66  *
67  * \par
68  * Design Considerations: We do not derive from \c vnl_vector to avoid being
69  * limited by the explicit template instantiations of vnl_vector and other
70  * hacks that vnl folks have been forced to use.
71  *
72  * \note
73  * This work is part of the National Alliance for Medical Image Computing
74  * (NAMIC), funded by the National Institutes of Health through the NIH Roadmap
75  * for Medical Research, Grant U54 EB005149.
76  *
77  * \sa CovariantVector
78  * \sa SymmetricSecondRankTensor
79  * \sa RGBPixel
80  * \sa DiffusionTensor3D
81  * \ingroup DataRepresentation
82  * \ingroup ITKCommon
83  *
84  * \wiki
85  * \wikiexample{SimpleOperations/VariableLengthVector,Variable length vector}
86  * \endwiki
87  *
88  * \invariant If \c m_LetArrayManageMemory is true, \c m_Data is deletable
89  * (whether it's null or pointing to something with no elements. i.e. \c
90  * m_NumElements may be 0 and yet \c m_Data may be not null.)
91  */
92 template< typename TValue >
93 class ITK_TEMPLATE_EXPORT VariableLengthVector
94 {
95 public:
96   /**\name Policies
97    * The following Policies will be used by \c itk::VariableLengthVector::SetSize
98    */
99   //@{
100   /** \c VariableLengthVector empty base-class for allocation policies.
101    * All Allocation Policies are expected to inherit from this empty base
102    * class.
103    *
104    * \sa \c itk::VariableLengthVector::SetSize
105    * \sa \c NeverReallocate
106    * \sa \c ShrinkToFit
107    * \sa \c DontShrinkToFit
108    * \ingroup ITKCommon
109    * \ingroup DataRepresentation
110    */
111   struct AllocateRootPolicy {};
112 
113   /** \c VariableLengthVector Allocation Policy: Always reallocate memory.
114    * This policy, when used from \c VariableLengthVector::SetSize(), always
115    * implies that the previous internal buffer will be reallocated. Even if
116    * enough memory was available.
117    * \return true (always)
118    *
119    * \sa \c itk::VariableLengthVector::SetSize
120    * \sa \c NeverReallocate
121    * \sa \c ShrinkToFit
122    * \sa \c DontShrinkToFit
123    * \ingroup ITKCommon
124    * \ingroup DataRepresentation
125    */
126   struct AlwaysReallocate : AllocateRootPolicy
127     {
operatorAlwaysReallocate128     bool operator()(unsigned int itkNotUsed(newSize), unsigned int itkNotUsed(oldSize)) const
129       {
130       return true;
131       }
132     };
133 
134   /** \c VariableLengthVector Allocation Policy: Never reallocate memory.
135    * This policy, when used from \c VariableLengthVector::SetSize(), always
136    * implies that the previous internal buffer will be kept. Even if not enough
137    * memory was available.
138    *
139    * The typical use case of this policy is to make sure a \c
140    * VariableLengthVector is not a proxy object.
141    * \return false (always)
142    *
143    * \pre <tt>oldSize == newSize</tt>, checked by assertion
144    *
145    * \sa \c itk::VariableLengthVector::SetSize
146    * \sa \c AlwaysReallocate
147    * \sa \c ShrinkToFit
148    * \sa \c DontShrinkToFit
149    * \ingroup ITKCommon
150    * \ingroup DataRepresentation
151    */
152   struct NeverReallocate : AllocateRootPolicy
153     {
operatorNeverReallocate154     bool operator()(unsigned int newSize, unsigned int oldSize) const
155       {
156       (void) newSize;
157       (void) oldSize;
158       itkAssertInDebugAndIgnoreInReleaseMacro(newSize == oldSize && "SetSize is expected to never change the VariableLengthVector size...");
159       return true;
160       }
161     };
162 
163   /** \c VariableLengthVector Allocation Policy: reallocate memory only when
164    * size changes.
165    * This policy, when used from \c VariableLengthVector::SetSize(), will
166    * reallocate the internal buffer only if the size of the \c
167    * VariableLengthVector changes.
168    * \return whether \c newSize differs from \c oldSize
169    *
170    * \note The name is related to \c DontShrinkToFit reallocation policy that
171    * will avoid reallocating when enough memory has already been allocated.
172    *
173    * \sa \c itk::VariableLengthVector::SetSize
174    * \sa \c AlwaysReallocate
175    * \sa \c NeverReallocate
176    * \sa \c DontShrinkToFit
177    * \ingroup ITKCommon
178    * \ingroup DataRepresentation
179    */
180   struct ShrinkToFit : AllocateRootPolicy
181     {
operatorShrinkToFit182     bool operator()(unsigned int newSize, unsigned int oldSize) const
183       { return newSize != oldSize; }
184     };
185 
186   /** \c VariableLengthVector Allocation Policy: reallocate memory only when
187    * size increases.
188    * This policy, when used from \c VariableLengthVector::SetSize(), will
189    * reallocate the internal buffer only if the new size requested for the \c
190    * VariableLengthVector increases.
191    * \return whether \c newSize is bigger than \c oldSize
192    *
193    * \warning Unlike classes like \c std::vector<>, \c VariableLengthVector has
194    * no capacity concept: the size of the \c VariableLengthVector is its
195    * capacity. However, this will help a class without capacity to emulate one.
196    * The consequence is that reallocations will occur with scenarios such as
197    * the following:
198    \code
199    VariableLengthVector<...> v;
200    v.SetSize(42);
201    v.SetSize(12); // no reallocation
202    v.SetSize(42); // pointless reallocation (given this policy)
203    \endcode
204    *
205    * \sa \c itk::VariableLengthVector::SetSize
206    * \sa \c AlwaysReallocate
207    * \sa \c NeverReallocate
208    * \sa \c ShrinkToFit
209    * \ingroup ITKCommon
210    * \ingroup DataRepresentation
211    */
212   struct DontShrinkToFit : AllocateRootPolicy
213     {
operatorDontShrinkToFit214     bool operator()(unsigned int newSize, unsigned int oldSize) const
215       { return newSize > oldSize; }
216     };
217 
218   /** \c VariableLengthVector empty base-class for values Keeping policies.
219    * All Values Keeping Policies are expected to inherit from this empty base
220    * class.
221    *
222    * The preconditions common to all sub classes are:
223    * \pre This policy is only meant to be executed in case of reallocation,
224    * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
225    * \pre This presumes \c TValue assignment is a \c noexcept operation.
226    * \pre \c newBuffer is not null (pre-conditions imposed by some
227    * implementations of \c std::copy())
228    * \pre `[oldBuffer, oldBuffer+oldSize)` is a valid range
229    *
230    * \sa \c itk::VariableLengthVector::SetSize
231    * \sa \c KeepOldValues
232    * \sa \c DumpOldValues
233    * \ingroup ITKCommon
234    * \ingroup DataRepresentation
235    */
236   struct KeepValuesRootPolicy {};
237 
238   /** \c VariableLengthVector Invariability Policy: Always keep old values.
239    * This policy, when used from \c VariableLengthVector::SetSize(), always
240    * copies <tt>min(newSize,oldSize)</tt> previous values from the previous
241    * internal buffer to the new one
242    *
243    * \pre This policy is only meant to be executed in case of reallocation,
244    * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
245    * \pre This presumes \c TValue assignment is a \c noexcept operation.
246    * \pre \c newBuffer is not null (pre-conditions imposed by some
247    * implementations of \c std::copy())
248    * \pre `[oldBuffer, oldBuffer+oldSize)` is a valid range
249    *
250    * This behaviour mimics \c std::vector<>::resize() behaviour. However, it
251    * makes to sense from \c VariableLengthVector::operator=()
252    *
253    * \sa \c itk::VariableLengthVector::SetSize
254    * \sa \c KeepValuesRootPolicy
255    * \sa \c DumpOldValues
256    * \ingroup ITKCommon
257    * \ingroup DataRepresentation
258    */
259   struct KeepOldValues : KeepValuesRootPolicy
260     {
261     template <typename TValue2>
operatorKeepOldValues262       void operator()(
263         unsigned int newSize, unsigned int oldSize,
264         TValue2 * oldBuffer, TValue2 * newBuffer) const
265         {
266         itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer);
267         const std::size_t nb = std::min(newSize, oldSize);
268         itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0  && oldBuffer != nullptr));
269         std::copy(oldBuffer, oldBuffer+nb, newBuffer);
270         }
271     };
272 
273   /** \c VariableLengthVector Invariability Policy: Never keep old values.
274    * This policy, when used from \c VariableLengthVector::SetSize(), is a no-op.
275    * It won't try to copy previous values from the previous internal buffer to
276    * the new one.
277    *
278    * \pre This policy is only meant to be executed in case of reallocation,
279    * i.e. \c oldBuffer and \c newBuffer are expected to differ (unchecked).
280    *
281    * This behaviour particularly fits \c VariableLengthVector::operator=()
282    *
283    * \sa \c itk::VariableLengthVector::SetSize
284    * \sa \c KeepValuesRootPolicy
285    * \sa \c DumpOldValues
286    * \ingroup ITKCommon
287    * \ingroup DataRepresentation
288    */
289   struct DumpOldValues : KeepValuesRootPolicy
290     {
291     template <typename TValue2>
operatorDumpOldValues292       void operator()(
293         unsigned int itkNotUsed(newSize), unsigned int itkNotUsed(oldSize),
294         TValue2 * itkNotUsed(oldBuffer), TValue2 * itkNotUsed(newBuffer)) const
295         {
296         }
297     };
298   //@}
299 
300 
301   /** The element type stored at each location in the Array. */
302   using ValueType = TValue;
303   using ComponentType = TValue;
304   using RealValueType = typename NumericTraits< ValueType >::RealType;
305   using Self = VariableLengthVector;
306 
307   /** Typedef used to indicate the number of elements in the vector */
308   using ElementIdentifier = unsigned int;
309 
310   /** Default constructor. It is created with an empty array
311    *  it has to be allocated later by assignment, \c SetSize() or \c Reserve().
312    * \post \c m_Data is null
313    * \post \c m_NumElements is 0
314    * \post \c m_LetArrayManageMemory is true
315    */
316   VariableLengthVector();
317 
318   /** Constructor with size.
319    * Size can only be changed by assignment, \c SetSize() or \c Reserve().
320    * \post \c m_Data is not null and points to an array of \c m_NumElements,
321    * even if \c m_NumElements is 0
322    * \post values are left uninitialized.
323    * \post \c m_NumElements is \c dimension
324    * \post \c m_LetArrayManageMemory is true
325    */
326   explicit VariableLengthVector(unsigned int dimension);
327 
328   /** Constructor that initializes array with contents from a user supplied
329    * buffer.
330    * The pointer to the buffer and the length is specified. By default, the
331    * array does not manage the memory of the buffer. It merely points to that
332    * location and it is the user's responsibility to delete it.
333    * If \c LetArrayManageMemory is true, then this class will free the
334    * memory when this object is destroyed.
335    *
336    * \post `m_Data == data`
337    * \post values are left unmodified
338    * \post `m_NumElements == sz`
339    * \post `m_LetArrayManageMemory == LetArrayManageMemory`
340    */
341   VariableLengthVector(ValueType *data, unsigned int sz,
342                        bool LetArrayManageMemory = false);
343 
344   /** Constructor that initializes array with contents from a user supplied
345    * buffer.
346    * The pointer to the buffer and the length is specified. By default, the
347    * array does not manage the memory of the buffer. It merely points to that
348    * location and it is the user's responsibility to delete it.
349    * If \c LetArrayManageMemory is true, then this class will free the
350    * memory when this object is destroyed.
351    *
352    * \warning This overload receives a non-modiable array, and yet it will let
353    * the end-user try to modify it through \c VariableLengthVector interface.
354    * Use this constructor with care as this may lead to undefined behaviour.
355    * Prefer using `VariableLengthVector<const TValue>` instead of
356    * `VariableLengthVector<TValue>` in case we which to use this constructor.
357    *
358    * \post `m_Data == data`
359    * \post values are left unmodified
360    * \post `m_NumElements == sz`
361    * \post `m_LetArrayManageMemory == LetArrayManageMemory`
362    */
363   VariableLengthVector(const ValueType *data, unsigned int sz,
364                        bool LetArrayManageMemory = false);
365 
366   /** Copy constructor. The reason why the copy constructor and the assignment
367    * operator are templated is that it will allow implicit casts to be
368    * performed. For instance:
369    \code
370    VariableLengthVector< int > vI;
371    VariableLengthVector< float > vF( vI );
372    or for instance vF = static_cast< VariableLengthVector< float > >( vI );
373    \endcode
374    * \note However that static casting in this way will imply the allocation of
375    * a temporary \c VariableLengthVector. Prefer to directly use the assignment
376    * converting operator in code where uses of \c static_cast<> would be
377    * required.
378    *
379    * \post \c m_Data is not null and points to an array of \c m_NumElements,
380    * if \c m_NumElements is 0, otherwise it's null.
381    * \post values are left uninitialized.
382    * \post \c m_NumElements is \c v.GetSize()
383    * \post \c m_LetArrayManageMemory is true
384    */
385   template< typename T >
VariableLengthVector(const VariableLengthVector<T> & v)386   VariableLengthVector(const VariableLengthVector< T > & v)
387     {
388     m_NumElements = v.Size();
389     m_LetArrayManageMemory = true;
390     if (m_NumElements != 0)
391       {
392       m_Data = this->AllocateElements(m_NumElements);
393       itkAssertInDebugAndIgnoreInReleaseMacro(m_Data != nullptr);
394       for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
395         {
396         this->m_Data[i] = static_cast< ValueType >( v[i] );
397         }
398       }
399     else
400       {
401       m_Data = nullptr;
402       }
403     }
404 
405   /** Copy constructor. Overrides the default non-templated copy constructor
406    * that the compiler provides.
407    * \post \c m_Data is not null and points to an array of \c m_NumElements,
408    * if \c m_NumElements is 0, otherwise it's null.
409    * \post values are left uninitialized.
410    * \post \c m_NumElements is \c v.GetSize()
411    * \post \c m_LetArrayManageMemory is true
412    */
413   VariableLengthVector(const VariableLengthVector< TValue > & v);
414 
415   /** Swaps two \c VariableLengthVector 's.
416    * \pre Expects either none of the \c VariableLengthVector to act as a proxy,
417    * or both, checked with an assertion.
418    * \post \c *this and \c old contents are swapped.
419    * \param[in,out] v  other \c VariableLengthVector to be swapped with.
420    * \throw None
421    * \sa \c itk::swap()
422    */
Swap(Self & v)423   void Swap(Self & v) noexcept
424     {
425     itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
426     using std::swap;
427     swap(v.m_Data       , m_Data);
428     swap(v.m_NumElements, m_NumElements);
429     }
430 
431   /** C++11 Move Constructor.
432    * \post \c v is destructible and assignable.
433    * \post `m_NumElements == 0`
434    * \post `m_LetArrayManageMemory == true`
435    * \post `m_Data == nullptr`
436    * \post Built object contains old \c v data.
437    */
438   VariableLengthVector(Self && v) noexcept;
439 
440   /** C++11 Move assignement operator.
441    * \pre \c v shall not be the same as the current object
442    * \post \c v is destructible and assignable.
443    * \post `m_NumElements == 0`
444    * \post `m_LetArrayManageMemory == true`
445    * \post `m_Data == nullptr`
446    * \post Current object contains old \c v data.
447    */
448   Self & operator=(Self && v) noexcept;
449 
450   /** Constructor from an Expression Template vector.
451    * \tparam TExpr1 Type of the left sub-expression
452    * \tparam TExpr2 Type of the right sub-expression
453    * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
454    * \param[in] rhs Non evaluated Expression Template.
455    *
456    * Builds the new \c VariableLengthVector with an expression template. The
457    * code loops over all components from the template expression, and evaluates
458    * them on the fly to fill the content of the new vector.
459    *
460    * \post \c m_Data is not null and points to an array of \c m_NumElements,
461    * even if \c m_NumElements is 0
462    * \post `*this == rhs`
463    * \post \c m_NumElements is \c rhs.GetSize()
464    * \post \c m_LetArrayManageMemory is true
465    */
466   template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
467       VariableLengthVector(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& rhs);
468   /** Assignment from an Expression Template vector.
469    * \tparam TExpr1 Type of the left sub-expression
470    * \tparam TExpr2 Type of the right sub-expression
471    * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
472    * \param[in] rhs Non evaluated Expression Template.
473    *
474    * Resets the new \c VariableLengthVector with an expression template. The
475    * code loops over all components from the template expression, and evaluates
476    * them on the fly to fill the content of the current vector.
477    *
478    * \post if called on a \c VariableLengthVector proxy, the referenced values
479    * are left unchanged.
480    * \post \c m_Data is not null and points to an array of \c m_NumElements,
481    * if \c m_NumElements is not 0. \c m_Data may be null otherwise (an empty
482    * vector is assigned into another empty vector)
483    * \post \c m_LetArrayManageMemory is true
484    * \post `GetSize() == rhs.GetSize()`
485    * \post `*this == rhs`
486    */
487   template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
488   Self & operator=(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& rhs);
489 
490   /** Set the all the elements of the array to the specified value.
491    * \pre This function may be called on empty vectors, it's a no-op.
492    */
493   void Fill(TValue const & v);
494 
495   /** Converting assignment operator.
496    * \note Ensures a <em>String Exception Guarantee</em>: resists to
497    * self-assignment, and no changes are made if memory cannot be allocated to
498    * hold the new elements. This presumes \c TValue assignment is a \c
499    * noexcept operation.
500    *
501    * \post if called on a \c VariableLengthVector proxy, the referenced values
502    * are left unchanged.
503    * \post \c m_LetArrayManageMemory is true
504    * \post <tt>GetSize() == v.GetSize()</tt>, modulo precision
505    * \post <tt>*this == v</tt>
506    */
507   template< typename T >
508   Self & operator=(const VariableLengthVector< T > & v)
509     {
510     // No self assignment test is done. Indeed:
511     // - the operator already resists self assignment through a strong exception
512     // guarantee
513     // - the test becomes a pessimization as we never write
514     //    VLV<const TValue> vcref(v.GetDataPointer(), v.GetSize());
515     //    ...;
516     //    v = vcref;
517     ElementIdentifier const N = v.Size();
518     this->SetSize( N, DontShrinkToFit(), DumpOldValues() );
519     for ( ElementIdentifier i = 0; i < N; ++i )
520       {
521       this->m_Data[i] = static_cast< ValueType >( v[i] );
522       }
523     return *this;
524   }
525 
526   /** Copy-Assignment operator.
527    * \note Ensures a <em>String Exception Guarantee</em>: resists to
528    * self-assignment, and no changes are made if memory cannot be allocated to
529    * hold the new elements. This is expecting \c TValue assignment is a \c
530    * noexcept operation.
531    *
532    * \post if called on a \c VariableLengthVector proxy, the referenced values
533    * are left unchanged.
534    * \post \c m_Data is not null and points to an array of \c m_NumElements,
535    * if \c m_NumElements is not 0. \c m_Data may be null otherwise (an empty
536    * vector is assigned into another empty vector)
537    * \post \c m_LetArrayManageMemory is true
538    * \post <tt>GetSize() == v.GetSize()</tt>
539    * \post <tt>*this == v</tt>
540    */
541   Self & operator=(const Self & v);
542 
543   /** Fast Assignment.
544    * \pre \c m_LetArrayManageMemory is true: the \c VariableLengthVector is not
545    * a proxy, checked with an assertion. Call <tt>SetSize(GetSize(), NeverReallocate(),
546    * DumpOldValues())</tt> to ensure a vector is not a proxy anymore.
547    * \pre current size is identical to the one from the right hand side
548    * operand, checked with an assertion.
549    * \pre Doesn't not support empty vectors.
550    */
551   Self & FastAssign(const Self & v);
552 
553   /** Assignment operator from a numeric value.
554    * \pre This assumes \c m_LetArrayManageMemory is true, but it is unchecked.
555    * If this operator is called on a \c VariableLengthVector proxy, referenced
556    * values will be overwritten.
557    * \post Elements in `[m_Data, m_Data+GetSize())` will be equal to \c v, modulo
558    * precision
559    */
560   Self & operator=(TValue const & v);
561 
562   /** Return the number of elements in the Array  */
Size()563   unsigned int Size() const { return m_NumElements; }
GetSize()564   unsigned int GetSize() const { return m_NumElements; }
GetNumberOfElements()565   unsigned int GetNumberOfElements() const { return m_NumElements; }
566 
567   /** Return reference to the element at specified index. No range checking. */
568   TValue       & operator[](unsigned int i) { return this->m_Data[i]; }
569   /** Return reference to the element at specified index. No range checking. */
570   TValue const & operator[](unsigned int i) const { return this->m_Data[i]; }
571 
572   /** Get one element */
GetElement(unsigned int i)573   const TValue & GetElement(unsigned int i) const { return m_Data[i]; }
574 
575   /** Set one element */
SetElement(unsigned int i,const TValue & value)576   void SetElement(unsigned int i, const TValue & value) { m_Data[i] = value; }
577 
578   /** Resizes the vector.
579    * \tparam TReallocatePolicy Policy that determines precisely the conditions
580    * under which the internal buffer shall be reallocated. It shall inherit
581    * from \c AllocateRootPolicy.
582    * \tparam TKeepValuesPolicy Policy that determines whether old elements
583    * shall be kept. It shall inherit from \c KeepValuesRootPolicy.
584    *
585    * \internal
586    * The purpose of this overload is to fine tune what \c SetSize() does. Some
587    * users seem to need to always reallocate, or to maintain old elements.
588    * However, some usages require fast resizing. In the assignment operators
589    * cases, we don't need to reallocate anything if we have enough memory, and
590    * we certainly do not need to maintain previous values as they'll get
591    * overridden with new ones.
592    * \internal
593    * If we could assert that \c VariableLengthVector proxies would (shall!)
594    * never be assigned anything, we could benefit from a version that won't
595    * check \c m_LetArrayManageMemory.
596    *
597    * \pre `m_NumElements == sz` if \c TReallocatePolicy is \c NeverReallocate
598    * \post `m_NumElements == sz`
599    * \post \c m_LetArrayManageMemory is true
600    * \post In case of reallocation, old \c m_Data buffer is deleted.
601    * \post If \c TKeepValuesPolicy is \c KeepOldValues, old values are
602    * garanteed to be kept, otherwise, it'll depend on the reallocation policy
603    * and the old and new vector size.
604    * \sa \c AlwaysReallocate
605    * \sa \c NeverReallocate
606    * \sa \c ShrinkToFit
607    * \sa \c DontShrinkToFit
608    * \sa \c KeepOldValues
609    * \sa \c DumpOldValues
610    */
611   template <typename TReallocatePolicy, typename TKeepValuesPolicy>
612   void SetSize(unsigned int sz,
613           TReallocatePolicy reallocatePolicy,
614           TKeepValuesPolicy keepValues);
615 
616   /** Set the size to that given.
617    *
618    * If \c destroyExistingData is \c false:
619    * If the array already contains data, the existing data is copied over and
620    * new space is allocated, if necessary. If the length to reserve is less
621    * than the current number of elements, then an appropriate number of elements
622    * are discarded.
623    *    If \c true, the size is set destructively to the length given. If the
624    * length is different from the current length, existing data will be lost.
625    * The default is \c true. */
626   void SetSize(unsigned int sz, bool destroyExistingData = true)
627     {
628     // Stays compatible with previous code version
629     // And works around the fact C++03 template functions can't have default
630     // arguments on template types.
631     if (destroyExistingData)
632       {
633       SetSize(sz, AlwaysReallocate(), KeepOldValues());
634       }
635     else
636       {
637       SetSize(sz, ShrinkToFit(), KeepOldValues());
638       }
639     }
640 
641   /** Destroy data that is allocated internally, if \c LetArrayManageMemory is
642    * true. */
643   void DestroyExistingData();
644 
645   /** Set the pointer from which the data is imported.
646    * If "LetArrayManageMemory" is false, then the application retains
647    * the responsibility of freeing the memory for this data.  If
648    * "LetArrayManageMemory" is true, then this class will free the
649    * memory when this object is destroyed.
650    * \warning The size of the new \c data shall match vector current size.
651    * Prefer the other overload.
652    * \post old \c m_Data is deleted iff \c m_LetArrayManageMemory is true
653    * \post `m_Data == data`
654    * \post `m_LetArrayManageMemory ==LetArrayManageMemory`
655    * \post \c Size() is left unmodified.
656    */
657   void SetData(TValue *data, bool LetArrayManageMemory = false);
658 
659   /** Similar to the previous method. In the above method, the size must be
660    * separately set prior to using user-supplied data. This introduces an
661    * unnecessary allocation step to be performed. This method avoids it
662    * and should be used to import data wherever possible to avoid this.
663    * Set the pointer from which the data is imported.
664    * If "LetArrayManageMemory" is false, then the application retains
665    * the responsibility of freeing the memory for this data.  If
666    * "LetArrayManageMemory" is true, then this class will free the
667    * memory when this object is destroyed.
668    * \post old \c m_Data is deleted iff \c m_LetArrayManageMemory is true
669    * \post `m_Data == data`
670    * \post `m_LetArrayManageMemory ==LetArrayManageMemory`
671    * \post `m_NumElements == sz`
672    */
673   void SetData(TValue *data, unsigned int sz, bool LetArrayManageMemory = false);
674 
675   /** This destructor is not virtual for performance reasons. However, this
676    * means that subclasses cannot allocate memory.
677    *
678    * \internal
679    * More precisally, this class has value semantics (copiable, assignable,
680    * comparable). It's hardly compatible with public inheritance: slicing would
681    * always be there somewhere to annoy us if we try to inherit publicaly from
682    * such a class.
683    * As a consequence, having the destructor virtual makes hardly any sense.
684    */
685   ~VariableLengthVector();
686 
687   /** Reserves memory of a certain length.
688    *
689    * If the array already contains data, the existing data is copied over and
690    * new space is allocated, if necessary. If the length to reserve is less
691    * than the current number of elements, then an appropriate number of elements
692    * are discarded.
693    * \post \c m_Data is not null and can hold \c size elements.
694    * \post \c m_LetArrayManageMemory may be left unchanged if there already are
695    * enough elements.
696    *
697    * \note You may prefer instead
698    * `SetSize(N, DontShrinkToFit(), KeepOldValues());` that ensures that the
699    * array is not a proxy at the end of the operation.
700    */
701   void Reserve(ElementIdentifier size);
702 
703   /** Allocate memory of certain size and return it.
704    * \return a non-null pointer to an array of \c size elements (0 is a valid
705    * parameter).
706    */
707   TValue * AllocateElements(ElementIdentifier size) const;
708 
GetDataPointer()709   const TValue * GetDataPointer() const { return m_Data; }
710 
711   /** Prefix operator that subtracts 1 from each element of the
712    * vector. */
713   Self & operator--()
714     {
715     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
716       {
717       this->m_Data[i] -= static_cast< ValueType >( 1.0 );
718       }
719     return *this;
720     }
721 
722   /** Prefix operator that adds 1 to each element of the vector. */
723   Self & operator++() // prefix operator ++v;
724     {
725     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
726       {
727       this->m_Data[i] += static_cast< ValueType >( 1.0 );
728       }
729     return *this;
730     }
731 
732   /** Postfix operator that subtracts 1 from each element of the
733    * vector. */
734   Self operator--(int) // postfix operator v--;
735     {
736     Self tmp(*this);
737 
738     --tmp;
739     return tmp;
740     }
741 
742   /** Postfix operator that adds 1 to each element of the vector. */
743   Self operator++(int) // postfix operator v++;
744     {
745     Self tmp(*this);
746 
747     ++tmp;
748     return tmp;
749     }
750 
751   /** Element-wise subtraction of vector 'v' from the current
752    * vector. The vectors do not have to have the same element
753    * type. The input vector elements are cast to the current vector
754    * element type before the subtraction is performed.
755    *
756    * \throw None
757    * \note For efficiency, the length of the vectors is not checked;
758    * they are assumed to have the same length. */
759   template< typename T >
760   Self & operator-=
761     (const VariableLengthVector< T > & v)
762     {
763     itkAssertInDebugAndIgnoreInReleaseMacro( m_NumElements == v.GetSize() );
764     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
765       {
766       m_Data[i] -= static_cast< ValueType >( v[i] );
767       }
768     return *this;
769     }
770 
771   /** Subtract scalar 's' from each element of the current vector. */
772   Self & operator-=(TValue s)
773     {
774     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
775       {
776       m_Data[i] -= s;
777       }
778     return *this;
779     }
780 
781   /** Element-wise addition of vector 'v' to the current vector. The
782    * vectors do not have to have the same element type. The input
783    * vector elements are cast to the current vector element type
784    * before the addition is performed.
785    *
786    * \throw None
787    * \note For efficiency, the length of the vectors is not checked;
788    * they are assumed to have the same length. */
789   template< typename T >
790   Self & operator+=
791     (const VariableLengthVector< T > & v)
792     {
793     itkAssertInDebugAndIgnoreInReleaseMacro( m_NumElements == v.GetSize() );
794     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
795       {
796       m_Data[i] += static_cast< ValueType >( v[i] );
797       }
798     return *this;
799     }
800 
801   /** Add scalar 's' to each element of the vector. */
802   Self & operator+=(TValue s)
803     {
804     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
805       {
806       m_Data[i] += s;
807       }
808     return *this;
809     }
810 
811   /** Compound addition operator with a expression template vector.
812    * \tparam TExpr1 Type of the left sub-expression
813    * \tparam TExpr2 Type of the right sub-expression
814    * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
815    * \param[in] rhs Non evaluated Expression Template.
816    *
817    * \pre `Size() == rhs.Size()`, checked with an assertion
818    * \note The elements of the expression template are evaluated one by one.
819    */
820   template <typename TExpr1, typename TExpr2, typename TBinaryOp>
821   Self& operator+=(VariableLengthVectorExpression<TExpr1,TExpr2,TBinaryOp> const& rhs)
822     {
823     itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
824     for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
825       {
826       m_Data[i] += static_cast<ValueType>(rhs[i]);
827       }
828     return *this;
829     }
830 
831   /** Compound subtraction operator with a expression template vector.
832    * \tparam TExpr1 Type of the left sub-expression
833    * \tparam TExpr2 Type of the right sub-expression
834    * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
835    * \param[in] rhs Non evaluated Expression Template.
836    *
837    * \pre `Size() == rhs.Size()`, checked with an assertion
838    * \note The elements of the expression template are evaluated one by one.
839    */
840   template <typename TExpr1, typename TExpr2, typename TBinaryOp>
841   Self& operator-=(VariableLengthVectorExpression<TExpr1,TExpr2,TBinaryOp> const& rhs)
842     {
843     itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
844     for ( ElementIdentifier i = 0; i < m_NumElements; ++i )
845       {
846       m_Data[i] -= static_cast<ValueType>(rhs[i]);
847       }
848     return *this;
849     }
850 
851   /** Multiply each element of the vector by a scalar 's'. The scalar
852    * value is cast to the current vector element type prior to
853    * multiplication.
854    * \throw None
855    */
856   template< typename T >
857   Self & operator*=(T s)
858     {
859     const ValueType & sc = static_cast<ValueType>(s);
860     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
861       {
862       m_Data[i] *= sc;
863       }
864     return *this;
865     }
866 
867   /** Multiply each element of the vector by a scalar 's'.
868    * \throw None
869    */
870   Self & operator*=(TValue s)
871     {
872     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
873       {
874       m_Data[i] *= s;
875       }
876     return *this;
877     }
878 
879   /** Divide vector elements by a scalar 's'. The vector does not
880    * have to have the same element type as the scalar type. Both the
881    * scalar and vector elements are cast to the RealValueType prior to
882    * division, and the result is cast to the ValueType.
883    * \throw None
884    */
885   template< typename T >
886   Self & operator/=(T s)
887     {
888     const RealValueType sc = s;
889     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
890       {
891       m_Data[i] = static_cast< ValueType >(
892         static_cast< RealValueType >( m_Data[i] )
893         / sc );
894       }
895     return *this;
896     }
897 
898   /** Negates each vector element.
899    * \warning This operator has a non standard semantics. Instead of returning
900    * a new \c VariableLengthVector, it modifies the current object.
901    */
902   Self & operator-();  // negation operator
903 
904   bool operator==(const Self & v) const;
905 
906   bool operator!=(const Self & v) const;
907 
908   /** Returns vector's Euclidean Norm  */
909   RealValueType GetNorm() const;
910 
911   /** Returns vector's squared Euclidean Norm  */
912   RealValueType GetSquaredNorm() const;
913 
914   /** letArrayManageMemory getter. */
IsAProxy()915   bool IsAProxy() const { return ! m_LetArrayManageMemory;}
916 
917 private:
918   bool              m_LetArrayManageMemory{true}; // if true, the array is responsible
919                                             // for memory of data
920   TValue *          m_Data;                 // Array to hold data
921   ElementIdentifier m_NumElements{0};
922 };
923 
924 /// \cond HIDE_META_PROGRAMMING
925 namespace mpl {
926 /** Tells whether a type is an array type for which the support of arithmetic
927  * operations is done with Expression Template.
928  * \note For the moment, only \c itk::VariableLengthVector<> is supported. It
929  * could be extented to other types of ITK arrays.
930  * \ingroup MetaProgrammingLibrary
931  * \ingroup ITKCommon
932  * \sa \c VariableLengthVector
933  * \sa \c VariableLengthVectorExpression
934  */
935 template <typename T>
936 struct IsArray : FalseType {};
937 
938 /// \cond SPECIALIZATION_IMPLEMENTATION
939 template <typename T>
940 struct IsArray<itk::VariableLengthVector<T> > : TrueType {};
941 
942 template <typename TExpr1, typename TExpr2, typename TBinaryOp>
943 struct IsArray<VariableLengthVectorExpression<TExpr1, TExpr2,TBinaryOp> > : TrueType {};
944 /// \endcond
945 } // namespace mpl
946 /// \endcond
947 
948 namespace Details
949 {
950 /// \cond HIDE_META_PROGRAMMING
951 /** Helper Trait for VLV expression template: returns the value type.
952  * \tparam TExpr Expression type
953  * \return \c Type The value type behind \c TExpr (\c TExpr in case of a
954  * numerical type, \c TExpr::ValueType in case of the \c VariableLengthVector,
955  * etc.)
956  *
957  * Also defines \c Load() that permits to fetch the i-th element in case of an
958  * array, array expression, or just the number in case of a number.
959  * \ingroup ITKCommon
960  * \sa \c VariableLengthVector
961  * \sa \c VariableLengthVectorExpression
962  */
963 template <typename TExpr> struct GetType
964   {
965   using Type = TExpr;
966   /** Fetches the i-th element from an array (expression).
967    * \note the default unspecialized behaviour returns the input number \c v.
968    */
969   static Type Load(Type const& v, unsigned int idx)
970     { (void)idx; return v; }
971   };
972 
973 /** Helper function for VLV expression templates: returns the common size.
974  * \param[in] lhs left hand side expression
975  * \param[in] rhs right hand side expression
976  * \note The default overload assumes both operands are \c VariableLengthVector
977  * (or expression) arrays
978  * \pre asserts both arrays have the same size.
979  * \ingroup ITKCommon
980  * \sa \c VariableLengthVector
981  * \sa \c VariableLengthVectorExpression
982  */
983 template <typename TExpr1, typename TExpr2>
984 inline
985 typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2> >, unsigned int>::Type
986 GetSize(TExpr1 const& lhs, TExpr2 const& rhs)
987   {
988   (void)rhs;
989   itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
990   return lhs.Size();
991   }
992 
993 /// \cond SPECIALIZATION_IMPLEMENTATION
994 /** Helper function for VLV expression templates: returns the common size.
995  * \param[in] lhs left hand side expression
996  * \param[in] rhs right hand side expression
997  * \note This overload assumes that only the first operand is a \c
998  * VariableLengthVector (or expression) array.
999  * \ingroup ITKCommon
1000  * \sa \c VariableLengthVector
1001  * \sa \c VariableLengthVectorExpression
1002  */
1003 template <typename TExpr1, typename TExpr2>
1004 inline
1005 typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2> > >, unsigned int>::Type
1006 GetSize(TExpr1 const& lhs, TExpr2 const& itkNotUsed(rhs))
1007   {
1008   return lhs.Size();
1009   }
1010 
1011 /** Helper function for VLV expression templates: returns the common size.
1012  * \param[in] lhs left hand side expression
1013  * \param[in] rhs right hand side expression
1014  * \note This overload assumes that only the second operand is a \c
1015  * VariableLengthVector (or expression) array.
1016  * \ingroup ITKCommon
1017  * \sa \c VariableLengthVector
1018  * \sa \c VariableLengthVectorExpression
1019  */
1020 template <typename TExpr1, typename TExpr2>
1021 inline
1022 typename mpl::EnableIf<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1> > >, unsigned int>::Type
1023 GetSize(TExpr1 const& itkNotUsed(lhs), TExpr2 const& rhs)
1024   {
1025   return rhs.Size();
1026   }
1027 
1028 template <typename T>
1029 struct GetType<VariableLengthVector<T> >
1030   {
1031   using Type = T;
1032   static Type Load(VariableLengthVector<T> const& v, unsigned int idx)
1033     { return v[idx]; }
1034   };
1035 template <typename TExpr1, typename TExpr2, typename TBinaryOp>
1036 struct GetType<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> >
1037   {
1038   using Type = typename VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>::ResType;
1039   static Type Load(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& v, unsigned int idx)
1040     { return v[idx]; }
1041   };
1042 /// \endcond
1043 
1044 namespace op
1045 {
1046 /** Tells whether objects from two types can be added or subtracted.
1047  * The operation is authorized if and only if:
1048  * - both are arrays,
1049  * - or one operand is an array while the second is a number.
1050  * \note As this traits is dedicated to help overload binary operators, it
1051  * shall not be used to help overload `operator+()` between floats for instance.
1052  * Hence, the case where both operands are numbers is rejected.
1053  *
1054  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1055  * \ingroup MetaProgrammingLibrary
1056  * \ingroup ITKCommon
1057  */
1058 template <typename TExpr1, typename TExpr2>
1059 struct CanBeAddedOrSubtracted
1060 : mpl::Or< mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2> >,
1061             mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >,
1062             mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2> >
1063   >
1064 {};
1065 
1066 /** Tells whether objects from two types can be multiplied.
1067  * The operation is authorized if and only if:
1068  * - one operand is an array while the second is a number.
1069  * \note As this traits is dedicated to help overload `operator*()`, it
1070  * shall not be used to help overload the operator between floats for instance.
1071  * Hence, the case where both operands are numbers is rejected.
1072  *
1073  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1074  * \ingroup MetaProgrammingLibrary
1075  * \ingroup ITKCommon
1076  */
1077 template <typename TExpr1, typename TExpr2>
1078 struct CanBeMultiplied
1079 : mpl::Or< mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >,
1080             mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2> >
1081   >
1082 {};
1083 
1084 /** Tells whether objects from two types can be multiplied.
1085  * The operation is authorized if and only if:
1086  * - the first operand is an array while the second is a number.
1087  * \note As this traits is dedicated to help overload `operator/()`, it
1088  * shall not be used to help overload the operator between floats for instance.
1089  * Hence, the case where both operands are numbers is rejected.
1090  *
1091  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1092  * \ingroup MetaProgrammingLibrary
1093  * \ingroup ITKCommon
1094  */
1095 template <typename TExpr1, typename TExpr2>
1096 struct CanBeDivided
1097 : mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2> >
1098 {};
1099 
1100 } // op namespace
1101 } // Details namespace
1102 /// \endcond
1103 
1104 /** Expression Template for \c VariableLengthVector.
1105  * Contains an expression template that models a binary operation between two
1106  * sub expressions (of type \c VariableLengthVector, or \c VariableLengthVectorExpression)
1107  * \tparam TExpr1 Type of the left sub-expression
1108  * \tparam TExpr2 Type of the right sub-expression
1109  * \tparam TBinaryOp Binary Operation to apply to both sub-expressions.
1110  *
1111  * \note We permit to add a `VariableLengthVector<float>` with a
1112  * `VariableLengthVector<double>`, the result will be of type
1113  * `VariableLengthVector<double>`.
1114  *
1115  * \warning Explicitly static casting an expression to a
1116  * \c VariableLengthVector<> will defeat the purpose of the optimization
1117  * implemented here. It's thus best to let the expression automatically adjust
1118  * to the type with the most precision.
1119  * Eventually, when assigning to the final destination (a
1120  * \c VariableLengthVector<>), a casting on-the-fly could be realized by the
1121  * assignment operator, or by the copy constructor.
1122  *
1123  * \todo Add support for unary operations like `operator-()`.
1124  *
1125  * \ingroup DataRepresentation
1126  * \ingroup ITKCommon
1127  */
1128 template <typename TExpr1, typename TExpr2, typename TBinaryOp>
1129 struct VariableLengthVectorExpression
1130 {
1131   VariableLengthVectorExpression(TExpr1 const& lhs, TExpr2 const& rhs)
1132     : m_lhs(lhs), m_rhs(rhs)
1133     {
1134     // Not neccessary actually as end-user/developper is not expected to
1135     // provide new BinaryOperations
1136     itkStaticAssert(
1137       (itk::mpl::IsBaseOf<Details::op::BinaryOperationConcept, TBinaryOp>::Value),
1138       "The Binary Operation shall inherit from BinaryOperationConcept");
1139     }
1140 
1141   /// Returns the size of the vector expression.
1142   unsigned int Size() const{ return Details::GetSize(m_lhs, m_rhs); }
1143 
1144   /// Vector type of the Result Expression
1145   using ResType = typename mpl::PromoteType<
1146     typename Details::GetType<TExpr1>::Type,
1147     typename Details::GetType<TExpr2>::Type>::Type;
1148   /// Real type of the elements
1149   using RealValueType = typename NumericTraits< ResType > ::RealType;
1150 
1151   /** Element access operator.
1152    * \pre `idx < Size()`
1153    * \internal
1154    * This is where the magic happens. Instead of building a new vector based on
1155    * the two input vectors, we compute each element on-the-fly when
1156    * requested(by a \c VariableLengthVector constructor or an assignment
1157    * operator).
1158    *
1159    * \c Load() is in charge of fetching the i-th element of the sub-expressions
1160    */
1161   ResType operator[](unsigned int idx) const
1162     {
1163     itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
1164     return TBinaryOp::Apply(
1165       Details::GetType<TExpr1>::Load(m_lhs, idx),
1166       Details::GetType<TExpr2>::Load(m_rhs, idx));
1167     }
1168 
1169   /** Returns vector's Euclidean Norm  */
1170   RealValueType GetNorm() const;
1171 
1172   /** Returns vector's squared Euclidean Norm  */
1173   RealValueType GetSquaredNorm() const;
1174 
1175 private:
1176   TExpr1 const& m_lhs;
1177   TExpr2 const& m_rhs;
1178 };
1179 
1180 /** Addition involving a \c VariableLengthVector.
1181  * This operation is generic and takes:
1182  * - two arrays,
1183  * - or one array and one number (on either side)
1184  * \return an expression template proxy object.
1185  * \throw None As no allocation will be performed.
1186  * \relates itk::VariableLengthVector
1187  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1188  */
1189 template <typename TExpr1, typename TExpr2>
1190 inline
1191 typename mpl::EnableIf<Details::op::CanBeAddedOrSubtracted<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus> >::Type
1192 operator+(TExpr1 const& lhs, TExpr2 const& rhs)
1193 { return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>(lhs, rhs); }
1194 
1195 /** Subtraction involving a \c VariableLengthVector.
1196  * This operation is generic and takes:
1197  * - two arrays,
1198  * - or one array and one number (on either side)
1199  * \return an expression template proxy object.
1200  * \throw None As no allocation will be performed.
1201  * \relates itk::VariableLengthVector
1202  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1203  */
1204 template <typename TExpr1, typename TExpr2>
1205 inline
1206 typename mpl::EnableIf<Details::op::CanBeAddedOrSubtracted<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub> >::Type
1207 operator-(TExpr1 const& lhs, TExpr2 const& rhs)
1208 { return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>(lhs, rhs); }
1209 
1210 /** Multiplication between a \c VariableLengthVector and a scalar.
1211  * This operation is generic and takes one array and one number (on either
1212  * side).
1213  * \return an expression template proxy object.
1214  * \throw None As no allocation will be performed.
1215  * \relates itk::VariableLengthVector
1216  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1217  */
1218 template <typename TExpr1, typename TExpr2>
1219 inline
1220 typename mpl::EnableIf<Details::op::CanBeMultiplied<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult> >::Type
1221 operator*(TExpr1 const& lhs, TExpr2 const& rhs)
1222 { return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>(lhs, rhs); }
1223 
1224 /** Division of a \c VariableLengthVector by a scalar.
1225  * This operation is generic and takes one array and one number.
1226  * \return an expression template proxy object.
1227  * \throw None As no allocation will be performed.
1228  * \relates itk::VariableLengthVector
1229  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1230  */
1231 template <typename TExpr1, typename TExpr2>
1232 inline
1233 typename mpl::EnableIf<Details::op::CanBeDivided<TExpr1,TExpr2>, VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div> >::Type
1234 operator/(TExpr1 const& lhs, TExpr2 const& rhs)
1235 { return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>(lhs, rhs); }
1236 
1237 /** Serialization of \c VariableLengthVectorExpression
1238  * \relates itk::VariableLengthVectorExpression
1239  */
1240 template <typename TExpr1, typename TExpr2, typename  TBinaryOp>
1241 std::ostream & operator<<(std::ostream &os, VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> const& v)
1242 {
1243   os << "[";
1244   if (v.Size() != 0)
1245     {
1246     os << v[0];
1247     for (unsigned int i = 1, N = v.Size(); i != N; ++i)
1248       {
1249       os << ", " << v[i];
1250       }
1251     }
1252   return os << "]";
1253 }
1254 
1255 /** Returns vector's Euclidean Norm.
1256  * \tparam TExpr must be an array
1257  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1258  * \relates itk::VariableLengthVectorExpression
1259  */
1260 template <typename TExpr>
1261 inline
1262 typename mpl::EnableIf<mpl::IsArray<TExpr>, typename TExpr::RealValueType>::Type
1263 GetNorm(TExpr const& v)
1264 {
1265   return static_cast<typename TExpr::RealValueType>(
1266     std::sqrt(static_cast<double>(GetSquaredNorm(v))));
1267 }
1268 
1269 /** Returns vector's squared Euclidean Norm.
1270  * \tparam TExpr must be an array
1271  * \sa \c mpl::IsArray<> to know the exact array types recognized as \em array by this traits
1272  * \relates itk::VariableLengthVectorExpression
1273  */
1274 template <typename TExpr>
1275 inline
1276 typename mpl::EnableIf<mpl::IsArray<TExpr>, typename TExpr::RealValueType>::Type
1277 GetSquaredNorm(TExpr const& v)
1278 {
1279   using RealValueType = typename TExpr::RealValueType;
1280   RealValueType sum = 0.0;
1281   for ( unsigned int i = 0, N=v.Size(); i < N; ++i )
1282     {
1283     const RealValueType value = v[i];
1284     sum += value * value;
1285     }
1286   return sum;
1287 }
1288 
1289 /**\name Serialization */
1290 //@{
1291 /** Serialization of \c VariableLengthVector
1292  * \relates itk::VariableLengthVector
1293  */
1294 template< typename TValue >
1295 std::ostream & operator<<(std::ostream & os, const VariableLengthVector< TValue > & arr)
1296 {
1297   const unsigned int length = arr.Size();
1298   const signed int   last   = (unsigned int)length - 1;
1299 
1300   os << "[";
1301   for ( signed int i = 0; i < last; ++i )
1302     {
1303     os << arr[i] << ", ";
1304     }
1305   if ( length >= 1 )
1306     {
1307     os << arr[last];
1308     }
1309   os << "]";
1310   return os;
1311 }
1312 //@}
1313 
1314 /**\name Standard compliance functions */
1315 //@{
1316 /** \c swap() overload for \c VariableLengthVector
1317  * \throw None
1318  * \relates itk::VariableLengthVector
1319  * \internal
1320  * This overload follows C++ standard naming convention. This is required to
1321  * permit \c VariableLengthVector to be exchanged by standard algorithms that
1322  * take advantage of Koening Namespace Lookup (a.k.a. Argument Dependant
1323  * Lookup). e.g.
1324  \code
1325  template <typename T> f(T & l, T & r)
1326  {
1327      using std::swap;
1328      swap(l,r);
1329      ...
1330  }
1331  * \endcode
1332  */
1333 template <typename T>
1334 inline
1335 void swap(VariableLengthVector<T> &l_, VariableLengthVector<T> &r_) noexcept
1336 {
1337   l_.Swap(r_);
1338 }
1339 //@}
1340 
1341 } // namespace itk
1342 
1343 #include "itkNumericTraitsVariableLengthVectorPixel.h"
1344 
1345 #ifndef ITK_MANUAL_INSTANTIATION
1346 #include "itkVariableLengthVector.hxx"
1347 #endif
1348 
1349 #endif
1350