trie.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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<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. ~trie();
  46. self_t & operator=(mapped_type const & value);
  47. self_t & operator=(trie const & value);
  48. self_t & operator=(trie && value) = default;
  49. operator mapped_type &() { return value_; }
  50. operator mapped_type const &() const { return value_; }
  51. mapped_type & value() { return value_; }
  52. mapped_type const & value() const { return value_; }
  53. template <typename KS, typename = is_collection_t<KS>>
  54. self_t & operator[](KS const & keys);
  55. self_t & operator[](key_type const & key);
  56. self_t & operator[](std::initializer_list<key_type> key);
  57. template <typename KS>
  58. void insert(KS const & keys, mapped_type const & value);
  59. void insert(std::initializer_list<key_type> keys, mapped_type const & value);
  60. std::pair<iterator, bool> insert(key_type const & key, mapped_type const & value);
  61. iterator begin() { return {this}; }
  62. iterator end() { return {}; }
  63. const_iterator begin() const { return {this}; }
  64. const_iterator end() const { return {}; }
  65. const_iterator cbegin() const { return begin(); }
  66. const_iterator cend() const { return end(); }
  67. reverse_iterator rbegin() { return {this}; }
  68. reverse_iterator rend() { return {}; }
  69. const_reverse_iterator rbegin() const { return {this}; }
  70. const_reverse_iterator rend() const { return {}; }
  71. const_reverse_iterator crbegin() const { return rbegin(); }
  72. const_reverse_iterator crend() const { return rend(); }
  73. local_iterator local_begin() { return impl_.begin(); }
  74. local_iterator local_end() { return impl_.end(); }
  75. local_const_iterator local_begin() const { return impl_.begin(); }
  76. local_const_iterator local_end() const { return impl_.end(); }
  77. local_reverse_iterator local_rbegin() { return impl_.rbegin(); }
  78. local_reverse_iterator local_rend() { return impl_.rend(); }
  79. local_const_reverse_iterator local_rbegin() const { return impl_.rbegin(); }
  80. local_const_reverse_iterator local_rend() const { return impl_.rend(); }
  81. void clear();
  82. private:
  83. friend bool operator==(trie const & lhs, trie const & rhs) {
  84. auto it1 = lhs.begin(), it2 = rhs.begin(), end1 = lhs.end(), end2 = lhs.end();
  85. for ( ; it1 != end1 && it2 != end2 && it1 == it2; ++it1, ++it2 );
  86. return it1 == end1 && it2 == end2;
  87. }
  88. friend void swap(trie & lhs, trie & rhs) {
  89. using std::swap;
  90. swap(lhs.value_, rhs.value_);
  91. swap(lhs.impl_, rhs.impl_);
  92. }
  93. mapped_type value_;
  94. backing_t impl_;
  95. };
  96. #include "trie_impl.hpp"