mod_servlet
C++Servlets
 All Classes Files Functions Variables Typedefs Macros Pages
linked_map.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2016 Alexei Novakov
3 https://github.com/novalexei
4 
5 Distributed under the Boost Software License, Version 1.0.
6 http://boost.org/LICENSE_1_0.txt
7 */
8 #ifndef SERVLET_LINKED_HASH_MAP_H
9 #define SERVLET_LINKED_HASH_MAP_H
10 
11 #include <map>
12 #include <unordered_map>
13 #include <list>
14 #include <chrono>
15 #include <mutex>
16 #include <experimental/any>
17 
18 #include <servlet/lib/optional.h>
19 
26 namespace servlet
27 {
28 
56 template<typename _Key, typename _Tp, typename _MT>
58 {
59 public:
63  typedef _Key key_type;
67  typedef _Tp mapped_type;
71  typedef std::pair<const _Key&, _Tp> value_type;
72 
80  typedef std::list<value_type> list_type;
84  typedef _MT map_type;
85 
89  typedef typename map_type::allocator_type allocator_type;
97  typedef const value_type& const_reference;
101  typedef value_type* pointer;
105  typedef const value_type* const_pointer;
109  typedef typename map_type::size_type size_type;
113  typedef typename map_type::difference_type difference_type;
114 
118  typedef typename list_type::iterator iterator;
122  typedef typename list_type::const_iterator const_iterator;
126  typedef typename list_type::reverse_iterator reverse_iterator;
130  typedef typename list_type::const_reverse_iterator const_reverse_iterator;
131 
135  linked_map() = default;
142  linked_map(const linked_map& m) = default;
149  linked_map(linked_map&& m) = default;
150 
151  ~linked_map() = default;
152 
161  linked_map& operator=(const linked_map& m) = default;
170  linked_map& operator=(linked_map&& m) = default;
171 
177  bool empty() const noexcept { return _map.empty(); }
182  size_type size() const noexcept { return _map.size(); }
183 
192  template<typename KeyType>
193  bool contains_key(const KeyType &key) const { return _map.find(key) != _map.end(); }
194 
201  void clear()
202  {
203  _map.clear();
204  _list.clear();
205  }
206 
221  template<typename KeyType>
222  optional_ref<const mapped_type> get(const KeyType& key) const
223  {
224  auto it = _map.find(key);
225  if (it == _map.end()) return optional_ref<const mapped_type>{};
226  _list.splice(_list.cend(), _list, it->second);
227  update(*it->second);
228  return optional_ref<const mapped_type>{it->second->second};
229  }
244  template<typename KeyType>
245  optional_ref<mapped_type> get(const KeyType& key)
246  {
247  auto it = _map.find(key);
248  if (it == _map.end()) return optional_ref<mapped_type>{};
249  _list.splice(_list.cend(), _list, it->second);
250  update(*it->second);
251  return optional_ref<mapped_type>{it->second->second};
252  }
253 
265  template<class... Args>
266  bool put(key_type&& key, Args &&... args)
267  {
268  auto it = _map.find(key);
269  bool found = it != _map.end();
270  if (found)
271  {
272  _list.splice(_list.cend(), _list, it->second);
273  it->second->second = mapped_type{std::forward<Args>(args)...};
274  }
275  else
276  {
277  auto pr = _map.emplace(std::move(key), _list.begin());
278  _list.emplace_back(std::piecewise_construct,
279  std::forward_as_tuple(pr.first->first),
280  std::forward_as_tuple(std::forward<Args>(args)...));
281  pr.first->second = --_list.end();
282  }
283  purge();
284  return found;
285  }
297  template<class... Args>
298  bool put(const key_type& key, Args &&... args)
299  {
300  auto it = _map.find(key);
301  bool found = it != _map.end();
302  if (found)
303  {
304  _list.splice(_list.cend(), _list, it->second);
305  it->second->second = mapped_type{std::forward<Args>(args)...};
306  }
307  else
308  {
309  auto pr = _map.emplace(key, _list.begin());
310  _list.emplace_back(std::piecewise_construct,
311  std::forward_as_tuple(pr.first->first),
312  std::forward_as_tuple(std::forward<Args>(args)...));
313  pr.first->second = --_list.end();
314  }
315  purge();
316  return found;
317  }
318 
330  template<class... Args>
331  bool try_put(key_type&& key, Args &&... args)
332  {
333  auto it = _map.find(key);
334  if (it != _map.end()) return false;
335  auto pr = _map.emplace(std::move(key), _list.begin());
336  _list.emplace_back(std::piecewise_construct,
337  std::forward_as_tuple(pr.first->first),
338  std::forward_as_tuple(std::forward<Args>(args)...));
339  pr.first->second = --_list.end();
340  purge();
341  return true;
342  }
354  template<class... Args>
355  bool try_put(const key_type& key, Args &&... args)
356  {
357  auto it = _map.find(key);
358  if (it != _map.end()) return false;
359  auto pr = _map.emplace(key, _list.begin());
360  _list.emplace_back(std::piecewise_construct,
361  std::forward_as_tuple(pr.first->first),
362  std::forward_as_tuple(std::forward<Args>(args)...));
363  pr.first->second = --_list.end();
364  purge();
365  return true;
366  }
367 
380  template<typename KeyType>
381  bool erase(const KeyType &key)
382  {
383  auto it = _map.find(key);
384  if (it == _map.end()) return false;
385  _list.erase(it->second);
386  _map.erase(it);
387  purge();
388  return true;
389  }
390 
398  iterator begin() noexcept { return _list.begin(); }
405  iterator end() noexcept { return _list.end(); }
413  const_iterator begin() const noexcept { return _list.begin(); }
420  const_iterator end() const noexcept { return _list.end(); }
421 
429  const_iterator cbegin() const noexcept { return _list.cbegin(); }
436  const_iterator cend() const noexcept { return _list.cend(); }
437 
446  reverse_iterator rbegin() noexcept { return _list.rbegin(); }
454  reverse_iterator rend() noexcept { return _list.rend(); }
463  const_reverse_iterator rbegin() const noexcept { return _list.rbegin(); }
471  const_reverse_iterator rend() const noexcept { return _list.rend(); }
472 
481  const_reverse_iterator crbegin() const noexcept { return _list.crbegin(); }
489  const_reverse_iterator crend() const noexcept { return _list.crend(); }
490 
491 protected:
501  virtual void update(value_type& val) const { }
509  virtual void purge() {}
510 
511 private:
512  map_type _map;
513  mutable list_type _list;
514 };
515 
519 template <typename _Key, typename _Value, typename _Compare = std::less<>,
520  typename _Alloc = std::allocator<std::pair<const _Key,
521  typename std::list<std::pair<const _Key&, _Value>>::iterator>>>
522 using linked_tree_map = linked_map<_Key, _Value,
523  std::map<_Key, typename std::list<std::pair<const _Key&, _Value>>::iterator,
524  _Compare, _Alloc>>;
525 
529 template <typename _Key, typename _Value, typename _Hash = std::hash<_Key>,
530  typename _Pred = std::equal_to<_Key>,
531  typename _Alloc = std::allocator<std::pair<const _Key,
532  typename std::list<std::pair<const _Key&, _Value>>::iterator>>>
533 using linked_hash_map = linked_map<_Key, _Value,
534  std::unordered_map<_Key, typename std::list<std::pair<const _Key&, _Value>>::iterator,
535  _Hash, _Pred, _Alloc>>;
536 
537 } // end of servlet namespace
538 
539 #endif // SERVLET_LINKED_HASH_MAP_H
map_type::difference_type difference_type
A signed integral type to represent distance between iterators.
Definition: linked_map.h:113
linked_map & operator=(const linked_map &m)=default
The copy assignment.
Defines optional container objects and related methods.
map_type::size_type size_type
An unsigned integral type to represent the size of this container.
Definition: linked_map.h:109
virtual void purge()
Removes elements which do not confirm to the storage criteria from the container. ...
Definition: linked_map.h:509
linked_map< _Key, _Tp, _MT > self_type
The type of this container.
Definition: linked_map.h:76
std::list< value_type > list_type
List type to maintain the order of elements.
Definition: linked_map.h:80
list_type::iterator iterator
Bidirectional iterator type.
Definition: linked_map.h:118
bool try_put(const key_type &key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:355
const_reverse_iterator rend() const noexcept
Return constant reverse iterator to reverse end.
Definition: linked_map.h:471
bool put(const key_type &key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:298
Optional reference implementation.
Definition: optional.h:221
reverse_iterator rbegin() noexcept
Return reverse iterator to reverse beginning.
Definition: linked_map.h:446
bool contains_key(const KeyType &key) const
Tests whether value with a given key exists in this container.
Definition: linked_map.h:193
const_iterator cbegin() const noexcept
Returns constant iterator to beginning of the container.
Definition: linked_map.h:429
const_iterator cend() const noexcept
Return constant iterator to end of the container.
Definition: linked_map.h:436
bool erase(const KeyType &key)
Erase element.
Definition: linked_map.h:381
const value_type * const_pointer
Constant pointer to value_type type.
Definition: linked_map.h:105
Implementation of linked associative container.
Definition: linked_map.h:57
value_type & reference
value_type&
Definition: linked_map.h:93
list_type::reverse_iterator reverse_iterator
Reverse iterator type.
Definition: linked_map.h:126
linked_map()=default
Constructs an empty container, with no elements.
iterator end() noexcept
Return iterator to end of the container.
Definition: linked_map.h:405
const_iterator begin() const noexcept
Returns constant iterator to beginning of the container.
Definition: linked_map.h:413
const_reverse_iterator crbegin() const noexcept
Return constant reverse iterator to reverse beginning.
Definition: linked_map.h:481
const_reverse_iterator rbegin() const noexcept
Return constant reverse iterator to reverse beginning.
Definition: linked_map.h:463
std::pair< const _Key &, _Tp > value_type
Container's value type: std::pair<const key_type&, mapped_type>
Definition: linked_map.h:71
map_type::allocator_type allocator_type
Container's allocator type.
Definition: linked_map.h:89
bool try_put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:331
value_type * pointer
Pointer to value_type type.
Definition: linked_map.h:101
bool empty() const noexcept
Test whether container is empty.
Definition: linked_map.h:177
const value_type & const_reference
const value_type&
Definition: linked_map.h:97
list_type::const_reverse_iterator const_reverse_iterator
Constant reverse iterator type.
Definition: linked_map.h:130
list_type::const_iterator const_iterator
Bidirectional constant iterator type.
Definition: linked_map.h:122
_MT map_type
Underlying map type.
Definition: linked_map.h:84
virtual void update(value_type &val) const
Updates element on access.
Definition: linked_map.h:501
size_type size() const noexcept
Returns the number of elements in the container.
Definition: linked_map.h:182
_Key key_type
Container's key type.
Definition: linked_map.h:63
_Tp mapped_type
Container's mapped type.
Definition: linked_map.h:67
const_reverse_iterator crend() const noexcept
Return constant reverse iterator to reverse end.
Definition: linked_map.h:489
bool put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:266
void clear()
Clear content.
Definition: linked_map.h:201
iterator begin() noexcept
Returns iterator to beginning of the container.
Definition: linked_map.h:398
const_iterator end() const noexcept
Return constant iterator to end of the container.
Definition: linked_map.h:420
reverse_iterator rend() noexcept
Return reverse iterator to reverse end.
Definition: linked_map.h:454