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 itkValarrayImageContainer_h
19 #define itkValarrayImageContainer_h
20 
21 #include "itkObject.h"
22 #include "itkObjectFactory.h"
23 
24 #include <utility>
25 #include <valarray>
26 
27 namespace itk
28 {
29 /** \class ValarrayImageContainer
30  *  \brief Defines a front-end to the std\\::\<valarray\> container that conforms to the
31  *         ImageContainerInterface.
32  *
33  * This is a full-fleged Object, so
34  * there is modification time, debug, and reference count information.
35  *
36  * \tparam TElementIdentifier
37  *    An INTEGRAL type for use in indexing the valarray.
38  *    It must have a \< operator defined for ordering.
39  *
40  * \tparam TElement
41  *    The element type stored in the container.
42  *
43  * \ingroup ImageObjects
44  * \ingroup DataRepresentation
45  * \ingroup ITKCommon
46  */
47 template<
48   typename TElementIdentifier,
49   typename TElement
50   >
51 class ITK_TEMPLATE_EXPORT ValarrayImageContainer:
52   public Object,
53   private std::valarray< TElement >
54 {
55 public:
56   /** Standard class type aliases. */
57   using Self = ValarrayImageContainer;
58   using Superclass = Object;
59   using Pointer = SmartPointer< Self >;
60   using ConstPointer = SmartPointer< const Self >;
61 
62   /** Save the template parameters. */
63   using ElementIdentifier = TElementIdentifier;
64   using Element = TElement;
65 
66 private:
67   /** Quick access to the STL valarray type that was inherited. */
68   using ValarrayType = std::valarray< Element >;
69 
70 protected:
71   /** Provide pass-through constructors corresponding to all the STL
72    * valarray constructors.  These are for internal use only since
73    * this is also an Object which must be constructed through the
74    * "New()" routine. */
ValarrayImageContainer()75   ValarrayImageContainer():
76     ValarrayType() {}
ValarrayImageContainer(unsigned long n)77   ValarrayImageContainer(unsigned long n):
78     ValarrayType(n) {}
ValarrayImageContainer(unsigned long n,const Element & x)79   ValarrayImageContainer(unsigned long n, const Element & x):
80     ValarrayType(n, x) {}
ValarrayImageContainer(const Self & r)81   ValarrayImageContainer(const Self & r):
82     ValarrayType(r) {}
83 
84 public:
85   /** Method for creation through the object factory. */
86   itkNewMacro(Self);
87 
88   /** Standard part of every itk Object. */
89   itkTypeMacro(ValarrayImageContainer, Object);
90 
91   /** Index operator. This version can be an lvalue. */
92   TElement & operator[](const ElementIdentifier id)
93   { return this->ValarrayType::operator[](id); }
94 
95   /** Index operator. This version can only be an rvalue */
96   const TElement & operator[](const ElementIdentifier id) const
97   { return this->ValarrayType::operator[](id); }
98 
99   /** Return a pointer to the beginning of the buffer.  This is used by
100    * the image iterator class. */
GetBufferPointer()101   TElement * GetBufferPointer()
102   {
103     if ( this->Size() > 0 )
104       {
105       return & ( this->ValarrayType::operator[](0) );
106       }
107     else
108       {
109       return nullptr;
110       }
111   }
112 
113   /** Get the number of elements currently stored in the container. */
Size()114   unsigned long Size() const
115   { return static_cast< unsigned long >( this->ValarrayType::size() ); }
116 
117   /** Tell the container to allocate enough memory to allow at least
118    * as many elements as the size given to be stored.  This is NOT
119    * guaranteed to actually allocate any memory, but is useful if the
120    * implementation of the container allocates contiguous storage. */
Reserve(ElementIdentifier num)121   void Reserve(ElementIdentifier num)
122   { this->ValarrayType::resize(num); }
123 
124   /** Tell the container to try to minimize its memory usage for storage of
125    * the current number of elements.  This is NOT guaranteed to decrease
126    * memory usage. */
Squeeze()127   void Squeeze()
128   { this->ValarrayType::resize( this->ValarrayType::size() ); }
129 
130   /** Tell the container to release any of its allocated memory. */
Initialize()131   void Initialize()
132   { this->ValarrayType::resize(0); }
133 
134   /** Tell the container to release any of its allocated memory. */
Fill(const TElement & value)135   void Fill(const TElement & value)
136   { this->ValarrayType::operator=(value); }
137 
138 public:
139   /** PrintSelf routine. Normally this is a protected internal method. It is
140    * made public here so that Image can call this method.  Users should not
141    * call this method but should call Print() instead.  */
PrintSelf(std::ostream & os,Indent indent)142   void PrintSelf(std::ostream & os, Indent indent) const override
143   {
144     Object::PrintSelf(os, indent);
145     // Print out the pointer to bulk data memory. We use const_cast<> to
146     // cast away the constness so we can call GetBufferPointer()
147     os << indent << "Pointer: "
148        << const_cast< ValarrayImageContainer * >( this )->GetBufferPointer()
149        << std::endl;
150 
151     os << indent << "Size: " << this->Size() << std::endl;
152   }
153 };
154 } // end namespace itk
155 
156 #endif
157