trie.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //
  2. // trie.hpp
  3. // trie
  4. //
  5. // Created by Sam Jaffe on 6/16/17.
  6. //
  7. #pragma once
  8. #include "pointers/const_propogating_ptr.hpp"
  9. #include "pointers/not_null.hpp"
  10. #include "pointers/value_ptr.hpp"
  11. #include <map>
  12. template <typename K, typename V, typename Compare = std::less<K>>
  13. class trie;
  14. template <typename Trie, typename Iter>
  15. class trie_iterator;
  16. template <typename Trie, typename Iter>
  17. class trie_reverse_iterator;
  18. template <typename K, typename V, typename Compare>
  19. class trie {
  20. private:
  21. using self_t = trie<K, V, Compare>;
  22. using layer_t = value_ptr<self_t>;
  23. using backing_t = std::map<K, const_propogating_ptr<not_null<layer_t>>, Compare>;
  24. template <typename KS>
  25. using is_collection_t = typename std::enable_if<std::is_same<K, std::decay_t<decltype(*std::begin(std::declval<KS>()))>>::value>::type;
  26. public:
  27. using key_type = K;
  28. using mapped_type = V;
  29. using key_compare = Compare;
  30. using local_iterator = typename backing_t::iterator;
  31. using local_const_iterator = typename backing_t::const_iterator;
  32. using local_reverse_iterator = typename backing_t::reverse_iterator;
  33. using local_const_reverse_iterator = typename backing_t::const_reverse_iterator;
  34. using iterator = trie_iterator<self_t, local_iterator>;
  35. using const_iterator = trie_iterator<self_t const, local_const_iterator>;
  36. using post_iterator = trie_iterator<self_t, local_reverse_iterator>;
  37. using const_post_iterator = trie_iterator<self_t const, local_const_reverse_iterator>;
  38. using reverse_iterator = trie_reverse_iterator<self_t, local_reverse_iterator>;
  39. using const_reverse_iterator = trie_reverse_iterator<self_t const, local_const_reverse_iterator>;
  40. public:
  41. trie() = default;
  42. trie(mapped_type const & value);
  43. trie(trie const & other);
  44. trie(trie && other) = default;
  45. self_t & operator=(mapped_type const & value);
  46. self_t & operator=(trie const & value);
  47. self_t & operator=(trie && value) = default;
  48. operator mapped_type &() { return value_; }
  49. operator mapped_type const &() const { return value_; }
  50. mapped_type & value() { return value_; }
  51. mapped_type const & value() const { return value_; }
  52. template <typename KS, typename = is_collection_t<KS>>
  53. self_t & operator[](KS const & keys);
  54. self_t & operator[](key_type const & key);
  55. self_t & operator[](std::initializer_list<key_type> key);
  56. template <typename KS>
  57. void insert(KS const & keys, mapped_type const & value);
  58. void insert(std::initializer_list<key_type> keys, mapped_type const & value);
  59. std::pair<iterator, bool> insert(key_type const & key, mapped_type const & value);
  60. iterator begin() { return {this}; }
  61. iterator end() { return {}; }
  62. const_iterator begin() const { return {this}; }
  63. const_iterator end() const { return {}; }
  64. const_iterator cbegin() const { return begin(); }
  65. const_iterator cend() const { return end(); }
  66. reverse_iterator rbegin() { return {this}; }
  67. reverse_iterator rend() { return {}; }
  68. const_reverse_iterator rbegin() const { return {this}; }
  69. const_reverse_iterator rend() const { return {}; }
  70. const_reverse_iterator crbegin() const { return rbegin(); }
  71. const_reverse_iterator crend() const { return rend(); }
  72. local_iterator local_begin() { return impl_.begin(); }
  73. local_iterator local_end() { return impl_.end(); }
  74. local_const_iterator local_begin() const { return impl_.begin(); }
  75. local_const_iterator local_end() const { return impl_.end(); }
  76. local_reverse_iterator local_rbegin() { return impl_.rbegin(); }
  77. local_reverse_iterator local_rend() { return impl_.rend(); }
  78. local_const_reverse_iterator local_rbegin() const { return impl_.rbegin(); }
  79. local_const_reverse_iterator local_rend() const { return impl_.rend(); }
  80. void clear() { impl_.clear(); value_ = mapped_type{}; }
  81. private:
  82. friend bool operator==(trie const & lhs, trie const & rhs) {
  83. auto it1 = lhs.begin(), it2 = rhs.begin(), end1 = lhs.end(), end2 = lhs.end();
  84. for ( ; it1 != end1 && it2 != end2 && it1 == it2; ++it1, ++it2 );
  85. return it1 == end1 && it2 == end2;
  86. }
  87. friend void swap(trie & lhs, trie & rhs) {
  88. using std::swap;
  89. swap(lhs.value_, rhs.value_);
  90. swap(lhs.impl_, rhs.impl_);
  91. }
  92. mapped_type value_;
  93. backing_t impl_;
  94. };
  95. #include "trie_impl.hpp"