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 itkMapContainer_h 19 #define itkMapContainer_h 20 21 #include "itkObject.h" 22 #include "itkObjectFactory.h" 23 24 #include <map> 25 26 namespace itk 27 { 28 /** \class MapContainer 29 * \brief A wrapper of the STL "map" container. 30 * 31 * Define a front-end to the STL "map" container that conforms to the 32 * IndexedContainerInterface. This is a full-fleged Object, so 33 * there are events, modification time, debug, and reference count 34 * information. 35 * 36 * \tparam TElementIdentifier A type that shall be used to index the 37 * container. It must have a < operator defined for ordering. 38 * 39 * \tparam TElement The element type stored in the container. 40 * 41 * \ingroup DataRepresentation 42 * \ingroup ITKCommon 43 */ 44 template< typename TElementIdentifier, typename TElement > 45 class ITK_TEMPLATE_EXPORT MapContainer: 46 public Object, 47 private std::map< TElementIdentifier, TElement > 48 { 49 public: 50 ITK_DISALLOW_COPY_AND_ASSIGN(MapContainer); 51 52 /** Standard class type aliases. */ 53 using Self = MapContainer; 54 using Superclass = Object; 55 using Pointer = SmartPointer< Self >; 56 using ConstPointer = SmartPointer< const Self >; 57 58 /** Standard part of every itk Object. */ 59 itkTypeMacro(MapContainer, Object); 60 61 /** Save the template parameters. */ 62 using ElementIdentifier = TElementIdentifier; 63 using Element = TElement; 64 65 private: 66 /** Quick access to the STL map type that was inherited. */ 67 using MapType = std::map< ElementIdentifier, Element >; 68 using MapIterator = typename MapType::iterator; 69 using MapConstIterator = typename MapType::const_iterator; 70 using MapKeyCompareType = typename MapType::key_compare; 71 72 public: 73 /** Provide pass-through constructors corresponding to all the STL 74 * map constructors. These are for internal use only since this is also 75 * an Object which must be constructed through the "New()" routine. */ MapContainer()76 MapContainer():MapType() {} MapContainer(const MapKeyCompareType & comp)77 MapContainer(const MapKeyCompareType & comp):MapType(comp) {} 78 // MapContainer(const Self& r):MapType(r) {} 79 template< typename TInputIterator > MapContainer(TInputIterator first,TInputIterator last)80 MapContainer(TInputIterator first, TInputIterator last):MapType(first, last) {} 81 template< typename TInputIterator > MapContainer(TInputIterator first,TInputIterator last,const MapKeyCompareType & comp)82 MapContainer(TInputIterator first, TInputIterator last, const MapKeyCompareType & comp): 83 MapType(first, last, comp) {} 84 85 /** Method for creation through the object factory. */ 86 itkNewMacro(Self); 87 88 /** This type is provided to adapt this container as an STL container */ 89 using STLContainerType = MapType; 90 91 /** Cast the container to a STL container type */ CastToSTLContainer()92 STLContainerType & CastToSTLContainer() ITK_NOEXCEPT 93 { 94 return *this; 95 } 96 97 /** Cast the container to a const STL container type */ CastToSTLConstContainer()98 const STLContainerType & CastToSTLConstContainer() const ITK_NOEXCEPT 99 { 100 return *this; 101 } 102 103 using STLContainerType::begin; 104 using STLContainerType::end; 105 using STLContainerType::rbegin; 106 using STLContainerType::rend; 107 108 using STLContainerType::empty; 109 using STLContainerType::size; 110 using STLContainerType::max_size; 111 112 using STLContainerType::operator[]; 113 114 using STLContainerType::insert; 115 using STLContainerType::erase; 116 using STLContainerType::swap; 117 using STLContainerType::clear; 118 119 using STLContainerType::key_comp; 120 using STLContainerType::value_comp; 121 122 using STLContainerType::find; 123 using STLContainerType::count; 124 using STLContainerType::lower_bound; 125 using STLContainerType::upper_bound; 126 using STLContainerType::equal_range; 127 128 using STLContainerType::get_allocator; 129 130 using typename STLContainerType::key_type; 131 using typename STLContainerType::mapped_type; 132 using typename STLContainerType::value_type; 133 using typename STLContainerType::key_compare; 134 using typename STLContainerType::value_compare; 135 using typename STLContainerType::allocator_type; 136 using typename STLContainerType::reference; 137 using typename STLContainerType::const_reference; 138 using typename STLContainerType::iterator; 139 using typename STLContainerType::const_iterator; 140 using typename STLContainerType::size_type; 141 using typename STLContainerType::difference_type; 142 using typename STLContainerType::pointer; 143 using typename STLContainerType::const_pointer; 144 using typename STLContainerType::reverse_iterator; 145 using typename STLContainerType::const_reverse_iterator; 146 147 /** Declare iterators to container. */ 148 class Iterator; 149 class ConstIterator; 150 friend class Iterator; 151 friend class ConstIterator; 152 153 /** \class Iterator 154 * \brief The non-const iterator type for the map. 155 * \ingroup ITKCommon 156 */ 157 class Iterator 158 { 159 public: 160 using iterator_category = typename MapIterator::iterator_category; 161 using value_type = typename MapIterator::value_type; 162 using difference_type = typename MapIterator::difference_type; 163 using pointer = typename MapIterator::pointer; 164 using reference = typename MapIterator::reference; 165 166 Iterator() = default; Iterator(const Iterator & i)167 Iterator(const Iterator & i):m_Iter(i.m_Iter) {} Iterator(const MapIterator & i)168 Iterator(const MapIterator & i):m_Iter(i) {} 169 Iterator & operator=(const Iterator & r ) { m_Iter = r.m_Iter; return *this; } 170 171 Iterator & operator*() { return *this; } 172 Iterator * operator->() { return this; } 173 Iterator & operator++() { ++m_Iter; return *this; } 174 Iterator operator++(int) { Iterator temp(*this); ++m_Iter; return temp; } 175 Iterator & operator--() { --m_Iter; return *this; } 176 Iterator operator--(int) { Iterator temp(*this); --m_Iter; return temp; } 177 178 bool operator==(const Iterator & r) const { return m_Iter == r.m_Iter; } 179 bool operator!=(const Iterator & r) const { return m_Iter != r.m_Iter; } 180 bool operator==(const ConstIterator & r) const { return m_Iter == r.m_Iter; } 181 bool operator!=(const ConstIterator & r) const { return m_Iter != r.m_Iter; } 182 183 /** Get the index into the MapContainer associated with this iterator. */ Index()184 ElementIdentifier Index() const { return m_Iter->first; } 185 186 /** Get the value at this iterator's location in the MapContainer. */ Value()187 Element & Value() { return m_Iter->second; } 188 189 private: 190 MapIterator m_Iter; 191 friend class ConstIterator; 192 }; 193 194 /** \class ConstIterator 195 * \brief The const iterator type for the map. 196 * \ingroup ITKCommon 197 */ 198 class ConstIterator 199 { 200 public: 201 using iterator_category = typename MapConstIterator::iterator_category; 202 using value_type = typename MapConstIterator::value_type; 203 using difference_type = typename MapConstIterator::difference_type; 204 using pointer = typename MapConstIterator::pointer; 205 using reference = typename MapConstIterator::reference; 206 207 ConstIterator() = default; ConstIterator(const MapConstIterator & ci)208 ConstIterator(const MapConstIterator & ci):m_Iter(ci) {} ConstIterator(const Iterator & r)209 ConstIterator(const Iterator & r) : m_Iter( r.m_Iter ) {} 210 ConstIterator & operator=(const ConstIterator & r ) { m_Iter = r.m_Iter; return *this; } 211 212 ConstIterator & operator*() { return *this; } 213 ConstIterator * operator->() { return this; } 214 ConstIterator & operator++() { ++m_Iter; return *this; } 215 ConstIterator operator++(int) { ConstIterator temp(*this); ++m_Iter; return temp; } 216 ConstIterator & operator--() { --m_Iter; return *this; } 217 ConstIterator operator--(int) { ConstIterator temp(*this); --m_Iter; return temp; } 218 219 bool operator==(const Iterator & r) const { return m_Iter == r.m_Iter; } 220 bool operator!=(const Iterator & r) const { return m_Iter != r.m_Iter; } 221 bool operator==(const ConstIterator & r) const { return m_Iter == r.m_Iter; } 222 bool operator!=(const ConstIterator & r) const { return m_Iter != r.m_Iter; } 223 224 /** Get the index into the MapContainer associated with this iterator. */ Index()225 ElementIdentifier Index() const { return m_Iter->first; } 226 227 /** Get the value at this iterator's location in the MapContainer. */ Value()228 const Element & Value() const { return m_Iter->second; } 229 230 private: 231 MapConstIterator m_Iter; 232 friend class Iterator; 233 }; 234 235 /* Declare the public interface routines. */ 236 237 /** 238 * Get a reference to the element at the given index. 239 * If the index does not exist, it is created automatically. 240 * 241 * It is assumed that the value of the element is modified through the 242 * reference. 243 */ 244 Element & ElementAt(ElementIdentifier); 245 246 /** 247 * Get a reference to the element at the given index. 248 * 249 */ 250 const Element & ElementAt(ElementIdentifier) const; 251 252 /** 253 * Get a reference to the element at the given index. 254 * If the index does not exist, it is created automatically. 255 * 256 * It is assumed that the value of the element is modified through the 257 * reference. 258 */ 259 Element & CreateElementAt(ElementIdentifier); 260 261 /** 262 * Get the element at the specified index. There is no check for 263 * existence performed. 264 */ 265 Element GetElement(ElementIdentifier) const; 266 267 /** 268 * Set the given index value to the given element. If the index doesn't 269 * exist, it is automatically created. 270 */ 271 void SetElement(ElementIdentifier, Element); 272 273 /** 274 * Set the given index value to the given element. If the index doesn't 275 * exist, it is automatically created. 276 */ 277 void InsertElement(ElementIdentifier, Element); 278 279 /** 280 * Check if the STL map has an entry corresponding to the given index. 281 * The count will be either 1 or 0. 282 */ 283 bool IndexExists(ElementIdentifier) const; 284 285 /** 286 * If the given index doesn't exist in the map, return false. 287 * Otherwise, set the element through the pointer (if it isn't null), and 288 * return true. 289 */ 290 bool GetElementIfIndexExists(ElementIdentifier, Element *) const; 291 292 /** 293 * The map will create an entry for a given index through the indexing 294 * operator. Whether or not it is created, it will be assigned to the 295 * default element. 296 */ 297 void CreateIndex(ElementIdentifier); 298 299 /** 300 * Delete the entry in the STL map corresponding to the given identifier. 301 * If the entry does not exist, nothing happens. 302 */ 303 void DeleteIndex(ElementIdentifier); 304 305 /** 306 * Get a begin const iterator for the map. 307 */ 308 ConstIterator Begin() const; 309 310 /** 311 * Get an end const iterator for the map. 312 */ 313 ConstIterator End() const; 314 315 /** 316 * Get a begin const iterator for the map. 317 */ 318 Iterator Begin(); 319 320 /** 321 * Get an end const iterator for the map. 322 */ 323 Iterator End(); 324 325 /** 326 * Get the number of elements currently stored in the map. 327 */ 328 ElementIdentifier Size() const; 329 330 /** 331 * Tell the container to allocate enough memory to allow at least 332 * as many elements as the size given to be stored. This is NOT 333 * guaranteed to actually allocate any memory, but is useful if the 334 * implementation of the container allocates contiguous storage. 335 */ 336 void Reserve(ElementIdentifier); 337 338 /** 339 * Tell the container to try to minimize its memory usage for storage of 340 * the current number of elements. This is NOT guaranteed to decrease 341 * memory usage. 342 */ 343 void Squeeze(); 344 345 /** 346 * Tell the container to release any memory it may have allocated and 347 * return itself to its initial state. 348 */ 349 void Initialize(); 350 }; 351 } // end namespace itk 352 353 #ifndef ITK_MANUAL_INSTANTIATION 354 #include "itkMapContainer.hxx" 355 #endif 356 357 #endif 358