OSDN Git Service

2006-05-17 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 May 2006 16:28:01 +0000 (16:28 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 17 May 2006 16:28:01 +0000 (16:28 +0000)
* include/tr1/hashtable (hashtable<>::m_find): Remove; update callers.

* include/tr1/hashtable (map_base<>::operator[]): Move out of line.

* include/tr1/hashtable (hashtable<>::m_insert(const value_type&,
std::tr1::false_type)): Avoid memory leak risk for new_node.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113868 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/tr1/hashtable

index db1a74e..eeea743 100644 (file)
@@ -1,3 +1,12 @@
+2006-05-17  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/tr1/hashtable (hashtable<>::m_find): Remove; update callers.
+
+       * include/tr1/hashtable (map_base<>::operator[]): Move out of line.
+
+       * include/tr1/hashtable (hashtable<>::m_insert(const value_type&,
+       std::tr1::false_type)): Avoid memory leak risk for new_node.
+
 2006-05-15  Paolo Carlini  <pcarlini@suse.de>
 
        * include/tr1/hashtable (hashtable<>::m_find, m_insert_bucket): Add.
index 9e71136..7c7c144 100644 (file)
@@ -677,18 +677,25 @@ namespace Internal
       typedef typename Pair::second_type mapped_type;
       
       mapped_type&
-      operator[](const K& k)
-      {
-       Hashtable* h = static_cast<Hashtable*>(this);
-       typename Hashtable::hash_code_t code = h->m_hash_code(k);
-       typename Hashtable::iterator it = h->m_find(k, code);
-       if (!it.m_cur_node)
-         it = h->m_insert_bucket(std::make_pair(k, mapped_type()),
-                                 it.m_cur_bucket - h->m_buckets, code);
-       return it->second;
-      }
+      operator[](const K& k);
     };
 
+  template<typename K, typename Pair, typename Hashtable>
+    typename map_base<K, Pair, extract1st<Pair>, true, Hashtable>::mapped_type&
+    map_base<K, Pair, extract1st<Pair>, true, Hashtable>::
+    operator[](const K& k)
+    {
+      Hashtable* h = static_cast<Hashtable*>(this);
+      typename Hashtable::hash_code_t code = h->m_hash_code(k);
+      std::size_t n = h->bucket_index(k, code, h->bucket_count());
+
+      typename Hashtable::node* p = h->m_find_node(h->m_buckets[n], k, code);
+      if (!p)
+       return h->m_insert_bucket(std::make_pair(k, mapped_type()),
+                                 n, code)->second;
+      return (p->m_v).second;
+    }
+
   // class template rehash_base.  Give hashtable the max_load_factor
   // functions iff the rehash policy is prime_rehash_policy.
   template<typename RehashPolicy, typename Hashtable>
@@ -1223,9 +1230,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
                                    >::type
         Insert_Conv_Type;
 
-      iterator
-      m_find(const key_type&, typename hashtable::hash_code_t) const;
-
       node*
       m_find_node(node*, const key_type&,
                  typename hashtable::hash_code_t) const;
@@ -1541,37 +1545,26 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
           bool c, bool ci, bool u>
     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
-    m_find(const key_type& k, typename hashtable::hash_code_t code) const
+    find(const key_type& k)
     {
+      typename hashtable::hash_code_t code = this->m_hash_code(k);
       std::size_t n = this->bucket_index(k, code, this->bucket_count());
       node* p = m_find_node(m_buckets[n], k, code);
-      return iterator(p, m_buckets + n);
+      return p ? iterator(p, m_buckets + n) : this->end();
     }
 
   template<typename K, typename V, 
           typename A, typename Ex, typename Eq,
           typename H1, typename H2, typename H, typename RP,
           bool c, bool ci, bool u>
-    typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
-    hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
-    find(const key_type& k)
-    {
-      typename hashtable::hash_code_t code = this->m_hash_code(k);
-      iterator i = m_find(k, code);
-      return i.m_cur_node ? i : this->end();
-    }
-  
-  template<typename K, typename V, 
-          typename A, typename Ex, typename Eq,
-          typename H1, typename H2, typename H, typename RP,
-          bool c, bool ci, bool u>
     typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
     hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
     find(const key_type& k) const
     {
       typename hashtable::hash_code_t code = this->m_hash_code(k);
-      const_iterator i = const_iterator(m_find(k, code));
-      return i.m_cur_node ? i : this->end();
+      std::size_t n = this->bucket_index(k, code, this->bucket_count());
+      node* p = m_find_node(m_buckets[n], k, code);
+      return p ? const_iterator(p, m_buckets + n) : this->end();
     }
 
   template<typename K, typename V, 
@@ -1750,8 +1743,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
       typename hashtable::hash_code_t code = this->m_hash_code(k);
       size_type n = this->bucket_index(k, code, m_bucket_count);
 
-      node* new_node = m_allocate_node(v);
+      // First find the node, avoid leaking new_node if compare throws.
       node* prev = m_find_node(m_buckets[n], k, code);
+      node* new_node = m_allocate_node(v);
+
       if (prev)
        {
          new_node->m_next = prev->m_next;