GEOS
StdContainerWrappers.hpp
1 #ifndef GEOS_COMMON_STD_CONTAINER_WRAPPERS_HPP
2 #define GEOS_COMMON_STD_CONTAINER_WRAPPERS_HPP
3 
4 #include <vector>
5 #include <map>
6 #include <unordered_map>
7 #include <memory>
8 
9 #include <iostream>
10 
11 namespace geos
12 {
13 
14 #ifdef GEOS_USE_BOUNDS_CHECK
15 #define USE_STD_CONTAINER_BOUNDS_CHECKING true
16 #else
17 #define USE_STD_CONTAINER_BOUNDS_CHECKING false
18 #endif
19 
20 
21 namespace internal
22 {
23 
30 template< typename T >
31 using DefaultAllocator = std::allocator< T >;
32 
41 template< typename T,
42  typename Allocator = DefaultAllocator< T >,
43  bool USE_BOUNDS_CHECKING = false >
44 class StdVectorWrapper : public std::vector< T, Allocator >
45 {
46 public:
48  using Base = std::vector< T, Allocator >;
49 
52  StdVectorWrapper() noexcept(noexcept(Allocator())): Base( Allocator()) {}
53 
54  explicit StdVectorWrapper( const Allocator & alloc ) noexcept: Base( alloc ) {}
55 
56  explicit StdVectorWrapper( size_t count, const Allocator & alloc = Allocator())
57  : Base( count, alloc ) {}
58 
59  explicit StdVectorWrapper( size_t count, const T & value,
60  const Allocator & alloc = Allocator())
61  : Base( count, value, alloc ) {}
62 
63  template< class InputIt >
64  StdVectorWrapper( InputIt first, InputIt last,
65  const Allocator & alloc = Allocator())
66  : Base( first, last, alloc ) {}
67 
68  StdVectorWrapper( const Base & other ): Base( other ) {}
69 
70  StdVectorWrapper( Base && other ): Base( other ) {}
71 
72  StdVectorWrapper( const Base & other, const Allocator & alloc )
73  : Base( other, alloc ) {}
74 
75  StdVectorWrapper( Base && other, const Allocator & alloc )
76  : Base( other, alloc ) {}
77 
78  StdVectorWrapper( std::initializer_list< T > init,
79  const Allocator & alloc = Allocator())
80  : Base( init, alloc ) {}
81 
83 
84 
92  T const & operator[]( size_t const index ) const
93  {
94  if constexpr (USE_BOUNDS_CHECKING)
95  {
96  if( index >= this->size() )
97  {
98  std::cout<< "Index out of bounds in StdVectorWrapper::operator[]: index = " + std::to_string( index ) + ", size = " + std::to_string( this->size());
99  }
100  return Base::at( index ); // Throws std::out_of_range if out of bounds.
101  }
102  else
103  {
104  return Base::operator[]( index );
105  }
106  }
107 
114  T & operator[]( size_t const index )
115  {
116  if constexpr (USE_BOUNDS_CHECKING)
117  {
118  if( index >= this->size() )
119  {
120  std::cout<< "Index out of bounds in StdVectorWrapper::operator[]: index = " + std::to_string( index ) + ", size = " + std::to_string( this->size());
121  }
122  return Base::at( index ); // Throws std::out_of_range if out of bounds.
123  }
124  else
125  {
126  return Base::operator[]( index ); // No bounds checking
127  }
128  }
129 };
130 }
131 
137 template< typename T, typename Allocator = std::allocator< T > >
138 using stdVector = internal::StdVectorWrapper< T, Allocator, USE_STD_CONTAINER_BOUNDS_CHECKING >;
139 
140 
141 
142 namespace internal
143 {
144 
152 template< typename MapType,
153  bool USE_BOUNDS_CHECKING = false >
154 class StdMapWrapper : public MapType
155 {
156 public:
158  using Base = MapType;
159  using KeyType = typename Base::key_type;
160  using MappedType = typename Base::mapped_type;
161  using ValueType = typename Base::value_type;
162 
164  using Base::Base;
165 
173  MappedType & operator[]( KeyType const & key )
174  {
175  if constexpr (USE_BOUNDS_CHECKING)
176  {
177  return this->at( key ); // Throws std::out_of_range if key is missing
178  }
179  else
180  {
181  return Base::operator[]( key ); // Inserts default-constructed value if missing
182  }
183  }
184 
192  MappedType const & operator[]( KeyType const & key ) const
193  {
194  if constexpr (USE_BOUNDS_CHECKING)
195  {
196  return this->at( key );
197  }
198  else
199  {
200  return Base::operator[]( key );
201  }
202  }
203 };
204 
205 } //namespace internal
206 
214 template< typename Key,
215  typename T,
216  typename Compare = std::less< Key >,
217  typename Allocator = std::allocator< std::pair< const Key, T > > >
218 using stdMap = internal::StdMapWrapper< std::map< Key, T, Compare, Allocator >,
219  USE_STD_CONTAINER_BOUNDS_CHECKING >;
220 
229 template< typename Key,
230  typename T,
231  typename Hash = std::hash< Key >,
232  typename KeyEqual = std::equal_to< Key >,
233  typename Allocator = std::allocator< std::pair< const Key, T > > >
234 using stdUnorderedMap = internal::StdMapWrapper< std::unordered_map< Key, T, Hash, KeyEqual, Allocator >,
235  USE_STD_CONTAINER_BOUNDS_CHECKING >;
236 
241 
243 
248 
255 template< typename TKEY, typename TVAL, typename SORTED >
256 class mapType
257 {};
258 
260 template< typename TKEY, typename TVAL >
261 class mapType< TKEY, TVAL, std::integral_constant< bool, true > > : public stdMap< TKEY, TVAL >
262 {
263  using stdMap< TKEY, TVAL >::stdMap; // enable list initialization
264 };
265 
266 template< typename TKEY, typename TVAL >
267 class mapType< TKEY, TVAL, std::integral_constant< bool, false > > : public stdUnorderedMap< TKEY, TVAL >
268 {
269  using stdUnorderedMap< TKEY, TVAL >::stdUnorderedMap; // enable list initialization
270 };
272 
273 
279 
286 template< typename TKEY, typename TVAL, typename SORTED >
287 class mapBase
288 {};
289 
291 template< typename TKEY, typename TVAL >
292 class mapBase< TKEY, TVAL, std::integral_constant< bool, true > > : public std::map< TKEY, TVAL >
293 {
294  using std::map< TKEY, TVAL >::map; // enable list initialization
295 };
296 
297 template< typename TKEY, typename TVAL >
298 class mapBase< TKEY, TVAL, std::integral_constant< bool, false > > : public std::unordered_map< TKEY, TVAL >
299 {
300  using std::unordered_map< TKEY, TVAL >::unordered_map; // enable list initialization
301 };
303 
304 } // namespace geos
305 
306 #endif /* GEOS_COMMON_STD_CONTAINER_WRAPPERS_HPP */
Base template for ordered and unordered maps.
Base template for ordered and unordered maps.
internal::StdMapWrapper< std::unordered_map< Key, T, Hash, KeyEqual, Allocator >, USE_STD_CONTAINER_BOUNDS_CHECKING > stdUnorderedMap
mapBase< TKEY, TVAL, std::integral_constant< bool, false > > unordered_map
Unordered map type.
Definition: DataTypes.hpp:343
internal::StdMapWrapper< std::map< Key, T, Compare, Allocator >, USE_STD_CONTAINER_BOUNDS_CHECKING > stdMap
mapBase< TKEY, TVAL, std::integral_constant< bool, true > > map
Ordered map type.
Definition: DataTypes.hpp:339
internal::StdVectorWrapper< T, Allocator, USE_STD_CONTAINER_BOUNDS_CHECKING > stdVector