Explorar o código

Create unified insert_impl, to allow multikeys-insert to return as if a normal insert function.

Samuel Jaffe %!s(int64=8) %!d(string=hai) anos
pai
achega
495c1744a7
Modificáronse 2 ficheiros con 27 adicións e 12 borrados
  1. 5 2
      trie.hpp
  2. 22 10
      trie_impl.hpp

+ 5 - 2
trie.hpp

@@ -66,9 +66,9 @@ public:
   self_t & operator[](std::initializer_list<key_type> key);
   
   template <typename KS>
-  void insert(KS const & keys, mapped_type const & value);
-  void insert(std::initializer_list<key_type> keys, mapped_type const & value);
+  std::pair<iterator, bool> insert(KS const & keys, mapped_type const & value);
   std::pair<iterator, bool> insert(key_type const & key, mapped_type const & value);
+  std::pair<iterator, bool> insert(std::initializer_list<key_type> keys, mapped_type const & value);
   
   iterator begin() { return {this}; }
   iterator end() { return {}; }
@@ -95,6 +95,9 @@ public:
   
   void clear();
 private:
+  template <typename... Args>
+  void insert_impl(std::pair<iterator, bool> & out, key_type const & key, Args &&... args);
+  
   friend bool operator==(trie const & lhs, trie const & rhs) {
     if (lhs.value() != rhs.value()) { return false; }
     auto it1 = ++lhs.begin(), it2 = ++rhs.begin(), end1 = lhs.end(), end2 = lhs.end();

+ 22 - 10
trie_impl.hpp

@@ -81,15 +81,32 @@ auto trie<K, V, C>::operator[](std::initializer_list<key_type> keys) -> self_t &
   return operator[]<std::initializer_list<key_type>>(keys);
 }
 
+template <typename K, typename V, typename C>
+template <typename... Args>
+void trie<K, V, C>::insert_impl(std::pair<iterator, bool> & out, key_type const & key, Args &&... args) {
+  auto it = impl_.lower_bound(key);
+  if ( it == impl_.end() || key_compare()(key, it->first) ) {
+    out.second = true;
+    it = impl_.emplace_hint(it, key, make_value<self_t>(std::forward<Args>(args)...));
+  }
+  out.first.push(make_end_aware_iterator(it, impl_.end()));
+}
+
 template <typename K, typename V, typename C>
 template <typename KS>
-auto trie<K, V, C>::insert(KS const & keys, mapped_type const & value) -> void {
-  operator[](keys) = value;
+auto trie<K, V, C>::insert(KS const & keys, mapped_type const & value) -> std::pair<iterator, bool> {
+  std::pair<iterator, bool> rval{this, false};
+  auto size = std::distance(std::begin(keys), std::end(keys));
+  for ( key_type const & key : keys ) {
+    if (size-- == 1) { insert_impl(rval, key, value); }
+    else { insert_impl(rval, key); }
+  }
+  return rval;
 }
 
 template <typename K, typename V, typename C>
-auto trie<K, V, C>::insert(std::initializer_list<key_type> keys, mapped_type const & value) -> void {
-  operator[](keys) = value;
+auto trie<K, V, C>::insert(std::initializer_list<key_type> keys, mapped_type const & value) -> std::pair<iterator, bool> {
+  return insert<std::initializer_list<key_type>>(keys, value);
 }
 
 // n := total elements
@@ -98,12 +115,7 @@ auto trie<K, V, C>::insert(std::initializer_list<key_type> keys, mapped_type con
 template <typename K, typename V, typename C>
 auto trie<K, V, C>::insert(key_type const & key, mapped_type const & value) -> std::pair<iterator, bool> {
   std::pair<iterator, bool> rval{this, false};
-  auto it = impl_.lower_bound(key);
-  if ( it == impl_.end() || key_compare()(key, it->first) ) {
-    rval.second = true;
-    it = impl_.emplace_hint(it, key, make_value<self_t>(value));
-  }
-  rval.first.push(make_end_aware_iterator(it, impl_.end()));
+  insert_impl(rval, key, value);
   return rval;
 }