LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
stdmap_shims.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_stdmap_shims_h
2 #define fhiclcpp_stdmap_shims_h
3 
4 #include <algorithm>
5 #include <iostream>
6 #include <iterator>
7 #include <list>
8 #include <map>
9 #include <stdexcept>
10 #include <type_traits>
11 #include <utility>
12 
14 
15 namespace shims {
16 
17  template <class Key,
18  class T,
19  class Compare = std::less<Key>,
20  class Allocator = std::allocator<std::pair<const Key, T>>>
21  class map {
22  public:
23  using mapmap_t = std::map<const Key, T, Compare, Allocator>;
24  using listmap_t = std::list<std::pair<const Key, T>, Allocator>;
25 
26  static_assert(std::is_same_v<typename mapmap_t::key_type,
27  typename listmap_t::value_type::first_type>,
28  "type mismatch for key_type");
29  static_assert(std::is_same_v<typename mapmap_t::mapped_type,
30  typename listmap_t::value_type::second_type>,
31  "type mismatch for mapped_type");
32  static_assert(std::is_same_v<typename mapmap_t::value_type,
33  typename listmap_t::value_type>,
34  "type mismatch for value_type");
35  static_assert(std::is_same_v<typename mapmap_t::size_type,
36  typename listmap_t::size_type>,
37  "type mismatch for size_type");
38 
39  using size_type = typename mapmap_t::size_type;
40 
41  using iterator_tag = std::input_iterator_tag;
42  struct iterator_tuple {
45  };
46 
47  template <class Category,
48  class TT,
49  class Distance = std::ptrdiff_t,
50  class Pointer = TT*,
51  class Reference = TT&>
52  struct iter {
53  using type = TT;
54  using iterator_category = Category;
55  using value_type = TT;
56  using difference_type = Distance;
57  using pointer = Pointer;
58  using reference = Reference;
59 
60  iter(typename mapmap_t::iterator it) noexcept { _iters.mapmap_iter = it; }
61  iter(typename listmap_t::iterator it) noexcept
62  {
63  _iters.listmap_iter = it;
64  }
65 
66  TT&
67  operator*() noexcept
68  {
69  return isSnippetMode() ? *_iters.listmap_iter : *_iters.mapmap_iter;
70  }
71 
72  TT*
73  operator->() noexcept
74  {
75  return isSnippetMode() ? &*_iters.listmap_iter : &*_iters.mapmap_iter;
76  }
77 
78  TT const*
79  operator->() const noexcept
80  {
81  return isSnippetMode() ? &*_iters.listmap_iter : &*_iters.mapmap_iter;
82  }
83 
84  TT&
86  {
87  return isSnippetMode() ? *(_iters.listmap_iter++) :
88  *(_iters.mapmap_iter++);
89  }
90 
91  bool
92  operator==(iter other) const noexcept
93  {
94  return isSnippetMode() ?
95  _iters.listmap_iter == other._iters.listmap_iter :
96  _iters.mapmap_iter == other._iters.mapmap_iter;
97  }
98 
99  bool
100  operator!=(iter other) const noexcept
101  {
102  return !operator==(other);
103  }
104 
105  template <typename II>
106  std::enable_if_t<std::is_same_v<typename mapmap_t::iterator, II>, II>
107  get(II)
108  {
109  return _iters.mapmap_iter;
110  }
111 
112  template <typename II>
113  std::enable_if_t<std::is_same_v<typename listmap_t::iterator, II>, II>
114  get(II)
115  {
116  return _iters.listmap_iter;
117  }
118 
119  template <typename IIL, typename IIR>
120  friend std::enable_if_t<
121  !std::is_same_v<IIL, IIR> &&
122  std::is_same_v<std::remove_const_t<typename IIL::type>,
123  std::remove_const_t<typename IIR::type>>,
124  bool>
125  operator==(IIL, IIR) noexcept;
126 
127  template <typename IIL, typename IIR>
128  friend std::enable_if_t<
129  !std::is_same_v<IIL, IIR> &&
130  std::is_same_v<std::remove_const_t<typename IIL::type>,
131  std::remove_const_t<typename IIR::type>>,
132  bool>
133  operator!=(IIL, IIR) noexcept;
134 
135  private:
137  };
138 
141 
142  struct maps_tuple {
145  };
146 
147  T&
148  operator[](Key const& key)
149  {
150  if (isSnippetMode()) {
151  for (auto& [stored_key, value] : _maps.listmap) {
152  if (stored_key == key)
153  return value;
154  }
155  _maps.listmap.emplace_back(key, T{});
156  return _maps.listmap.back().second;
157  }
158  return _maps.mapmap[key];
159  }
160 
161  iterator
162  begin() noexcept
163  {
166  }
167 
169  begin() const noexcept
170  {
171  auto& maps = const_cast<maps_tuple&>(_maps);
172  return isSnippetMode() ? const_iterator{std::begin(maps.listmap)} :
173  const_iterator{std::begin(maps.mapmap)};
174  }
175 
177  cbegin() const noexcept
178  {
179  return begin();
180  }
181 
182  iterator
183  end() noexcept
184  {
187  }
188 
190  end() const noexcept
191  {
192  auto& maps = const_cast<maps_tuple&>(_maps);
193  return isSnippetMode() ? const_iterator{std::end(maps.listmap)} :
194  const_iterator{std::end(maps.mapmap)};
195  }
196 
198  cend() const noexcept
199  {
200  return end();
201  }
202 
203  T&
204  at(Key const& key)
205  {
206  if (isSnippetMode()) {
207  auto it =
208  std::find_if(_maps.listmap.begin(),
209  _maps.listmap.end(),
210  [&key](auto& element) { return element.first == key; });
211  if (it == _maps.listmap.end())
212  throw std::out_of_range("Key <" + key + "> not found.");
213  return it->second;
214  } else {
215  return _maps.mapmap.at(key);
216  }
217  }
218 
219  T const&
220  at(Key const& key) const
221  {
222  if (isSnippetMode()) {
223  auto it = std::find_if(
224  _maps.listmap.cbegin(),
225  _maps.listmap.cend(),
226  [&key](auto const& element) { return element.first == key; });
227  if (it == _maps.listmap.cend())
228  throw std::out_of_range("Key <" + key + "> not found.");
229  return it->second;
230  } else {
231  return _maps.mapmap.at(key);
232  }
233  }
234 
235  iterator
236  find(Key const& key)
237  {
238  if (isSnippetMode()) {
239  return std::find_if(
240  _maps.listmap.begin(), _maps.listmap.end(), [&key](auto& element) {
241  return element.first == key;
242  });
243  } else {
244  return _maps.mapmap.find(key);
245  }
246  }
247 
249  find(Key const& key) const
250  {
251  maps_tuple& maps = *const_cast<maps_tuple*>(&_maps);
252 
253  if (isSnippetMode()) {
254  return std::find_if(
255  maps.listmap.begin(),
256  maps.listmap.end(),
257  [&key](auto const& element) { return element.first == key; });
258  } else {
259  return maps.mapmap.find(key);
260  }
261  }
262 
263  size_t
264  erase(Key const& key)
265  {
266  if (isSnippetMode()) {
267  auto erase_count = size_t{0};
268  auto i = _maps.listmap.begin();
269  auto e = _maps.listmap.end();
270 
271  while (i != e) {
272  if (key == i->first) {
273  i = _maps.listmap.erase(i);
274  ++erase_count;
275  } else {
276  i++;
277  }
278  }
279 
280  return erase_count;
281  } else {
282  return _maps.mapmap.erase(key);
283  }
284  }
285 
286  bool
287  empty() const noexcept
288  {
289  return isSnippetMode() ? _maps.listmap.empty() : _maps.mapmap.empty();
290  }
291 
292  size_type
293  size() const noexcept
294  {
295  return isSnippetMode() ? _maps.listmap.size() : _maps.mapmap.size();
296  }
297 
298  iterator
300  {
301  if (isSnippetMode()) {
302  return _maps.listmap.erase(it.get(typename listmap_t::iterator{}));
303  }
304  return _maps.mapmap.erase(it.get(typename mapmap_t::iterator{}));
305  }
306 
307  iterator
309  {
310  if (isSnippetMode()) {
311  return _maps.listmap.erase(it.get(typename listmap_t::iterator{}));
312  } else {
313  return _maps.mapmap.erase(it.get(typename mapmap_t::iterator{}));
314  }
315  }
316 
317  template <class... Args>
318  std::pair<iterator, bool>
319  emplace(Args&&... args)
320  {
321  if (isSnippetMode()) {
322  _maps.listmap.emplace_back(std::forward<Args>(args)...);
323  return std::make_pair(iterator{std::prev(_maps.listmap.end())}, true);
324  } else {
325  auto result = _maps.mapmap.emplace(std::forward<Args>(args)...);
326  return std::make_pair(iterator{result.first}, result.second);
327  }
328  }
329 
331  };
332  template <typename IIL, typename IIR>
333  std::enable_if_t<!std::is_same_v<IIL, IIR> &&
334  std::is_same_v<std::remove_const_t<typename IIL::type>,
335  std::remove_const_t<typename IIR::type>>,
336  bool>
337  operator==(IIL left, IIR right) noexcept
338  {
339  return isSnippetMode() ?
340  left._iters.listmap_iter == right._iters.listmap_iter :
341  left._iters.mapmap_iter == right._iters.mapmap_iter;
342  }
343 
344  template <typename IIL, typename IIR>
345  std::enable_if_t<!std::is_same_v<IIL, IIR> &&
346  std::is_same_v<std::remove_const_t<typename IIL::type>,
347  std::remove_const_t<typename IIR::type>>,
348  bool>
349  operator!=(IIL left, IIR right) noexcept
350  {
351  return !operator==(left, right);
352  }
353 }
354 
355 #endif /* fhiclcpp_stdmap_shims_h */
356 
357 // Local Variables:
358 // mode: c++
359 // End:
const_iterator cbegin() const noexcept
Definition: stdmap_shims.h:177
iterator end() noexcept
Definition: stdmap_shims.h:183
intermediate_table::iterator iterator
size_t erase(Key const &key)
Definition: stdmap_shims.h:264
TT const * operator->() const noexcept
Definition: stdmap_shims.h:79
iter(typename mapmap_t::iterator it) noexcept
Definition: stdmap_shims.h:60
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
bool operator!=(iter other) const noexcept
Definition: stdmap_shims.h:100
Reference reference
Definition: stdmap_shims.h:58
const_iterator end() const noexcept
Definition: stdmap_shims.h:190
iterator_tuple _iters
Definition: stdmap_shims.h:136
maps_tuple _maps
Definition: stdmap_shims.h:330
listmap_t::iterator listmap_iter
Definition: stdmap_shims.h:44
Distance difference_type
Definition: stdmap_shims.h:56
Category iterator_category
Definition: stdmap_shims.h:54
TT * operator->() noexcept
Definition: stdmap_shims.h:73
std::pair< iterator, bool > emplace(Args &&...args)
Definition: stdmap_shims.h:319
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
iter(typename listmap_t::iterator it) noexcept
Definition: stdmap_shims.h:61
bool empty() const noexcept
Definition: stdmap_shims.h:287
std::enable_if_t< std::is_same_v< typename mapmap_t::iterator, II >, II > get(II)
Definition: stdmap_shims.h:107
size_type size() const noexcept
Definition: stdmap_shims.h:293
mapmap_t::iterator mapmap_iter
Definition: stdmap_shims.h:43
std::enable_if_t<!std::is_same_v< IIL, IIR > &&std::is_same_v< std::remove_const_t< typename IIL::type >, std::remove_const_t< typename IIR::type > >, bool > operator==(IIL left, IIR right) noexcept
Definition: stdmap_shims.h:337
std::enable_if_t<!std::is_same_v< IIL, IIR > &&std::is_same_v< std::remove_const_t< typename IIL::type >, std::remove_const_t< typename IIR::type > >, bool > operator!=(IIL left, IIR right) noexcept
Definition: stdmap_shims.h:349
T const & at(Key const &key) const
Definition: stdmap_shims.h:220
double value
Definition: spectrum.C:18
bool operator==(iter other) const noexcept
Definition: stdmap_shims.h:92
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
iterator erase(iterator it)
Definition: stdmap_shims.h:299
T & operator[](Key const &key)
Definition: stdmap_shims.h:148
T & at(Key const &key)
Definition: stdmap_shims.h:204
iterator begin() noexcept
Definition: stdmap_shims.h:162
TT & operator*() noexcept
Definition: stdmap_shims.h:67
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
std::list< std::pair< const Key, T >, Allocator > listmap_t
Definition: stdmap_shims.h:24
bool isSnippetMode(bool m=false) noexcept
Float_t e
Definition: plot.C:35
iterator find(Key const &key)
Definition: stdmap_shims.h:236
typename mapmap_t::size_type size_type
Definition: stdmap_shims.h:39
std::input_iterator_tag iterator_tag
Definition: stdmap_shims.h:41
std::map< const Key, T, Compare, Allocator > mapmap_t
Definition: stdmap_shims.h:23
iterator erase(const_iterator &it)
Definition: stdmap_shims.h:308
const_iterator cend() const noexcept
Definition: stdmap_shims.h:198
const_iterator find(Key const &key) const
Definition: stdmap_shims.h:249
const_iterator begin() const noexcept
Definition: stdmap_shims.h:169