Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58405 - in trunk: boost/unordered boost/unordered/detail libs/unordered/doc libs/unordered/test/unordered
From: daniel_james_at_[hidden]
Date: 2009-12-15 17:53:34


Author: danieljames
Date: 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
New Revision: 58405
URL: http://svn.boost.org/trac/boost/changeset/58405

Log:
Add templated find overload for compatible keys.
Text files modified:
   trunk/boost/unordered/detail/fwd.hpp | 5 +
   trunk/boost/unordered/detail/table.hpp | 33 +++++++++
   trunk/boost/unordered/unordered_map.hpp | 40 +++++++++++
   trunk/boost/unordered/unordered_set.hpp | 19 +++++
   trunk/libs/unordered/doc/changes.qbk | 1
   trunk/libs/unordered/doc/ref.xml | 136 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/unordered/test/unordered/find_tests.cpp | 53 +++++++++++++++
   7 files changed, 287 insertions(+), 0 deletions(-)

Modified: trunk/boost/unordered/detail/fwd.hpp
==============================================================================
--- trunk/boost/unordered/detail/fwd.hpp (original)
+++ trunk/boost/unordered/detail/fwd.hpp 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -466,6 +466,9 @@
             return extractor::extract(node::get_value(n));
         }
         bool equal(key_type const& k, value_type const& v) const;
+ template <class Key, class Pred>
+ node_ptr find_iterator(bucket_ptr bucket, Key const& k,
+ Pred const&) const;
         node_ptr find_iterator(bucket_ptr bucket, key_type const& k) const;
         node_ptr find_iterator(key_type const& k) const;
         node_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const;
@@ -523,6 +526,8 @@
 
         std::size_t count(key_type const& k) const;
         iterator_base find(key_type const& k) const;
+ template <class Key, class Hash, class Pred>
+ iterator_base find(Key const& k, Hash const& h, Pred const& eq) const;
         value_type& at(key_type const& k) const;
         iterator_pair equal_range(key_type const& k) const;
 

Modified: trunk/boost/unordered/detail/table.hpp
==============================================================================
--- trunk/boost/unordered/detail/table.hpp (original)
+++ trunk/boost/unordered/detail/table.hpp 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -30,6 +30,23 @@
 
     // strong exception safety, no side effects
     template <class T>
+ template <class Key, class Pred>
+ inline BOOST_DEDUCED_TYPENAME T::node_ptr
+ hash_table<T>::find_iterator(bucket_ptr bucket, Key const& k,
+ Pred const& eq) const
+ {
+ node_ptr it = bucket->next_;
+ while (BOOST_UNORDERED_BORLAND_BOOL(it) &&
+ !eq(k, get_key(node::get_value(it))))
+ {
+ it = node::next_group(it);
+ }
+
+ return it;
+ }
+
+ // strong exception safety, no side effects
+ template <class T>
     inline BOOST_DEDUCED_TYPENAME T::node_ptr
         hash_table<T>::find_iterator(
             bucket_ptr bucket, key_type const& k) const
@@ -571,6 +588,22 @@
     }
 
     template <class T>
+ template <class Key, class Hash, class Pred>
+ BOOST_DEDUCED_TYPENAME T::iterator_base hash_table<T>::find(Key const& k,
+ Hash const& h, Pred const& eq) const
+ {
+ if(!this->size_) return this->end();
+
+ bucket_ptr bucket = this->get_bucket(h(k) % this->bucket_count_);
+ node_ptr it = find_iterator(bucket, k, eq);
+
+ if (BOOST_UNORDERED_BORLAND_BOOL(it))
+ return iterator_base(bucket, it);
+ else
+ return this->end();
+ }
+
+ template <class T>
     BOOST_DEDUCED_TYPENAME T::value_type&
         hash_table<T>::at(key_type const& k) const
     {

Modified: trunk/boost/unordered/unordered_map.hpp
==============================================================================
--- trunk/boost/unordered/unordered_map.hpp (original)
+++ trunk/boost/unordered/unordered_map.hpp 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -422,6 +422,26 @@
             return const_iterator(table_.find(k));
         }
 
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq)
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
+
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ const_iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq) const
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
+
         size_type count(const key_type& k) const
         {
             return table_.count(k);
@@ -925,6 +945,26 @@
             return const_iterator(table_.find(k));
         }
 
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq)
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
+
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ const_iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq) const
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
+
         size_type count(const key_type& k) const
         {
             return table_.count(k);

Modified: trunk/boost/unordered/unordered_set.hpp
==============================================================================
--- trunk/boost/unordered/unordered_set.hpp (original)
+++ trunk/boost/unordered/unordered_set.hpp 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -395,6 +395,15 @@
             return const_iterator(table_.find(k));
         }
 
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ const_iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq) const
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
         size_type count(const key_type& k) const
         {
             return table_.count(k);
@@ -874,6 +883,16 @@
             return const_iterator(table_.find(k));
         }
 
+ template <class CompatibleKey, class CompatibleHash,
+ class CompatiblePredicate>
+ const_iterator find(
+ CompatibleKey const& k,
+ CompatibleHash const& hash,
+ CompatiblePredicate const& eq) const
+ {
+ return iterator(table_.find(k, hash, eq));
+ }
+
         size_type count(const key_type& k) const
         {
             return table_.count(k);

Modified: trunk/libs/unordered/doc/changes.qbk
==============================================================================
--- trunk/libs/unordered/doc/changes.qbk (original)
+++ trunk/libs/unordered/doc/changes.qbk 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -111,6 +111,7 @@
   Add `erase_return_void` as a temporary workaround for the current
   `erase` which can be inefficient because it has to find the next
   element to return an iterator.
+* Add templated find overload for compatible keys.
 * [@http://svn.boost.org/trac/boost/ticket/3773 Ticket 3773]:
   Add missing `std` qualifier to `ptrdiff_t`.
 

Modified: trunk/libs/unordered/doc/ref.xml
==============================================================================
--- trunk/libs/unordered/doc/ref.xml (original)
+++ trunk/libs/unordered/doc/ref.xml 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -576,6 +576,40 @@
                 </parameter>
                 <type>const_iterator</type>
               </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>iterator</type>
+ </signature>
+ <signature cv="const">
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>const_iterator</type>
+ </signature>
               <returns>
                 <para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
               </returns>
@@ -1399,6 +1433,40 @@
                 </parameter>
                 <type>const_iterator</type>
               </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>iterator</type>
+ </signature>
+ <signature cv="const">
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>const_iterator</type>
+ </signature>
               <returns>
                 <para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
               </returns>
@@ -2236,6 +2304,40 @@
                 </parameter>
                 <type>const_iterator</type>
               </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>iterator</type>
+ </signature>
+ <signature cv="const">
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>const_iterator</type>
+ </signature>
               <returns>
                 <para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
               </returns>
@@ -3108,6 +3210,40 @@
                 </parameter>
                 <type>const_iterator</type>
               </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>iterator</type>
+ </signature>
+ <signature cv="const">
+ <template>
+ <template-type-parameter name="CompatibleKey"/>
+ <template-type-parameter name="CompatibleHash"/>
+ <template-type-parameter name="CompatiblePredicate"/>
+ </template>
+ <parameter name="k">
+ <paramtype>CompatibleKey const&amp;</paramtype>
+ </parameter>
+ <parameter name="hash">
+ <paramtype>CompatibleHash const&amp;</paramtype>
+ </parameter>
+ <parameter name="eq">
+ <paramtype>CompatiblePredicate const&amp;</paramtype>
+ </parameter>
+ <type>const_iterator</type>
+ </signature>
               <returns>
                 <para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
               </returns>

Modified: trunk/libs/unordered/test/unordered/find_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/find_tests.cpp (original)
+++ trunk/libs/unordered/test/unordered/find_tests.cpp 2009-12-15 17:53:33 EST (Tue, 15 Dec 2009)
@@ -83,6 +83,55 @@
     }
 }
 
+struct compatible_key
+{
+ test::object o_;
+
+ compatible_key(test::object const& o) : o_(o) {}
+};
+
+struct compatible_hash
+{
+ test::hash hash_;
+
+ std::size_t operator()(compatible_key const& k) const {
+ return hash_(k.o_);
+ }
+};
+
+struct compatible_predicate
+{
+ test::equal_to equal_;
+
+ bool operator()(compatible_key const& k1, compatible_key const& k2) const {
+ return equal_(k1.o_, k2.o_);
+ }
+};
+
+template <class X>
+void find_compatible_keys_test(X*, test::random_generator generator = test::default_generator)
+{
+ typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
+ typedef BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator value_iterator;
+ test::random_values<X> v(500, generator);
+ X x(v.begin(), v.end());
+
+ compatible_hash h;
+ compatible_predicate eq;
+
+ for(value_iterator it = v.begin(), end = v.end(); it != end; ++it) {
+ BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
+ BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
+ }
+
+ test::random_values<X> v2(20, generator);
+
+ for(value_iterator it = v2.begin(), end = v2.end(); it != end; ++it) {
+ BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
+ BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
+ }
+}
+
 boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
 boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
 boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
@@ -95,6 +144,10 @@
     ((test_set)(test_multiset)(test_map)(test_multimap))
     ((default_generator)(generate_collisions))
 )
+UNORDERED_TEST(find_compatible_keys_test,
+ ((test_set)(test_multiset)(test_map)(test_multimap))
+ ((default_generator)(generate_collisions))
+)
 
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk