Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-01-13 13:07:08


Author: danieljames
Date: 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
New Revision: 42728
URL: http://svn.boost.org/trac/boost/changeset/42728

Log:
Merge.
Added:
   branches/unordered/dev/boost/functional/
      - copied from r42726, /branches/unordered/trunk/boost/functional/
   branches/unordered/dev/boost/functional/detail/
      - copied from r42726, /branches/unordered/trunk/boost/functional/detail/
   branches/unordered/dev/boost/functional/hash/
      - copied from r42726, /branches/unordered/trunk/boost/functional/hash/
   branches/unordered/dev/libs/functional/hash/examples/
      - copied from r42726, /branches/unordered/trunk/libs/functional/hash/examples/
   branches/unordered/dev/libs/functional/hash/test/
      - copied from r42726, /branches/unordered/trunk/libs/functional/hash/test/
Removed:
   branches/unordered/dev/libs/unordered/test/container/
   branches/unordered/dev/libs/unordered/test/exception/assign_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/constructor_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/copy_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/erase_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/insert_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/rehash_tests.cpp
   branches/unordered/dev/libs/unordered/test/exception/swap_tests.cpp
   branches/unordered/dev/libs/unordered/test/unordered/compile_tests.cpp
Properties modified:
   branches/unordered/dev/ (props changed)
   branches/unordered/dev/doc/ (props changed)
Text files modified:
   branches/unordered/dev/boost/unordered/detail/allocator.hpp | 2
   branches/unordered/dev/boost/unordered/detail/hash_table.hpp | 10
   branches/unordered/dev/boost/unordered/detail/hash_table_impl.hpp | 52 +---
   branches/unordered/dev/boost/unordered_map.hpp | 2
   branches/unordered/dev/boost/unordered_set.hpp | 2
   branches/unordered/dev/libs/functional/hash/doc/intro.qbk | 9
   branches/unordered/dev/libs/unordered/doc/buckets.qbk | 20 +
   branches/unordered/dev/libs/unordered/doc/comparison.qbk | 14
   branches/unordered/dev/libs/unordered/doc/hash_equality.qbk | 21 +
   branches/unordered/dev/libs/unordered/doc/intro.qbk | 11 +
   branches/unordered/dev/libs/unordered/doc/rationale.qbk | 11 +
   branches/unordered/dev/libs/unordered/doc/ref.xml | 37 ++-
   branches/unordered/dev/libs/unordered/doc/src_code/point2.cpp | 2
   branches/unordered/dev/libs/unordered/test/Jamfile.v2 | 1
   branches/unordered/dev/libs/unordered/test/exception/Jamfile.v2 | 19
   branches/unordered/dev/libs/unordered/test/helpers/allocator.hpp | 15 +
   branches/unordered/dev/libs/unordered/test/helpers/equivalent.hpp | 8
   branches/unordered/dev/libs/unordered/test/helpers/generators.hpp | 7
   branches/unordered/dev/libs/unordered/test/helpers/helpers.hpp | 4
   branches/unordered/dev/libs/unordered/test/helpers/invariants.hpp | 12
   branches/unordered/dev/libs/unordered/test/helpers/metafunctions.hpp | 32 +-
   branches/unordered/dev/libs/unordered/test/helpers/random_values.hpp | 4
   branches/unordered/dev/libs/unordered/test/helpers/strong.hpp | 2
   branches/unordered/dev/libs/unordered/test/helpers/tracker.hpp | 33 +-
   branches/unordered/dev/libs/unordered/test/objects/exception.hpp | 440 ++++++++-------------------------------
   branches/unordered/dev/libs/unordered/test/objects/minimal.hpp | 35 +-
   branches/unordered/dev/libs/unordered/test/objects/test.hpp | 147 +------------
   branches/unordered/dev/libs/unordered/test/unordered/Jamfile.v2 | 7
   branches/unordered/dev/libs/unordered/test/unordered/assign_tests.cpp | 16
   branches/unordered/dev/libs/unordered/test/unordered/bucket_tests.cpp | 6
   branches/unordered/dev/libs/unordered/test/unordered/constructor_tests.cpp | 24 +-
   branches/unordered/dev/libs/unordered/test/unordered/copy_tests.cpp | 12
   branches/unordered/dev/libs/unordered/test/unordered/erase_tests.cpp | 14
   branches/unordered/dev/libs/unordered/test/unordered/find_tests.cpp | 20
   branches/unordered/dev/libs/unordered/test/unordered/insert_tests.cpp | 48 ++--
   branches/unordered/dev/libs/unordered/test/unordered/load_factor_tests.cpp | 4
   branches/unordered/dev/libs/unordered/test/unordered/rehash_tests.cpp | 2
   branches/unordered/dev/libs/unordered/test/unordered/swap_tests.cpp | 6
   branches/unordered/dev/libs/unordered/test/unordered/unnecessary_copy_tests.cpp | 69 +++---
   branches/unordered/dev/release.sh | 2
   40 files changed, 437 insertions(+), 745 deletions(-)

Modified: branches/unordered/dev/boost/unordered/detail/allocator.hpp
==============================================================================
--- branches/unordered/dev/boost/unordered/detail/allocator.hpp (original)
+++ branches/unordered/dev/boost/unordered/detail/allocator.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -207,7 +207,7 @@
                 BOOST_ASSERT(!ptr_);
                 length_ = l;
                 ptr_ = alloc_.allocate(length_);
- pointer end = ptr_ + length_;
+ pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_);
                 for(constructed_ = ptr_; constructed_ != end; ++constructed_)
                     alloc_.construct(constructed_, v);
             }

Modified: branches/unordered/dev/boost/unordered/detail/hash_table.hpp
==============================================================================
--- branches/unordered/dev/boost/unordered/detail/hash_table.hpp (original)
+++ branches/unordered/dev/boost/unordered/detail/hash_table.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -32,7 +32,7 @@
 
 #include <boost/mpl/aux_/config/eti.hpp>
 
-#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
 #define BOOST_UNORDERED_BORLAND_BOOL(x) (bool)(x)
 #else
 #define BOOST_UNORDERED_BORLAND_BOOL(x) x
@@ -48,8 +48,8 @@
     namespace unordered_detail {
         template <class T> struct type_wrapper {};
 
- const static std::size_t default_initial_bucket_count = 50;
- const static float minimum_max_load_factor = 1e-3f;
+ static const std::size_t default_initial_bucket_count = 50;
+ static const float minimum_max_load_factor = 1e-3f;
         inline std::size_t next_prime(std::size_t n);
 
         template <class T>
@@ -63,9 +63,9 @@
 #endif
         }
 
- inline std::size_t float_to_size_t(float f)
+ inline std::size_t double_to_size_t(double f)
         {
- return f > static_cast<float>((std::numeric_limits<std::size_t>::max)()) ?
+ return f >= static_cast<double>((std::numeric_limits<std::size_t>::max)()) ?
                 (std::numeric_limits<std::size_t>::max)() :
                 static_cast<std::size_t>(f);
         }

Modified: branches/unordered/dev/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- branches/unordered/dev/boost/unordered/detail/hash_table_impl.hpp (original)
+++ branches/unordered/dev/boost/unordered/detail/hash_table_impl.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -58,26 +58,8 @@
             typedef BOOST_DEDUCED_TYPENAME allocator_reference<value_allocator>::type reference;
             typedef BOOST_DEDUCED_TYPENAME allocator_reference<bucket_allocator>::type bucket_reference;
 
-#if 1
             typedef bucket_ptr link_ptr;
-#else
- // This alternative version of link_ptr is used to check that the
- // implementation is type safe wrt bucket_ptr and link_ptr.
- //
- // It's a sort of strict typedef.
 
- struct link_ptr {
- link_ptr() : ptr_() { BOOST_UNORDERED_MSVC_RESET_PTR(ptr_); }
- explicit link_ptr(bucket_ptr p) : ptr_(p) {}
- bucket_reference operator*() const { return *ptr_; }
- bucket* operator->() const { return &*ptr_; }
- operator bool() const { return ptr_; }
- bool operator==(link_ptr const& x) const { return ptr_ == x.ptr_; }
- bool operator!=(link_ptr const& x) const { return ptr_ != x.ptr_; }
- private:
- bucket_ptr ptr_;
- };
-#endif
             // Hash Bucket
             //
             // all no throw
@@ -149,7 +131,7 @@
 
                 void destroy(link_ptr ptr)
                 {
- node_ptr n(node_alloc_.address(static_cast<node&>(*ptr)));
+ node_ptr n(node_alloc_.address(*static_cast<node*>(&*ptr)));
                     value_alloc_.destroy(value_alloc_.address(n->value_));
                     node_base_alloc_.destroy(node_base_alloc_.address(*n));
                     node_alloc_.deallocate(n, 1);
@@ -242,7 +224,7 @@
 
 #if BOOST_UNORDERED_EQUIVALENT_KEYS
             static inline link_ptr& prev_in_group(link_ptr n) {
- return static_cast<node&>(*n).group_prev_;
+ return static_cast<node*>(&*n)->group_prev_;
             }
 
             // pre: Must be pointing to the first node in a group.
@@ -260,13 +242,13 @@
             // pre: Must be pointing to a node
             static inline node& get_node(link_ptr p) {
                 BOOST_ASSERT(p);
- return static_cast<node&>(*p);
+ return *static_cast<node*>(&*p);
             }
 
             // pre: Must be pointing to a node
             static inline reference get_value(link_ptr p) {
                 BOOST_ASSERT(p);
- return static_cast<node&>(*p).value_;
+ return static_cast<node*>(&*p)->value_;
             }
 
             class iterator_base
@@ -314,7 +296,7 @@
                     }
                 }
 
- void incrementGroup()
+ void increment_group()
                 {
                     node_ = data::next_group(node_);
 
@@ -434,7 +416,6 @@
                 return buckets_ + static_cast<difference_type>(bucket_count_);
             }
 
-
             iterator_base begin() const
             {
                 return size_
@@ -449,7 +430,7 @@
 
             link_ptr begin(size_type n) const
             {
- return buckets_[n].next_;
+ return (buckets_ + static_cast<difference_type>(n))->next_;
             }
 
             link_ptr end(size_type) const
@@ -1244,9 +1225,11 @@
             // no throw
             size_type max_size() const
             {
+ using namespace std;
+
                 // size < mlf_ * count
- return float_to_size_t(ceil(
- max_bucket_count() * mlf_)) - 1;
+ return double_to_size_t(ceil(
+ (double) mlf_ * max_bucket_count())) - 1;
             }
 
             // strong safety
@@ -1291,7 +1274,7 @@
                 //
                 // Or from rehash post-condition:
                 // count > size / mlf_
- return static_cast<size_type>(floor(n / mlf_)) + 1;
+ return double_to_size_t(floor(n / (double) mlf_)) + 1;
             }
 
             // no throw
@@ -1301,7 +1284,8 @@
 
                 // From 6.3.1/13:
                 // Only resize when size >= mlf_ * count
- max_load_ = float_to_size_t(ceil(mlf_ * this->bucket_count_));
+ max_load_ = double_to_size_t(ceil(
+ (double) mlf_ * this->bucket_count_));
             }
 
             // basic exception safety
@@ -1322,10 +1306,13 @@
             // factor. This is to try to avoid excessive rehashes.
             bool reserve_extra(size_type n)
             {
+ using namespace std;
+
                 bool need_to_reserve = n >= max_load_;
                 // throws - basic:
                 if (need_to_reserve) {
- rehash_impl(static_cast<size_type>(floor(n / mlf_ * 1.25)) + 1);
+ rehash_impl(double_to_size_t(floor(
+ n / (double) mlf_ * 1.25)) + 1);
                 }
                 BOOST_ASSERT(n < max_load_ || n > max_size());
                 return need_to_reserve;
@@ -1736,8 +1723,7 @@
 
                         // Create the node before rehashing in case it throws an
                         // exception (need strong safety in such a case).
- value_type const& v = *i;
- a.construct(v);
+ a.construct(*i);
 
                         // reserve has basic exception safety if the hash function
                         // throws, strong otherwise.
@@ -1823,7 +1809,7 @@
                 if (BOOST_UNORDERED_BORLAND_BOOL(it)) {
                     iterator_base first(iterator_base(bucket, it));
                     iterator_base second(first);
- second.incrementGroup();
+ second.increment_group();
                     return std::pair<iterator_base, iterator_base>(first, second);
                 }
                 else {

Modified: branches/unordered/dev/boost/unordered_map.hpp
==============================================================================
--- branches/unordered/dev/boost/unordered_map.hpp (original)
+++ branches/unordered/dev/boost/unordered_map.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -4,6 +4,8 @@
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
+// See http://www.boost.org/libs/unordered for documentation
+
 #ifndef BOOST_UNORDERED_MAP_HPP_INCLUDED
 #define BOOST_UNORDERED_MAP_HPP_INCLUDED
 

Modified: branches/unordered/dev/boost/unordered_set.hpp
==============================================================================
--- branches/unordered/dev/boost/unordered_set.hpp (original)
+++ branches/unordered/dev/boost/unordered_set.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -4,6 +4,8 @@
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
+// See http://www.boost.org/libs/unordered for documentation
+
 #ifndef BOOST_UNORDERED_SET_HPP_INCLUDED
 #define BOOST_UNORDERED_SET_HPP_INCLUDED
 

Modified: branches/unordered/dev/libs/functional/hash/doc/intro.qbk
==============================================================================
--- branches/unordered/dev/libs/functional/hash/doc/intro.qbk (original)
+++ branches/unordered/dev/libs/functional/hash/doc/intro.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -11,10 +11,14 @@
 [def __tr1__
     [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
     TR1]]
+[def __unordered__ [link unordered Boost.Unordered]]
+[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
 [def __multi-index__ [@../../libs/multi_index/doc/index.html
     Boost Multi-Index Containers Library]]
 [def __multi-index-short__ [@../../libs/multi_index/doc/index.html
     Boost.MultiIndex]]
+[def __bimap__ [@../../libs/multi_index/doc/index.html
+ Boost.MultiIndex]]
 [def __issues__
     [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
     Library Extension Technical Report Issues List]]
@@ -22,8 +26,9 @@
 [def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
 
 [classref boost::hash] is an implementation of the __hash-function__ object
-specified by the __tr1-full__ (TR1). It is intended for use as the default hash function
-for unordered associative containers, and the __multi-index__'s hash indexes.
+specified by the __tr1-full__ (TR1). It is the default hash function for
+__unordered__, __intrusive__'s unordered associative containers, and
+__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
 
 As it is compliant with __tr1__, it will work with:
 

Modified: branches/unordered/dev/libs/unordered/doc/buckets.qbk
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/buckets.qbk (original)
+++ branches/unordered/dev/libs/unordered/doc/buckets.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -20,11 +20,15 @@
 then the number of buckets, so that container applies another transformation to
 that value to choose a bucket to place the element in.
 
-Retreiving the elements for a given key is simple. The same process is applied
+Retrieving the elements for a given key is simple. The same process is applied
 to the key to find the correct bucket. Then the key is compared with the
-elements in the bucket to find any elements that match. If the hash
-function has worked well the elements will be evenly distributed amongst the
-buckets so only a small number of elements will need to be examined.
+elements in the bucket to find any elements that match (using the equality
+predicate `Pred`). If the hash function has worked well the elements will be
+evenly distributed amongst the buckets so only a small number of elements will
+need to be examined.
+
+There is [link unordered.hash_equality more information on hash functions and
+equality predicates in the next section].
 
 You can see in the diagram that `A` & `D` have been placed in the same bucket.
 When looking for elements in this bucket up to 2 comparisons are made, making
@@ -71,7 +75,7 @@
 You can also tell the container to change the bucket count (if required) by
 calling `rehash`.
 
-The standard leaves a lot of freedom to the implementor to decide how the
+The standard leaves a lot of freedom to the implementer to decide how the
 number of buckets are chosen, but it does make some requirements based on the
 container's 'load factor', the average number of elements per bucket.
 Containers also have a 'maximum load factor' which they should try to keep the
@@ -115,11 +119,15 @@
 
 ]
 
+[h2 Iterator Invalidation]
+
 It is not specified how member functions other than `rehash` affect
 the bucket count, although `insert` is only allowed to invalidate iterators
 when the insertion causes the load factor to be greater than or equal to the
 maximum load factor. For most implementations this means that insert will only
-change the number of buckets when this happens.
+change the number of buckets when this happens. While iterators can be
+invalidated by calls to `insert` and `rehash`, pointers and references to the
+container's elements are never invalidated.
 
 In a similar manner to using `reserve` for `vector`s, it can be a good idea
 to call `rehash` before inserting a large number of elements. This will get

Modified: branches/unordered/dev/libs/unordered/doc/comparison.qbk
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/comparison.qbk (original)
+++ branches/unordered/dev/libs/unordered/doc/comparison.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -50,8 +50,11 @@
         [`iterator`, `const_iterator` are of at least the forward category.]
     ]
     [
- [Inserts do not invalidate iterators or references to the container.]
- [Inserts can invalidate iterators but not references to the container.]
+ [Iterators, pointers and references to the container's elements are
+ never invalidated.]
+ [[link unordered.buckets.iterator_invalidation Iterators can
+ be invalidated by calls to insert or rehash]. Pointers and
+ references to the container's elements are never invalidated.]
     ]
     [
         [Iterators iterate through the container in the order defined by
@@ -67,8 +70,11 @@
             required to have any correspondence.)]
     ]
     [
- [Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators]
- [No comparison operators are defined]
+ [Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators.]
+ [No comparison operators are defined in the standard, although
+ [link unordered.rationale.equality_operator
+ implementations might extend the containers to support `==` and
+ `!=`].]
     ]
     [
         []

Modified: branches/unordered/dev/libs/unordered/doc/hash_equality.qbk
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/hash_equality.qbk (original)
+++ branches/unordered/dev/libs/unordered/doc/hash_equality.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -26,15 +26,15 @@
 An example implementation of FNV-1, and some other hash functions are supplied
 in the examples directory.
 
-Alternatively, you might wish to use a different equality function. If so, make
-sure you use a hash function that matches it. So to implement a
+Alternatively, you might wish to use a different equality function. If you do
+this you will need to use a hash function that matches it. So to implement a
 case-insensitive dictionary:
 
-[import src_code/insensitive.cpp]
-[case_insensitive_functions]
-[case_insensitive_dictionary]
+[import src_code/insensitive.cpp]
+[case_insensitive_functions]
+[case_insensitive_dictionary]
 
-This is a simplified version of the example at:
+This is a simplified version of the example at
 [@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
 which supports other locales and string types.
 
@@ -45,14 +45,15 @@
 [import src_code/point1.cpp]
 [point_example1]
 
-Although, customizing Boost.Hash is probably a better solution:
+Although, [link hash.custom extending boost::hash to support the type] is
+probably a better solution:
 
 [import src_code/point2.cpp]
 [point_example2]
 
-See the Boost.Hash documentation for more detail on how to do this. Remember
-that it relies on extensions to the draft standard - so it won't work on other
-implementations of the unordered associative containers.
+See the [link hash.custom Boost.Hash documentation] for more detail on how to
+do this. Remember that it relies on extensions to the draft standard - so it
+won't work on other implementations of the unordered associative containers.
 
 [table Methods for accessing the hash and equality functions.
     [[Method] [Description]]

Modified: branches/unordered/dev/libs/unordered/doc/intro.qbk
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/intro.qbk (original)
+++ branches/unordered/dev/libs/unordered/doc/intro.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -111,6 +111,17 @@
     three,3
     missing,0
 
+To store an object in an unordered associative container requires both an
+key equality function and a hash function. The default function objects in
+the standard containers support a few basic types including integer types,
+floating point types, pointer types, and the standard strings. Since
+Boost.Unordered uses [classref boost::hash] it also supports some other types,
+including standard containers. To use any types not supported by these methods
+you have to [link hash.custom extend Boost.Hash to support the type] or use
+your own custom equality predicates and hash functions. See the
+[link unordered.hash_equality Equality Predicates and Hash Functions] section
+for more details.
+
 There are other differences, which are listed in the
 [link unordered.comparison Comparison with Associative Containers] section.
 

Modified: branches/unordered/dev/libs/unordered/doc/rationale.qbk
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/rationale.qbk (original)
+++ branches/unordered/dev/libs/unordered/doc/rationale.qbk 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -198,4 +198,15 @@
 new constructors in `std::pair`. But partial support is possible - especially
 if I don't use the `construct` member of allocators.
 
+[h3 Equality operator]
+
+While `operator==` and `operator!=` are not included in the standard, it's
+possible to implement them for all the containers - this is helped by having
+stable order of elements with equivalent keys. They will need to be specified
+differently to the standard associative containers, probably comparing keys
+using the equality predicate rather than `operator==`. This is inconsistent
+with the other containers but it is probably closer to user's expectations.
+
+If these are added then a `hash_value` free function should also be added.
+
 [endsect]

Modified: branches/unordered/dev/libs/unordered/doc/ref.xml
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/ref.xml (original)
+++ branches/unordered/dev/libs/unordered/doc/ref.xml 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -270,6 +270,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -293,6 +294,7 @@
               <notes>
                 <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -315,6 +317,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="erase">
@@ -388,7 +391,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </method>
@@ -584,7 +587,7 @@
               <type>void</type>
               <description>
                 <para>Changes the number of buckets so that there at least <code>n</code> buckets, and so that the load factor is less than the maximum load factor.</para>
- <para>Invalidates iterators, and changes the order of elements</para>
+ <para>Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.</para>
               </description>
               <throws>
                 <para>The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.</para>
@@ -682,7 +685,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </function>
@@ -946,6 +949,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -969,6 +973,7 @@
               <notes>
                 <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -991,6 +996,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="erase">
@@ -1064,7 +1070,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </method>
@@ -1260,7 +1266,7 @@
               <type>void</type>
               <description>
                 <para>Changes the number of buckets so that there at least <code>n</code> buckets, and so that the load factor is less than the maximum load factor.</para>
- <para>Invalidates iterators, and changes the order of elements</para>
+ <para>Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.</para>
               </description>
               <throws>
                 <para>The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.</para>
@@ -1358,7 +1364,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </function>
@@ -1639,6 +1645,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -1662,6 +1669,7 @@
               <notes>
                 <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -1684,6 +1692,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="erase">
@@ -1757,7 +1766,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </method>
@@ -1837,6 +1846,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <overloaded-method name="at">
@@ -1987,7 +1997,7 @@
               <type>void</type>
               <description>
                 <para>Changes the number of buckets so that there at least <code>n</code> buckets, and so that the load factor is less than the maximum load factor.</para>
- <para>Invalidates iterators, and changes the order of elements</para>
+ <para>Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.</para>
               </description>
               <throws>
                 <para>The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.</para>
@@ -2093,7 +2103,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </function>
@@ -2365,6 +2375,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -2388,6 +2399,7 @@
               <notes>
                 <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="insert">
@@ -2410,6 +2422,7 @@
               </throws>
               <notes>
                 <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
               </notes>
             </method>
             <method name="erase">
@@ -2483,7 +2496,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>key_equal</code> or <code>hasher</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </method>
@@ -2679,7 +2692,7 @@
               <type>void</type>
               <description>
                 <para>Changes the number of buckets so that there at least <code>n</code> buckets, and so that the load factor is less than the maximum load factor.</para>
- <para>Invalidates iterators, and changes the order of elements</para>
+ <para>Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.</para>
               </description>
               <throws>
                 <para>The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.</para>
@@ -2785,7 +2798,7 @@
                 <para>If the allocators are equal, doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of <code>Hash</code> or <code>Pred</code>.</para>
               </throws>
               <notes>
- <para>For a discussion of the behaviour when allocators aren't equal see
+ <para>For a discussion of the behavior when allocators aren't equal see
                   <link linkend="unordered.rationale.swapping_containers_with_unequal_allocators">the implementation details</link>.</para>
               </notes>
             </function>

Modified: branches/unordered/dev/libs/unordered/doc/src_code/point2.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/doc/src_code/point2.cpp (original)
+++ branches/unordered/dev/libs/unordered/doc/src_code/point2.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -25,7 +25,7 @@
         return seed;
     }
 
- // Now the default functions work.
+ // Now the default function objects work.
     boost::unordered_multiset<point> points;
 //]
 

Modified: branches/unordered/dev/libs/unordered/test/Jamfile.v2
==============================================================================
--- branches/unordered/dev/libs/unordered/test/Jamfile.v2 (original)
+++ branches/unordered/dev/libs/unordered/test/Jamfile.v2 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -3,6 +3,5 @@
 # Distributed under the Boost Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-build-project container ;
 build-project unordered ;
 build-project exception ;

Modified: branches/unordered/dev/libs/unordered/test/exception/Jamfile.v2
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/Jamfile.v2 (original)
+++ branches/unordered/dev/libs/unordered/test/exception/Jamfile.v2 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -5,7 +5,8 @@
 
 import testing ;
 
-alias framework : /boost/test//boost_unit_test_framework ;
+#alias framework : /boost/test//boost_unit_test_framework ;
+alias framework : ;
 
 project unordered-test/exception-tests
     : requirements
@@ -13,14 +14,14 @@
         <toolset>gcc:<cxxflags>-Wsign-promo
     ;
 
-test-suite unordered-tests
+test-suite unordered-exception
     :
- [ run constructor_tests.cpp framework ]
- [ run copy_tests.cpp framework ]
- [ run assign_tests.cpp framework ]
- [ run insert_tests.cpp framework ]
- [ run erase_tests.cpp framework ]
- [ run rehash_tests.cpp framework ]
- [ run swap_tests.cpp framework : : :
+ [ run constructor_exception_tests.cpp framework ]
+ [ run copy_exception_tests.cpp framework ]
+ [ run assign_exception_tests.cpp framework ]
+ [ run insert_exception_tests.cpp framework ]
+ [ run erase_exception_tests.cpp framework ]
+ [ run rehash_exception_tests.cpp framework ]
+ [ run swap_exception_tests.cpp framework : : :
             <define>BOOST_UNORDERED_SWAP_METHOD=2 ]
     ;

Deleted: branches/unordered/dev/libs/unordered/test/exception/assign_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/assign_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,81 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include "../helpers/random_values.hpp"
-#include "../helpers/invariants.hpp"
-
-test::seed_t seed(12847);
-
-template <class T>
-struct self_assign_base : public test::exception_base
-{
- test::random_values<T> values;
- self_assign_base(int count = 0) : values(count) {}
-
- typedef T data_type;
- T init() const { return T(values.begin(), values.end()); }
- void run(T& x) const { x = x; }
- void check(T const& x) const { test::check_equivalent_keys(x); }
-};
-
-template <class T>
-struct self_assign_test1 : self_assign_base<T> {};
-
-template <class T>
-struct self_assign_test2 : self_assign_base<T>
-{
- self_assign_test2() : self_assign_base<T>(100) {}
-};
-
-template <class T>
-struct assign_base : public test::exception_base
-{
- const test::random_values<T> x_values, y_values;
- const T x,y;
-
- assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
- : x_values(count1), y_values(count2),
- x(x_values.begin(), x_values.end(), 0, typename T::hasher(tag1), typename T::key_equal(tag1), typename T::allocator_type(tag1)),
- y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2), typename T::key_equal(tag2), typename T::allocator_type(tag2)) {}
-
- typedef T data_type;
- T init() const { return T(x); }
- void run(T& x1) const { x1 = y; }
- void check(T const& x1) const { test::check_equivalent_keys(x1); }
-};
-
-template <class T>
-struct assign_test1 : assign_base<T>
-{
- assign_test1() : assign_base<T>(0, 0, 0, 0) {}
-};
-
-template <class T>
-struct assign_test2 : assign_base<T>
-{
- assign_test2() : assign_base<T>(60, 0, 0, 0) {}
-};
-
-template <class T>
-struct assign_test3 : assign_base<T>
-{
- assign_test3() : assign_base<T>(0, 60, 0, 0) {}
-};
-
-template <class T>
-struct assign_test4 : assign_base<T>
-{
- assign_test4() : assign_base<T>(10, 10, 1, 2) {}
-};
-
-RUN_EXCEPTION_TESTS(
- (self_assign_test1)(self_assign_test2)
- (assign_test1)(assign_test2)(assign_test3)(assign_test4),
- CONTAINER_SEQ)

Deleted: branches/unordered/dev/libs/unordered/test/exception/constructor_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/constructor_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,133 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include "../helpers/random_values.hpp"
-#include "../helpers/input_iterator.hpp"
-
-test::seed_t seed(91274);
-
-struct objects
-{
- test::exception::object obj;
- test::exception::hash hash;
- test::exception::equal_to equal_to;
- test::exception::allocator<test::exception::object> allocator;
-};
-
-template <class T>
-struct construct_test1 : public objects, test::exception_base
-{
- void run() const {
- T x;
- }
-};
-
-template <class T>
-struct construct_test2 : public objects, test::exception_base
-{
- void run() const {
- T x(300);
- }
-};
-
-template <class T>
-struct construct_test3 : public objects, test::exception_base
-{
- void run() const {
- T x(0, hash);
- }
-};
-
-template <class T>
-struct construct_test4 : public objects, test::exception_base
-{
- void run() const {
- T x(0, hash, equal_to);
- }
-};
-
-template <class T>
-struct construct_test5 : public objects, test::exception_base
-{
- void run() const {
- T x(50, hash, equal_to, allocator);
- }
-};
-
-template <class T>
-struct range : public test::exception_base
-{
- test::random_values<T> values;
-
- range() : values(5) {}
- range(unsigned int count) : values(count) {}
-};
-
-template <class T>
-struct range_construct_test1 : public range<T>, objects
-{
- void run() const {
- T x(this->values.begin(), this->values.end());
- }
-};
-
-template <class T>
-struct range_construct_test2 : public range<T>, objects
-{
- void run() const {
- T x(this->values.begin(), this->values.end(), 0);
- }
-};
-
-template <class T>
-struct range_construct_test3 : public range<T>, objects
-{
- void run() const {
- T x(this->values.begin(), this->values.end(), 0, hash);
- }
-};
-
-template <class T>
-struct range_construct_test4 : public range<T>, objects
-{
- void run() const {
- T x(this->values.begin(), this->values.end(), 100, hash, equal_to);
- }
-};
-
-// Need to run at least one test with a fairly large number
-// of objects in case it triggers a rehash.
-template <class T>
-struct range_construct_test5 : public range<T>, objects
-{
- range_construct_test5() : range<T>(60) {}
-
- void run() const {
- T x(this->values.begin(), this->values.end(), 0, hash, equal_to, allocator);
- }
-};
-
-template <class T>
-struct input_range_construct_test : public range<T>, objects
-{
- input_range_construct_test() : range<T>(60) {}
-
- void run() const {
- T x(test::input_iterator(this->values.begin()),
- test::input_iterator(this->values.end()),
- 0, hash, equal_to, allocator);
- }
-};
-
-RUN_EXCEPTION_TESTS(
- (construct_test1)(construct_test2)(construct_test3)(construct_test4)(construct_test5)
- (range_construct_test1)(range_construct_test2)(range_construct_test3)(range_construct_test4)(range_construct_test5)
- (input_range_construct_test),
- CONTAINER_SEQ)

Deleted: branches/unordered/dev/libs/unordered/test/exception/copy_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/copy_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,53 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include "../helpers/random_values.hpp"
-
-test::seed_t seed(73041);
-
-template <class T>
-struct copy_test1 : public test::exception_base
-{
- T x;
-
- void run() const {
- T y(x);
- }
-};
-
-template <class T>
-struct copy_test2 : public test::exception_base
-{
- test::random_values<T> values;
- T x;
-
- copy_test2() : values(5), x(values.begin(), values.end()) {}
-
- void run() const {
- T y(x);
- }
-};
-
-template <class T>
-struct copy_test3 : public test::exception_base
-{
- test::random_values<T> values;
- T x;
-
- copy_test3() : values(100), x(values.begin(), values.end()) {}
-
- void run() const {
- T y(x);
- }
-};
-
-RUN_EXCEPTION_TESTS(
- (copy_test1)(copy_test2)(copy_test3),
- CONTAINER_SEQ)

Deleted: branches/unordered/dev/libs/unordered/test/exception/erase_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/erase_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,57 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include "../helpers/random_values.hpp"
-#include "../helpers/invariants.hpp"
-#include "../helpers/helpers.hpp"
-
-test::seed_t seed(835193);
-
-template <class T>
-struct erase_test_base : public test::exception_base
-{
- test::random_values<T> values;
- erase_test_base(unsigned int count = 5) : values(count) {}
-
- typedef T data_type;
-
- data_type init() const {
- return T(values.begin(), values.end());
- }
-
- void check(T const& x) const {
- std::string scope(test::scope);
-
- HASH_CHECK(scope.find("hash::") != std::string::npos ||
- scope.find("equal_to::") != std::string::npos ||
- scope == "operator==(object, object)");
-
- test::check_equivalent_keys(x);
- }
-};
-
-template <class T>
-struct erase_by_key_test1 : public erase_test_base<T>
-{
- void run(T& x) const
- {
- typedef typename test::random_values<T>::const_iterator iterator;
-
- for(iterator it = this->values.begin(), end = this->values.end();
- it != end; ++it)
- {
- x.erase(test::get_key<T>(*it));
- }
- }
-};
-
-RUN_EXCEPTION_TESTS(
- (erase_by_key_test1),
- CONTAINER_SEQ)

Deleted: branches/unordered/dev/libs/unordered/test/exception/insert_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/insert_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,212 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include <string>
-#include "../helpers/random_values.hpp"
-#include "../helpers/invariants.hpp"
-#include "../helpers/strong.hpp"
-#include "../helpers/input_iterator.hpp"
-
-#include <cmath>
-
-test::seed_t seed(747373);
-
-template <class T>
-struct insert_test_base : public test::exception_base
-{
- test::random_values<T> values;
- insert_test_base(unsigned int count = 5) : values(count) {}
-
- typedef T data_type;
- typedef test::strong<T> strong_type;
-
- data_type init() const {
- return T();
- }
-
- void check(T const& x, strong_type const& strong) const {
- std::string scope(test::scope);
-
- if(scope.find("hash::operator()") == std::string::npos)
- strong.test(x);
- test::check_equivalent_keys(x);
- }
-};
-
-template <class T>
-struct insert_test1 : public insert_test_base<T>
-{
- typedef typename insert_test_base<T>::strong_type strong_type;
-
- void run(T& x, strong_type& strong) const {
- for(typename test::random_values<T>::const_iterator
- it = this->values.begin(), end = this->values.end(); it != end; ++it)
- {
- strong.store(x);
- x.insert(*it);
- }
- }
-};
-
-template <class T>
-struct insert_test2 : public insert_test_base<T>
-{
- typedef typename insert_test_base<T>::strong_type strong_type;
-
- void run(T& x, strong_type& strong) const {
- for(typename test::random_values<T>::const_iterator
- it = this->values.begin(), end = this->values.end(); it != end; ++it)
- {
- strong.store(x);
- x.insert(x.begin(), *it);
- }
- }
-};
-
-template <class T>
-struct insert_test3 : public insert_test_base<T>
-{
- void run(T& x) const {
- x.insert(this->values.begin(), this->values.end());
- }
-
- void check(T const& x) const {
- test::check_equivalent_keys(x);
- }
-};
-
-template <class T>
-struct insert_test4 : public insert_test_base<T>
-{
- typedef typename insert_test_base<T>::strong_type strong_type;
-
- void run(T& x, strong_type& strong) const {
- for(typename test::random_values<T>::const_iterator
- it = this->values.begin(), end = this->values.end(); it != end; ++it)
- {
- strong.store(x);
- x.insert(it, boost::next(it));
- }
- }
-};
-
-template <class T>
-struct insert_test_rehash1 : public insert_test_base<T>
-{
- typedef typename insert_test_base<T>::strong_type strong_type;
-
- insert_test_rehash1() : insert_test_base<T>(1000) {}
-
- T init() const {
- typedef typename T::size_type size_type;
-
- T x;
- x.max_load_factor(0.25);
- size_type bucket_count = x.bucket_count();
- size_type initial_elements = static_cast<size_type>(
- std::ceil(bucket_count * x.max_load_factor()) - 1);
- BOOST_REQUIRE(initial_elements < this->values.size());
- x.insert(this->values.begin(),
- boost::next(this->values.begin(), initial_elements));
- BOOST_REQUIRE(bucket_count == x.bucket_count());
- return x;
- }
-
- void run(T& x, strong_type& strong) const {
- typename T::size_type bucket_count = x.bucket_count();
- int count = 0;
- typename T::const_iterator pos = x.cbegin();
-
- for(typename test::random_values<T>::const_iterator
- it = boost::next(this->values.begin(), x.size()), end = this->values.end();
- it != end && count < 10; ++it, ++count)
- {
- strong.store(x);
- pos = x.insert(pos, *it);
- }
-
- // This isn't actually a failure, but it means the test isn't doing its
- // job.
- BOOST_REQUIRE(x.bucket_count() != bucket_count);
- }
-};
-
-template <class T>
-struct insert_test_rehash2 : public insert_test_rehash1<T>
-{
- typedef typename insert_test_base<T>::strong_type strong_type;
-
- void run(T& x, strong_type& strong) const {
- typename T::size_type bucket_count = x.bucket_count();
- int count = 0;
-
- for(typename test::random_values<T>::const_iterator
- it = boost::next(this->values.begin(), x.size()), end = this->values.end();
- it != end && count < 10; ++it, ++count)
- {
- strong.store(x);
- x.insert(*it);
- }
-
- // This isn't actually a failure, but it means the test isn't doing its
- // job.
- BOOST_REQUIRE(x.bucket_count() != bucket_count);
- }
-};
-
-template <class T>
-struct insert_test_rehash3 : public insert_test_base<T>
-{
- typename T::size_type mutable rehash_bucket_count, original_bucket_count;
-
- insert_test_rehash3() : insert_test_base<T>(1000) {}
-
- T init() const {
- typedef typename T::size_type size_type;
-
- T x;
- x.max_load_factor(0.25);
-
- original_bucket_count = x.bucket_count();
- rehash_bucket_count = static_cast<size_type>(
- std::ceil(original_bucket_count * x.max_load_factor())) - 1;
-
- size_type initial_elements = rehash_bucket_count - 5;
-
- BOOST_REQUIRE(initial_elements < this->values.size());
- x.insert(this->values.begin(),
- boost::next(this->values.begin(), initial_elements));
- BOOST_REQUIRE(original_bucket_count == x.bucket_count());
- return x;
- }
-
- void run(T& x) const {
- typename T::size_type bucket_count = x.bucket_count();
-
- x.insert(boost::next(this->values.begin(), x.size()),
- boost::next(this->values.begin(), x.size() + 20));
-
- // This isn't actually a failure, but it means the test isn't doing its
- // job.
- BOOST_REQUIRE(x.bucket_count() != bucket_count);
- }
-
- void check(T const& x) const {
- if(x.size() < rehash_bucket_count) {
- //BOOST_CHECK(x.bucket_count() == original_bucket_count);
- }
- test::check_equivalent_keys(x);
- }
-};
-
-RUN_EXCEPTION_TESTS(
- (insert_test1)(insert_test2)(insert_test3)(insert_test4)
- (insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3),
- CONTAINER_SEQ)

Deleted: branches/unordered/dev/libs/unordered/test/exception/rehash_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/rehash_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,85 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include <string>
-#include "../helpers/random_values.hpp"
-#include "../helpers/invariants.hpp"
-#include "../helpers/strong.hpp"
-
-#include <iostream>
-
-test::seed_t seed(3298597);
-
-template <class T>
-struct rehash_test_base : public test::exception_base
-{
- test::random_values<T> values;
- unsigned int n;
- rehash_test_base(unsigned int count = 100, unsigned int n = 0) : values(count), n(n) {}
-
- typedef T data_type;
- typedef test::strong<T> strong_type;
-
- data_type init() const {
- T x(values.begin(), values.end(), n);
- return x;
- }
-
- void check(T const& x, strong_type const& strong) const {
- std::string scope(test::scope);
-
- if(scope.find("hash::operator()") == std::string::npos &&
- scope.find("equal_to::operator()") == std::string::npos &&
- scope != "operator==(object, object)")
- strong.test(x);
-
- test::check_equivalent_keys(x);
- }
-};
-
-template <class T>
-struct rehash_test0 : rehash_test_base<T>
-{
- rehash_test0() : rehash_test_base<T>(0) {}
- void run(T& x) const { x.rehash(0); }
-};
-
-template <class T>
-struct rehash_test1 : rehash_test_base<T>
-{
- rehash_test1() : rehash_test_base<T>(0) {}
- void run(T& x) const { x.rehash(200); }
-};
-
-template <class T>
-struct rehash_test2 : rehash_test_base<T>
-{
- rehash_test2() : rehash_test_base<T>(0, 200) {}
- void run(T& x) const { x.rehash(0); }
-};
-
-template <class T>
-struct rehash_test3 : rehash_test_base<T>
-{
- rehash_test3() : rehash_test_base<T>(10, 0) {}
- void run(T& x) const { x.rehash(200); }
-};
-
-template <class T>
-struct rehash_test4 : rehash_test_base<T>
-{
- rehash_test4() : rehash_test_base<T>(10, 200) {}
- void run(T& x) const { x.rehash(0); }
-};
-
-RUN_EXCEPTION_TESTS(
- (rehash_test0)(rehash_test1)(rehash_test2)(rehash_test3)(rehash_test4),
- CONTAINER_SEQ)
-

Deleted: branches/unordered/dev/libs/unordered/test/exception/swap_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/exception/swap_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,119 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include "./containers.hpp"
-
-#define BOOST_TEST_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/exception_safety.hpp>
-#include "../helpers/random_values.hpp"
-#include "../helpers/invariants.hpp"
-
-test::seed_t seed(9387);
-
-template <class T>
-struct self_swap_base : public test::exception_base
-{
- test::random_values<T> values;
- self_swap_base(int count = 0) : values(count) {}
-
- typedef T data_type;
- T init() const { return T(values.begin(), values.end()); }
- void run(T& x) const { x.swap(x); }
- void check(T const& x) const {
- std::string scope(test::scope);
-
-#if BOOST_UNORDERED_SWAP_METHOD != 2
- HASH_CHECK(
- scope == "hash::operator(hash)" ||
- scope == "hash::operator=(hash)" ||
- scope == "equal_to::operator(equal_to)" ||
- scope == "equal_to::operator=(equal_to)");
-#endif
-
- test::check_equivalent_keys(x);
- }
-};
-
-template <class T>
-struct self_swap_test1 : self_swap_base<T> {};
-
-template <class T>
-struct self_swap_test2 : self_swap_base<T>
-{
- self_swap_test2() : self_swap_base<T>(100) {}
-};
-
-template <class T>
-struct swap_base : public test::exception_base
-{
- const test::random_values<T> x_values, y_values;
- const T initial_x, initial_y;
-
- swap_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
- : x_values(count1), y_values(count2),
- initial_x(x_values.begin(), x_values.end(), 0, typename T::hasher(tag1),
- typename T::key_equal(tag1), typename T::allocator_type(tag1)),
- initial_y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2),
- typename T::key_equal(tag2), typename T::allocator_type(tag2))
- {}
-
- struct data_type {
- data_type(T const& x, T const& y)
- : x(x), y(y) {}
-
- T x, y;
- };
-
- data_type init() const { return data_type(initial_x, initial_y); }
- void run(data_type& d) const {
- try {
- d.x.swap(d.y);
- } catch (std::runtime_error) {}
- }
- void check(data_type const& d) const {
- std::string scope(test::scope);
-
-#if BOOST_UNORDERED_SWAP_METHOD != 2
- HASH_CHECK(
- scope == "hash::operator(hash)" ||
- scope == "hash::operator=(hash)" ||
- scope == "equal_to::operator(equal_to)" ||
- scope == "equal_to::operator=(equal_to)");
-#endif
-
- test::check_equivalent_keys(d.x);
- test::check_equivalent_keys(d.y);
- }
-};
-
-template <class T>
-struct swap_test1 : swap_base<T>
-{
- swap_test1() : swap_base<T>(0, 0, 0, 0) {}
-};
-
-template <class T>
-struct swap_test2 : swap_base<T>
-{
- swap_test2() : swap_base<T>(60, 0, 0, 0) {}
-};
-
-template <class T>
-struct swap_test3 : swap_base<T>
-{
- swap_test3() : swap_base<T>(0, 60, 0, 0) {}
-};
-
-template <class T>
-struct swap_test4 : swap_base<T>
-{
- swap_test4() : swap_base<T>(10, 10, 1, 2) {}
-};
-
-RUN_EXCEPTION_TESTS(
- (self_swap_test1)(self_swap_test2)
- (swap_test1)(swap_test2)(swap_test3)(swap_test4),
- CONTAINER_SEQ)

Modified: branches/unordered/dev/libs/unordered/test/helpers/allocator.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/allocator.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/allocator.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -38,11 +38,22 @@
         const_pointer address(const_reference r) { return &r; }
 
         pointer allocate(size_type n) {
+ using namespace std;
             return static_cast<T*>(malloc(n * sizeof(T)));
         }
 
         pointer allocate(size_type n, const_pointer u) { return allocate(n); }
- void deallocate(pointer p, size_type) { free(p); }
+
+#if defined(__IBMCPP__)
+ // Workaround for IBM Visual Age which seems to use a void pointer
+ // for the second argument.
+ pointer allocate(size_type n, void const* u) { return allocate(n); }
+#endif
+
+ void deallocate(pointer p, size_type) {
+ using namespace std;
+ free(p);
+ }
         void construct(pointer p, T const& t) { new(p) T(t); }
         void destroy(pointer p) { p->~T(); }
 
@@ -55,9 +66,11 @@
 
 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
         template <class T> void deallocate(T* p, size_type) {
+ using namespace std;
             free(p);
         }
         char* _Charalloc(size_type n) {
+ using namespace std;
             return static_cast<char*>(malloc(n * sizeof(char)));
         }
 #endif

Modified: branches/unordered/dev/libs/unordered/test/helpers/equivalent.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/equivalent.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/equivalent.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -51,12 +51,12 @@
     template <class Container>
     class unordered_equivalence_tester
     {
- typename Container::size_type size_;
- typename Container::hasher hasher_;
- typename Container::key_equal key_equal_;
+ BOOST_DEDUCED_TYPENAME Container::size_type size_;
+ BOOST_DEDUCED_TYPENAME Container::hasher hasher_;
+ BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_;
         float max_load_factor_;
 
- typedef typename non_const_value_type<Container>::type value_type;
+ typedef BOOST_DEDUCED_TYPENAME non_const_value_type<Container>::type value_type;
         std::vector<value_type> values_;
     public:
         unordered_equivalence_tester(Container const &x)

Modified: branches/unordered/dev/libs/unordered/test/helpers/generators.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/generators.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/generators.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -15,6 +15,7 @@
 #include <utility>
 #include <stdexcept>
 #include <cstdlib>
+#include <boost/type_traits/add_const.hpp>
 
 #include "./fwd.hpp"
 
@@ -43,9 +44,10 @@
     struct generator
     {
         typedef T value_type;
- value_type operator()()
+ typedef BOOST_DEDUCED_TYPENAME boost::add_const<T>::type const_value_type;
+ value_type operator()() const
         {
- return generate((T const*) 0);
+ return generate((const_value_type*) 0);
         }
     };
 
@@ -84,6 +86,7 @@
 
     float generate(float const*)
     {
+ using namespace std;
         return (float) rand() / (float) RAND_MAX;
     }
 }

Modified: branches/unordered/dev/libs/unordered/test/helpers/helpers.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/helpers.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/helpers.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -11,7 +11,7 @@
     template <class Container>
     struct get_key_impl
     {
- typedef typename Container::key_type key_type;
+ typedef BOOST_DEDUCED_TYPENAME Container::key_type key_type;
 
         static key_type const& get_key(key_type const& x)
         {
@@ -32,7 +32,7 @@
     };
     
     template <class Container, class T>
- inline typename Container::key_type const& get_key(T const& x)
+ inline BOOST_DEDUCED_TYPENAME Container::key_type const& get_key(T const& x)
     {
         return get_key_impl<Container>::get_key(x);
     }

Modified: branches/unordered/dev/libs/unordered/test/helpers/invariants.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/invariants.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/invariants.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -25,14 +25,14 @@
     template <class X>
     void check_equivalent_keys(X const& x1)
     {
- typename X::key_equal eq = x1.key_eq();
- typedef typename X::key_type key_type;
+ BOOST_DEDUCED_TYPENAME X::key_equal eq = x1.key_eq();
+ typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
         // Boost.Test was reporting memory leaks for std::set on g++-3.3.
         // So I work around it by using malloc.
         std::set<key_type, std::less<key_type>, test::malloc_allocator<key_type> > found_;
 
- typename X::const_iterator it = x1.begin(), end = x1.end();
- typename X::size_type size = 0;
+ BOOST_DEDUCED_TYPENAME X::const_iterator it = x1.begin(), end = x1.end();
+ BOOST_DEDUCED_TYPENAME X::size_type size = 0;
         while(it != end) {
             // First test that the current key has not occured before, required
             // to test either that keys are unique or that equivalent keys are
@@ -70,8 +70,8 @@
 
             // // Check that the keys are in the correct bucket and are
             // // adjacent in the bucket.
- // typename X::size_type bucket = x1.bucket(key);
- // typename X::const_local_iterator lit = x1.begin(bucket), lend = x1.end(bucket);
+ // BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key);
+ // BOOST_DEDUCED_TYPENAME X::const_local_iterator lit = x1.begin(bucket), lend = x1.end(bucket);
             // for(; lit != lend && !eq(get_key<X>(*lit), key); ++lit) continue;
             // if(lit == lend)
             // BOOST_ERROR("Unable to find element with a local_iterator");

Modified: branches/unordered/dev/libs/unordered/test/helpers/metafunctions.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/metafunctions.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/metafunctions.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -8,10 +8,11 @@
 
 #include <boost/config.hpp>
 #include <boost/type_traits/is_same.hpp>
-#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/mpl/not.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/apply.hpp>
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
 
@@ -40,8 +41,8 @@
     template <class Container>
     struct is_set
         : public boost::is_same<
- typename Container::key_type,
- typename Container::value_type> {};
+ BOOST_DEDUCED_TYPENAME Container::key_type,
+ BOOST_DEDUCED_TYPENAME Container::value_type> {};
 
     template <class Container>
     struct is_map
@@ -81,20 +82,29 @@
 
     // Non Const Value Type
 
- template <class Container>
     struct map_non_const_value_type
     {
- typedef std::pair<
- typename Container::key_type,
- typename Container::mapped_type> type;
+ template <class Container>
+ struct apply {
+ typedef std::pair<
+ BOOST_DEDUCED_TYPENAME Container::key_type,
+ BOOST_DEDUCED_TYPENAME Container::mapped_type> type;
+ };
     };
 
-
+ struct set_non_const_value_type
+ {
+ template <class Container>
+ struct apply {
+ typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
+ };
+ };
+
     template <class Container>
     struct non_const_value_type
- : boost::mpl::eval_if<is_map<Container>,
- map_non_const_value_type<Container>,
- boost::mpl::identity<typename Container::value_type> >
+ : boost::mpl::apply1<
+ BOOST_DEDUCED_TYPENAME boost::mpl::if_<is_map<Container>, map_non_const_value_type, set_non_const_value_type>::type,
+ Container>
     {
     };
 }

Modified: branches/unordered/dev/libs/unordered/test/helpers/random_values.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/random_values.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/random_values.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -14,10 +14,10 @@
 {
     template <class X>
     struct random_values
- : public std::list<typename X::value_type>
+ : public std::list<BOOST_DEDUCED_TYPENAME X::value_type>
     {
         random_values(int count) {
- typedef typename X::value_type value_type;
+ typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
             static test::generator<value_type> gen;
             std::generate_n(std::back_inserter(*this), count, gen);
         }

Modified: branches/unordered/dev/libs/unordered/test/helpers/strong.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/strong.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/strong.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -18,7 +18,7 @@
     template <class X>
     class strong
     {
- typedef std::vector<typename non_const_value_type<X>::type> values_type;
+ typedef std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type> values_type;
         values_type values_;
     public:
         void store(X const& x) {

Modified: branches/unordered/dev/libs/unordered/test/helpers/tracker.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/helpers/tracker.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/helpers/tracker.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -27,7 +27,7 @@
 {
     template <class X>
     struct equals_to_compare2
- : public boost::mpl::identity<std::less<typename X::first_argument_type> >
+ : public boost::mpl::identity<std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> >
     {
     };
 
@@ -44,8 +44,7 @@
     template <class X1, class X2>
     void compare_range(X1 const& x1, X2 const& x2)
     {
- typedef typename non_const_value_type<X1>::type value_type;
- std::vector<value_type> values1, values2;
+ std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X1>::type> values1, values2;
         values1.reserve(x1.size());
         values2.reserve(x2.size());
         std::copy(x1.begin(), x1.end(), std::back_inserter(values1));
@@ -74,20 +73,20 @@
     struct ordered_set
         : public boost::mpl::if_<
             test::has_unique_keys<X>,
- std::set<typename X::value_type,
- typename equals_to_compare<typename X::key_equal>::type>,
- std::multiset<typename X::value_type,
- typename equals_to_compare<typename X::key_equal>::type>
+ std::set<BOOST_DEDUCED_TYPENAME X::value_type,
+ BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>,
+ std::multiset<BOOST_DEDUCED_TYPENAME X::value_type,
+ BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
> {};
 
     template <class X>
     struct ordered_map
         : public boost::mpl::if_<
             test::has_unique_keys<X>,
- std::map<typename X::key_type, typename X::mapped_type,
- typename equals_to_compare<typename X::key_equal>::type>,
- std::multimap<typename X::key_type, typename X::mapped_type,
- typename equals_to_compare<typename X::key_equal>::type>
+ std::map<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
+ BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>,
+ std::multimap<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
+ BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
> {};
 
     template <class X>
@@ -102,9 +101,9 @@
     template <class X>
     class ordered : public ordered_base<X>::type
     {
- typedef typename ordered_base<X>::type base;
+ typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base;
     public:
- typedef typename base::key_compare key_compare;
+ typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare;
 
         ordered()
             : base()
@@ -119,12 +118,12 @@
             compare_range(x, *this);
         }
 
- void compare_key(X const& x, typename X::value_type const& val)
+ void compare_key(X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val)
         {
             compare_pairs(
                 x.equal_range(get_key<X>(val)),
                 this->equal_range(get_key<X>(val)),
- (typename non_const_value_type<X>::type*) 0
+ (BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type*) 0
                 );
         }
 
@@ -138,9 +137,9 @@
     };
 
     template <class Equals>
- typename equals_to_compare<Equals>::type create_compare(Equals const&)
+ BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare(Equals const&)
     {
- typename equals_to_compare<Equals>::type x;
+ BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
         return x;
     }
 

Modified: branches/unordered/dev/libs/unordered/test/objects/exception.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/objects/exception.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/objects/exception.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -3,175 +3,17 @@
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-#if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER)
-#define BOOST_UNORDERED_TEST_OBJECTS_HEADER
+#if !defined(BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER)
+#define BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER
+
+#include "../helpers/exception_test.hpp"
 
 #include <cstddef>
-#include <boost/limits.hpp>
-#include <boost/test/test_tools.hpp>
-#include <boost/test/exception_safety.hpp>
-#include <boost/preprocessor/seq/for_each_product.hpp>
-#include <boost/preprocessor/seq/elem.hpp>
-#include <boost/preprocessor/cat.hpp>
 #include <iostream>
+#include <boost/limits.hpp>
 #include "../helpers/fwd.hpp"
 #include "../helpers/allocator.hpp"
-#include <map>
-
-#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
- BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, (test_seq)(param_seq))
-
-#define RUN_EXCEPTION_TESTS_OP(r, product) \
- RUN_EXCEPTION_TESTS_OP2( \
- BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
- BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \
- ), \
- BOOST_PP_SEQ_ELEM(0, product), \
- BOOST_PP_SEQ_ELEM(1, product) \
- )
-
-#define RUN_EXCEPTION_TESTS_OP2(name, test_func, type) \
- BOOST_AUTO_TEST_CASE(name) \
- { \
- test_func< type > fixture; \
- ::test::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
- }
-
-#define SCOPE(scope_name) \
- for(::test::scope_guard unordered_test_guard( \
- BOOST_STRINGIZE(scope_name)); \
- !unordered_test_guard.dismissed(); \
- unordered_test_guard.dismiss())
-
-#define EPOINT(name) \
- if(::test::exceptions_enabled) { \
- BOOST_ITEST_EPOINT(name); \
- }
-
-#define ENABLE_EXCEPTIONS \
- ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)
-#define DISABLE_EXCEPTIONS \
- ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
-
-#define HASH_CHECK(test) if(!(test)) BOOST_ERROR(BOOST_STRINGIZE(test))
-
-namespace test {
- static char const* scope = "";
- bool exceptions_enabled = false;
-
- class scope_guard {
- scope_guard& operator=(scope_guard const&);
- scope_guard(scope_guard const&);
-
- char const* old_scope_;
- char const* scope_;
- bool dismissed_;
- public:
- scope_guard(char const* name)
- : old_scope_(scope),
- scope_(name),
- dismissed_(false)
- {
- scope = scope_;
- }
-
- ~scope_guard() {
- if(dismissed_) scope = old_scope_;
- }
-
- void dismiss() {
- dismissed_ = true;
- }
-
- bool dismissed() const {
- return dismissed_;
- }
- };
-
- class exceptions_enable
- {
- exceptions_enable& operator=(exceptions_enable const&);
- exceptions_enable(exceptions_enable const&);
-
- bool old_value_;
- public:
- exceptions_enable(bool enable)
- : old_value_(exceptions_enabled)
- {
- exceptions_enabled = enable;
- }
-
- ~exceptions_enable()
- {
- exceptions_enabled = old_value_;
- }
- };
-
- struct exception_base {
- struct data_type {};
- struct strong_type {
- template <class T> void store(T const&) {}
- template <class T> void test(T const&) const {}
- };
- data_type init() const { return data_type(); }
- void check() const {}
- };
-
- template <class T, class P1, class P2, class T2>
- inline void call_ignore_extra_parameters(void (T::*fn)() const, T2 const& obj,
- P1&, P2&)
- {
- (obj.*fn)();
- }
-
- template <class T, class P1, class P2, class T2>
- inline void call_ignore_extra_parameters(void (T::*fn)(P1&) const, T2 const& obj,
- P1& p1, P2&)
- {
- (obj.*fn)(p1);
- }
-
- template <class T, class P1, class P2, class T2>
- inline void call_ignore_extra_parameters(void (T::*fn)(P1&, P2&) const, T2 const& obj,
- P1& p1, P2& p2)
- {
- (obj.*fn)(p1, p2);
- }
-
- template <class T>
- T const& constant(T const& x) {
- return x;
- }
-
- template <class Test>
- class test_runner
- {
- Test const& test_;
- public:
- test_runner(Test const& t) : test_(t) {}
- void operator()() const {
- DISABLE_EXCEPTIONS;
- typename Test::data_type x(test_.init());
- typename Test::strong_type strong;
- strong.store(x);
- try {
- ENABLE_EXCEPTIONS;
- call_ignore_extra_parameters(&Test::run, test_, x, strong);
- }
- catch(...) {
- call_ignore_extra_parameters(&Test::check, test_,
- constant(x), constant(strong));
- throw;
- }
- }
- };
-
- template <class Test>
- void exception_safety(Test const& f, char const* name) {
- test_runner<Test> runner(f);
- ::boost::itest::exception_safety(runner, name);
- }
-}
+#include "./memory.hpp"
 
 namespace test
 {
@@ -179,119 +21,15 @@
 {
     namespace detail
     {
- // This annoymous namespace won't cause ODR violations as I won't
- // be linking multiple translation units together. I'll probably
- // move this into a cpp file before a full release, but for now it's
- // the most convenient way.
- namespace
- {
- struct memory_area {
- void const* start;
- void const* end;
-
- memory_area(void const* s, void const* e)
- : start(s), end(e)
- {
- }
-
- // This is a bit dodgy as it defines overlapping
- // areas as 'equal', so this isn't a total ordering.
- // But it is for non-overlapping memory regions - which
- // is what'll be stored.
- //
- // All searches will be for areas entirely contained by
- // a member of the set - so it should find the area that contains
- // the region that is searched for.
- bool operator<(memory_area const& other) const {
- return end < other.start;
- }
+ struct malloc_allocator_holder {
+ template <class T> struct apply {
+ typedef test::malloc_allocator<T> type;
             };
+ };
 
- struct memory_track {
- explicit memory_track(int tag = -1) :
- tag_(tag) {}
-
- int tag_;
- };
-
- typedef std::map<memory_area, memory_track, std::less<memory_area>,
- test::malloc_allocator<std::pair<memory_area const, memory_track> > >
- allocated_memory_type;
- allocated_memory_type allocated_memory;
- unsigned int count_allocators = 0;
- unsigned int count_allocations = 0;
- unsigned int count_constructions = 0;
- }
-
- void allocator_ref()
- {
- if(count_allocators == 0) {
- count_allocations = 0;
- count_constructions = 0;
- allocated_memory.clear();
- }
- ++count_allocators;
- }
-
- void allocator_unref()
- {
- HASH_CHECK(count_allocators > 0);
- if(count_allocators > 0) {
- --count_allocators;
- if(count_allocators == 0) {
- bool no_allocations_left = (count_allocations == 0);
- bool no_constructions_left = (count_constructions == 0);
- bool allocated_memory_empty = allocated_memory.empty();
-
- // Clearing the data before the checks terminate the tests.
- count_allocations = 0;
- count_constructions = 0;
- allocated_memory.clear();
-
- HASH_CHECK(no_allocations_left);
- HASH_CHECK(no_constructions_left);
- HASH_CHECK(allocated_memory_empty);
- }
- }
- }
-
- void track_allocate(void *ptr, std::size_t n, std::size_t size, int tag)
- {
- if(n == 0) {
- BOOST_ERROR("Allocating 0 length array.");
- }
- else {
- ++count_allocations;
- allocated_memory[memory_area(ptr, (char*) ptr + n * size)] =
- memory_track(tag);
- }
- }
-
- void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag)
- {
- allocated_memory_type::iterator pos
- = allocated_memory.find(memory_area(ptr, ptr));
- if(pos == allocated_memory.end()) {
- BOOST_ERROR("Deallocating unknown pointer.");
- } else {
- HASH_CHECK(pos->first.start == ptr);
- HASH_CHECK(pos->first.end == (char*) ptr + n * size);
- HASH_CHECK(pos->second.tag_ == tag);
- allocated_memory.erase(pos);
- }
- HASH_CHECK(count_allocations > 0);
- if(count_allocations > 0) --count_allocations;
- }
-
- void track_construct(void* ptr, std::size_t /*size*/, int tag)
- {
- ++count_constructions;
- }
-
- void track_destroy(void* ptr, std::size_t /*size*/, int tag)
+ namespace
         {
- HASH_CHECK(count_constructions > 0);
- if(count_constructions > 0) --count_constructions;
+ test::detail::memory_tracker<malloc_allocator_holder> tracker;
         }
     }
 
@@ -307,23 +45,23 @@
 
         explicit object() : tag1_(0), tag2_(0)
         {
- SCOPE(object::object()) {
- EPOINT("Mock object default constructor.");
+ UNORDERED_SCOPE(object::object()) {
+ UNORDERED_EPOINT("Mock object default constructor.");
             }
         }
 
         explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
         {
- SCOPE(object::object(int)) {
- EPOINT("Mock object constructor by value.");
+ UNORDERED_SCOPE(object::object(int)) {
+ UNORDERED_EPOINT("Mock object constructor by value.");
             }
         }
 
         object(object const& x)
              : tag1_(x.tag1_), tag2_(x.tag2_)
         {
- SCOPE(object::object(object)) {
- EPOINT("Mock object copy constructor.");
+ UNORDERED_SCOPE(object::object(object)) {
+ UNORDERED_EPOINT("Mock object copy constructor.");
             }
         }
 
@@ -334,26 +72,26 @@
 
         object& operator=(object const& x)
         {
- SCOPE(object::operator=(object)) {
+ UNORDERED_SCOPE(object::operator=(object)) {
                 tag1_ = x.tag1_;
- EPOINT("Mock object assign operator 1.");
+ UNORDERED_EPOINT("Mock object assign operator 1.");
                 tag2_ = x.tag2_;
- //EPOINT("Mock object assign operator 2.");
+ //UNORDERED_EPOINT("Mock object assign operator 2.");
             }
             return *this;
         }
 
         friend bool operator==(object const& x1, object const& x2) {
- SCOPE(operator==(object, object)) {
- EPOINT("Mock object equality operator.");
+ UNORDERED_SCOPE(operator==(object, object)) {
+ UNORDERED_EPOINT("Mock object equality operator.");
             }
 
             return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
         }
 
         friend bool operator!=(object const& x1, object const& x2) {
- SCOPE(operator!=(object, object)) {
- EPOINT("Mock object inequality operator.");
+ UNORDERED_SCOPE(operator!=(object, object)) {
+ UNORDERED_EPOINT("Mock object inequality operator.");
             }
 
             return !(x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_);
@@ -383,32 +121,32 @@
     public:
         hash(int t = 0) : tag_(t)
         {
- SCOPE(hash::object()) {
- EPOINT("Mock hash default constructor.");
+ UNORDERED_SCOPE(hash::object()) {
+ UNORDERED_EPOINT("Mock hash default constructor.");
             }
         }
 
         hash(hash const& x)
             : tag_(x.tag_)
         {
- SCOPE(hash::hash(hash)) {
- EPOINT("Mock hash copy constructor.");
+ UNORDERED_SCOPE(hash::hash(hash)) {
+ UNORDERED_EPOINT("Mock hash copy constructor.");
             }
         }
 
         hash& operator=(hash const& x)
         {
- SCOPE(hash::operator=(hash)) {
- EPOINT("Mock hash assign operator 1.");
+ UNORDERED_SCOPE(hash::operator=(hash)) {
+ UNORDERED_EPOINT("Mock hash assign operator 1.");
                 tag_ = x.tag_;
- EPOINT("Mock hash assign operator 2.");
+ UNORDERED_EPOINT("Mock hash assign operator 2.");
             }
             return *this;
         }
 
         std::size_t operator()(object const& x) const {
- SCOPE(hash::operator()(object)) {
- EPOINT("Mock hash function.");
+ UNORDERED_SCOPE(hash::operator()(object)) {
+ UNORDERED_EPOINT("Mock hash function.");
             }
 
             switch(tag_) {
@@ -422,15 +160,15 @@
         }
 
         friend bool operator==(hash const& x1, hash const& x2) {
- SCOPE(operator==(hash, hash)) {
- EPOINT("Mock hash equality function.");
+ UNORDERED_SCOPE(operator==(hash, hash)) {
+ UNORDERED_EPOINT("Mock hash equality function.");
             }
             return x1.tag_ == x2.tag_;
         }
 
         friend bool operator!=(hash const& x1, hash const& x2) {
- SCOPE(hash::operator!=(hash, hash)) {
- EPOINT("Mock hash inequality function.");
+ UNORDERED_SCOPE(hash::operator!=(hash, hash)) {
+ UNORDERED_EPOINT("Mock hash inequality function.");
             }
             return x1.tag_ != x2.tag_;
         }
@@ -442,32 +180,32 @@
     public:
         equal_to(int t = 0) : tag_(t)
         {
- SCOPE(equal_to::equal_to()) {
- EPOINT("Mock equal_to default constructor.");
+ UNORDERED_SCOPE(equal_to::equal_to()) {
+ UNORDERED_EPOINT("Mock equal_to default constructor.");
             }
         }
 
         equal_to(equal_to const& x)
             : tag_(x.tag_)
         {
- SCOPE(equal_to::equal_to(equal_to)) {
- EPOINT("Mock equal_to copy constructor.");
+ UNORDERED_SCOPE(equal_to::equal_to(equal_to)) {
+ UNORDERED_EPOINT("Mock equal_to copy constructor.");
             }
         }
 
         equal_to& operator=(equal_to const& x)
         {
- SCOPE(equal_to::operator=(equal_to)) {
- EPOINT("Mock equal_to assign operator 1.");
+ UNORDERED_SCOPE(equal_to::operator=(equal_to)) {
+ UNORDERED_EPOINT("Mock equal_to assign operator 1.");
                 tag_ = x.tag_;
- EPOINT("Mock equal_to assign operator 2.");
+ UNORDERED_EPOINT("Mock equal_to assign operator 2.");
             }
             return *this;
         }
 
         bool operator()(object const& x1, object const& x2) const {
- SCOPE(equal_to::operator()(object, object)) {
- EPOINT("Mock equal_to function.");
+ UNORDERED_SCOPE(equal_to::operator()(object, object)) {
+ UNORDERED_EPOINT("Mock equal_to function.");
             }
 
             switch(tag_) {
@@ -481,15 +219,15 @@
         }
 
         friend bool operator==(equal_to const& x1, equal_to const& x2) {
- SCOPE(operator==(equal_to, equal_to)) {
- EPOINT("Mock equal_to equality function.");
+ UNORDERED_SCOPE(operator==(equal_to, equal_to)) {
+ UNORDERED_EPOINT("Mock equal_to equality function.");
             }
             return x1.tag_ == x2.tag_;
         }
 
         friend bool operator!=(equal_to const& x1, equal_to const& x2) {
- SCOPE(operator!=(equal_to, equal_to)) {
- EPOINT("Mock equal_to inequality function.");
+ UNORDERED_SCOPE(operator!=(equal_to, equal_to)) {
+ UNORDERED_EPOINT("Mock equal_to inequality function.");
             }
             return x1.tag_ != x2.tag_;
         }
@@ -512,35 +250,35 @@
 
         explicit allocator(int t = 0) : tag_(t)
         {
- SCOPE(allocator::allocator()) {
- EPOINT("Mock allocator default constructor.");
+ UNORDERED_SCOPE(allocator::allocator()) {
+ UNORDERED_EPOINT("Mock allocator default constructor.");
             }
- detail::allocator_ref();
+ detail::tracker.allocator_ref();
         }
 
         template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
         {
- SCOPE(allocator::allocator()) {
- EPOINT("Mock allocator template copy constructor.");
+ UNORDERED_SCOPE(allocator::allocator()) {
+ UNORDERED_EPOINT("Mock allocator template copy constructor.");
             }
- detail::allocator_ref();
+ detail::tracker.allocator_ref();
         }
 
         allocator(allocator const& x) : tag_(x.tag_)
         {
- SCOPE(allocator::allocator()) {
- EPOINT("Mock allocator copy constructor.");
+ UNORDERED_SCOPE(allocator::allocator()) {
+ UNORDERED_EPOINT("Mock allocator copy constructor.");
             }
- detail::allocator_ref();
+ detail::tracker.allocator_ref();
         }
 
         ~allocator() {
- detail::allocator_unref();
+ detail::tracker.allocator_unref();
         }
 
         allocator& operator=(allocator const& x) {
- SCOPE(allocator::allocator()) {
- EPOINT("Mock allocator assignment operator.");
+ UNORDERED_SCOPE(allocator::allocator()) {
+ UNORDERED_EPOINT("Mock allocator assignment operator.");
                 tag_ = x.tag_;
             }
             return *this;
@@ -551,29 +289,29 @@
         // this.
 
         pointer address(reference r) {
- //SCOPE(allocator::address(reference)) {
- // EPOINT("Mock allocator address function.");
+ //UNORDERED_SCOPE(allocator::address(reference)) {
+ // UNORDERED_EPOINT("Mock allocator address function.");
             //}
             return pointer(&r);
         }
 
         const_pointer address(const_reference r) {
- //SCOPE(allocator::address(const_reference)) {
- // EPOINT("Mock allocator const address function.");
+ //UNORDERED_SCOPE(allocator::address(const_reference)) {
+ // UNORDERED_EPOINT("Mock allocator const address function.");
             //}
             return const_pointer(&r);
         }
 
         pointer allocate(size_type n) {
             T* ptr = 0;
- SCOPE(allocator::allocate(size_type)) {
- EPOINT("Mock allocator allocate function.");
+ UNORDERED_SCOPE(allocator::allocate(size_type)) {
+ UNORDERED_EPOINT("Mock allocator allocate function.");
 
                 using namespace std;
                 ptr = (T*) malloc(n * sizeof(T));
                 if(!ptr) throw std::bad_alloc();
             }
- detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
+ detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
             return pointer(ptr);
 
             //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
@@ -582,14 +320,14 @@
         pointer allocate(size_type n, const_pointer u)
         {
             T* ptr = 0;
- SCOPE(allocator::allocate(size_type, const_pointer)) {
- EPOINT("Mock allocator allocate function.");
+ UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) {
+ UNORDERED_EPOINT("Mock allocator allocate function.");
 
                 using namespace std;
                 ptr = (T*) malloc(n * sizeof(T));
                 if(!ptr) throw std::bad_alloc();
             }
- detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
+ detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
             return pointer(ptr);
 
             //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
@@ -599,28 +337,28 @@
         {
             //::operator delete((void*) p);
             if(p) {
- detail::track_deallocate((void*) p, n, sizeof(T), tag_);
+ detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
                 using namespace std;
                 free(p);
             }
         }
 
         void construct(pointer p, T const& t) {
- SCOPE(allocator::construct(pointer, T)) {
- EPOINT("Mock allocator construct function.");
+ UNORDERED_SCOPE(allocator::construct(pointer, T)) {
+ UNORDERED_EPOINT("Mock allocator construct function.");
                 new(p) T(t);
             }
- detail::track_construct((void*) p, sizeof(T), tag_);
+ detail::tracker.track_construct((void*) p, sizeof(T), tag_);
         }
 
         void destroy(pointer p) {
- detail::track_destroy((void*) p, sizeof(T), tag_);
+ detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
             p->~T();
         }
 
         size_type max_size() const {
- SCOPE(allocator::construct(pointer, T)) {
- EPOINT("Mock allocator max_size function.");
+ UNORDERED_SCOPE(allocator::construct(pointer, T)) {
+ UNORDERED_EPOINT("Mock allocator max_size function.");
             }
             return (std::numeric_limits<std::size_t>::max)();
         }
@@ -638,8 +376,8 @@
     template <class T>
     inline bool operator==(allocator<T> const& x, allocator<T> const& y)
     {
- //SCOPE(operator==(allocator, allocator)) {
- // EPOINT("Mock allocator equality operator.");
+ //UNORDERED_SCOPE(operator==(allocator, allocator)) {
+ // UNORDERED_EPOINT("Mock allocator equality operator.");
         //}
         return x.tag_ == y.tag_;
     }
@@ -647,13 +385,23 @@
     template <class T>
     inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
     {
- //SCOPE(operator!=(allocator, allocator)) {
- // EPOINT("Mock allocator inequality operator.");
+ //UNORDERED_SCOPE(operator!=(allocator, allocator)) {
+ // UNORDERED_EPOINT("Mock allocator inequality operator.");
         //}
         return x.tag_ != y.tag_;
     }
 }
 }
 
+// Workaround for ADL deficient compilers
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace test
+{
+ test::exception::object generate(test::exception::object const* x) {
+ return test::exception::generate(x);
+ }
+}
+#endif
+
 #endif
 

Modified: branches/unordered/dev/libs/unordered/test/objects/minimal.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/objects/minimal.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/objects/minimal.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -3,6 +3,10 @@
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
+// Define some minimal classes which provide the bare minimum concepts to
+// test that the containers don't rely on something that they shouldn't.
+// They are not intended to be good examples of how to implement the concepts.
+
 #if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
 #define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
 
@@ -124,22 +128,18 @@
     public:
         ptr() : ptr_(0) {}
 
- typedef void (ptr::*bool_type)() const;
- void this_type_does_not_support_comparisons() const {}
-
         T& operator*() const { return *ptr_; }
         T* operator->() const { return ptr_; }
         ptr& operator++() { ++ptr_; return *this; }
         ptr operator++(int) { ptr tmp(*this); ++ptr_; return tmp; }
- ptr operator+(int s) const { return ptr<T>(ptr_ + s); }
- T& operator[](int s) const { return ptr_[s]; }
+ ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
+ friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
+ T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
         bool operator!() const { return !ptr_; }
-
- operator bool_type() const {
- return ptr_ ?
- &ptr::this_type_does_not_support_comparisons
- : 0;
- }
+
+ // I'm not using the safe bool idiom because the containers should be
+ // able to cope with bool conversions.
+ operator bool() const { return !!ptr_; }
 
         bool operator==(ptr const& x) const { return ptr_ == x.ptr_; }
         bool operator!=(ptr const& x) const { return ptr_ != x.ptr_; }
@@ -168,22 +168,15 @@
         const_ptr() : ptr_(0) {}
         const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
 
- typedef void (const_ptr::*bool_type)() const;
- void this_type_does_not_support_comparisons() const {}
-
         T const& operator*() const { return *ptr_; }
         T const* operator->() const { return ptr_; }
         const_ptr& operator++() { ++ptr_; return *this; }
         const_ptr operator++(int) { const_ptr tmp(*this); ++ptr_; return tmp; }
- const_ptr operator+(int s) const { return const_ptr(ptr_ + s); }
+ const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
+ friend const_ptr operator+(std::ptrdiff_t s, const_ptr p) { return ptr<T>(s + p.ptr_); }
         T const& operator[](int s) const { return ptr_[s]; }
         bool operator!() const { return !ptr_; }
-
- operator bool_type() const {
- return ptr_ ?
- &const_ptr::this_type_does_not_support_comparisons
- : 0;
- }
+ operator bool() const { return !!ptr_; }
 
         bool operator==(ptr<T> const& x) const { return ptr_ == x.ptr_; }
         bool operator!=(ptr<T> const& x) const { return ptr_ != x.ptr_; }

Modified: branches/unordered/dev/libs/unordered/test/objects/test.hpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/objects/test.hpp (original)
+++ branches/unordered/dev/libs/unordered/test/objects/test.hpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -9,8 +9,9 @@
 #include <boost/config.hpp>
 #include <boost/limits.hpp>
 #include <cstddef>
-#include "../helpers/fwd.hpp"
 #include <iostream>
+#include "../helpers/fwd.hpp"
+#include "memory.hpp"
 #include <map>
 
 namespace test
@@ -203,132 +204,8 @@
 
     namespace detail
     {
- // This annoymous namespace won't cause ODR violations as I won't
- // be linking multiple translation units together. I'll probably
- // move this into a cpp file before a full release, but for now it's
- // the most convenient way.
         namespace {
- struct memory_area {
- void const* start;
- void const* end;
-
- memory_area(void const* s, void const* e)
- : start(s), end(e)
- {
- }
-
- // This is a bit dodgy as it defines overlapping
- // areas as 'equal', so this isn't a total ordering.
- // But it is for non-overlapping memory regions - which
- // is what'll be stored.
- //
- // All searches will be for areas entirely contained by
- // a member of the set - so it should find the area that contains
- // the region that is searched for.
- bool operator<(memory_area const& other) const {
- return end < other.start;
- }
- };
-
- struct memory_track {
- explicit memory_track(int tag = -1) :
- constructed_(0),
- tag_(tag) {}
-
- int constructed_;
- int tag_;
- };
-
- typedef std::map<memory_area, memory_track> allocated_memory_type;
- allocated_memory_type allocated_memory;
- unsigned int count_allocators = 0;
- unsigned int count_allocations = 0;
- unsigned int count_constructions = 0;
- }
-
- void allocator_ref()
- {
- if(count_allocators == 0) {
- count_allocations = 0;
- count_constructions = 0;
- allocated_memory.clear();
- }
- ++count_allocators;
- }
-
- void allocator_unref()
- {
- BOOST_TEST(count_allocators > 0);
- if(count_allocators > 0) {
- --count_allocators;
- if(count_allocators == 0) {
- bool no_allocations_left = (count_allocations == 0);
- bool no_constructions_left = (count_constructions == 0);
- bool allocated_memory_empty = allocated_memory.empty();
-
- // Clearing the data before the checks terminate the tests.
- count_allocations = 0;
- count_constructions = 0;
- allocated_memory.clear();
-
- BOOST_TEST(no_allocations_left);
- BOOST_TEST(no_constructions_left);
- BOOST_TEST(allocated_memory_empty);
- }
- }
- }
-
- void track_allocate(void *ptr, std::size_t n, std::size_t size, int tag)
- {
- if(n == 0) {
- BOOST_ERROR("Allocating 0 length array.");
- }
- else {
- ++count_allocations;
- allocated_memory[memory_area(ptr, (char*) ptr + n * size)] =
- memory_track(tag);
- }
- }
-
- void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag)
- {
- allocated_memory_type::iterator pos
- = allocated_memory.find(memory_area(ptr, ptr));
- if(pos == allocated_memory.end()) {
- BOOST_ERROR("Deallocating unknown pointer.");
- } else {
- BOOST_TEST(pos->first.start == ptr);
- BOOST_TEST(pos->first.end == (char*) ptr + n * size);
- BOOST_TEST(pos->second.tag_ == tag);
- BOOST_TEST(pos->second.constructed_ == 0);
- allocated_memory.erase(pos);
- }
- BOOST_TEST(count_allocations > 0);
- if(count_allocations > 0) --count_allocations;
- }
-
- void track_construct(void* ptr, std::size_t /*size*/, int tag)
- {
- allocated_memory_type::iterator pos
- = allocated_memory.find(memory_area(ptr, ptr));
- if(pos == allocated_memory.end())
- BOOST_ERROR("Constructing unknown pointer.");
- BOOST_TEST(pos->second.tag_ == tag);
- ++count_constructions;
- ++pos->second.constructed_;
- }
-
- void track_destroy(void* ptr, std::size_t /*size*/, int tag)
- {
- allocated_memory_type::iterator pos
- = allocated_memory.find(memory_area(ptr, ptr));
- if(pos == allocated_memory.end())
- BOOST_ERROR("Destroying unknown pointer.");
- BOOST_TEST(count_constructions > 0);
- BOOST_TEST(pos->second.tag_ == tag);
- BOOST_TEST(pos->second.constructed_ > 0);
- if(count_constructions > 0) --count_constructions;
- if(pos->second.constructed_ > 0) --pos->second.constructed_;
+ test::detail::memory_tracker<test::detail::default_allocator_holder> tracker;
         }
     }
 
@@ -352,40 +229,40 @@
 
         template <class U> struct rebind { typedef allocator<U> other; };
 
- explicit allocator(int t = 0) : tag_(t) { detail::allocator_ref(); }
- template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::allocator_ref(); }
- allocator(allocator const& x) : tag_(x.tag_) { detail::allocator_ref(); }
- ~allocator() { detail::allocator_unref(); }
+ explicit allocator(int t = 0) : tag_(t) { detail::tracker.allocator_ref(); }
+ template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
+ allocator(allocator const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
+ ~allocator() { detail::tracker.allocator_unref(); }
 
         pointer address(reference r) { return pointer(&r); }
         const_pointer address(const_reference r) { return const_pointer(&r); }
 
         pointer allocate(size_type n) {
             pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
- detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
+ detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
             return ptr;
         }
 
         pointer allocate(size_type n, const_pointer u)
         {
             pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
- detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
+ detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
             return ptr;
         }
 
         void deallocate(pointer p, size_type n)
         {
- detail::track_deallocate((void*) p, n, sizeof(T), tag_);
+ detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
             ::operator delete((void*) p);
         }
 
         void construct(pointer p, T const& t) {
- detail::track_construct((void*) p, sizeof(T), tag_);
+ detail::tracker.track_construct((void*) p, sizeof(T), tag_);
             new(p) T(t);
         }
 
         void destroy(pointer p) {
- detail::track_destroy((void*) p, sizeof(T), tag_);
+ detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
             p->~T();
         }
 

Modified: branches/unordered/dev/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/Jamfile.v2 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -12,10 +12,13 @@
         <toolset>msvc:<cxxflags>/W4
     ;
 
-test-suite unordered-tests
+test-suite unordered
     :
+ [ run compile_set.cpp ]
+ [ run compile_map.cpp ]
+ [ run link_test_1.cpp link_test_2.cpp ]
+ [ run simple_tests.cpp ]
         [ run equivalent_keys_tests.cpp ]
- [ run compile_tests.cpp ]
         [ run constructor_tests.cpp ]
         [ run copy_tests.cpp ]
         [ run assign_tests.cpp ]

Modified: branches/unordered/dev/libs/unordered/test/unordered/assign_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/assign_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/assign_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -18,8 +18,8 @@
 template <class T>
 void assign_tests1(T* = 0)
 {
- typename T::hasher hf;
- typename T::key_equal eq;
+ BOOST_DEDUCED_TYPENAME T::hasher hf;
+ BOOST_DEDUCED_TYPENAME T::key_equal eq;
 
     std::cerr<<"assign_tests1.1\n";
     {
@@ -52,12 +52,12 @@
 template <class T>
 void assign_tests2(T* = 0)
 {
- typename T::hasher hf1(1);
- typename T::hasher hf2(2);
- typename T::key_equal eq1(1);
- typename T::key_equal eq2(2);
- typename T::allocator_type al1(1);
- typename T::allocator_type al2(2);
+ BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
+ BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
+ BOOST_DEDUCED_TYPENAME T::key_equal eq1(1);
+ BOOST_DEDUCED_TYPENAME T::key_equal eq2(2);
+ BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
+ BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
 
     std::cerr<<"assign_tests2.1\n";
     {

Modified: branches/unordered/dev/libs/unordered/test/unordered/bucket_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/bucket_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/bucket_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -16,8 +16,8 @@
 template <class X>
 void bucket_tests(X* = 0)
 {
- typedef typename X::size_type size_type;
- typedef typename X::const_local_iterator const_local_iterator;
+ typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
+ typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
     test::random_values<X> v(1000);
 
     X x(v.begin(), v.end());
@@ -25,7 +25,7 @@
     BOOST_TEST(x.bucket_count() < x.max_bucket_count());
     std::cerr<<x.bucket_count()<<"<"<<x.max_bucket_count()<<"\n";
 
- for(typename test::random_values<X>::const_iterator
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
             it = v.begin(), end = v.end(); it != end; ++it)
     {
         size_type bucket = x.bucket(test::get_key<X>(*it));

Deleted: branches/unordered/dev/libs/unordered/test/unordered/compile_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/compile_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
+++ (empty file)
@@ -1,328 +0,0 @@
-
-// Copyright 2006-2007 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include <boost/unordered_set.hpp>
-#include <boost/unordered_map.hpp>
-
-#if defined(BOOST_MSVC)
-#pragma warning(push)
-#pragma warning(disable:4100) // unreferenced formal parameter
-#endif
-
-#include <boost/concept_check.hpp>
-
-#if defined(BOOST_MSVC)
-#pragma warning(pop)
-#endif
-
-#include <boost/mpl/assert.hpp>
-#include <boost/iterator/iterator_traits.hpp>
-#include "../helpers/check_return_type.hpp"
-
-#include <iostream>
-#include <boost/detail/lightweight_test.hpp>
-#include "../objects/minimal.hpp"
-
-template <class T> void sink(T const&) {}
-
-template <class X, class Key>
-void unordered_set_test(X&, Key const&)
-{
- typedef typename X::value_type value_type;
- typedef typename X::key_type key_type;
-
- BOOST_MPL_ASSERT((boost::is_same<value_type, key_type>));
-}
-
-template <class X, class Key, class T>
-void unordered_map_test(X&, Key const&, T const&)
-{
- typedef typename X::value_type value_type;
- typedef typename X::key_type key_type;
- BOOST_MPL_ASSERT((boost::is_same<value_type, std::pair<key_type const, T> >));
-}
-
-template <class X, class T>
-void unordered_unique_test(X& r, T const& t)
-{
- typedef typename X::iterator iterator;
- test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
-}
-
-template <class X, class T>
-void unordered_equivalent_test(X& r, T const& t)
-{
- typedef typename X::iterator iterator;
- test::check_return_type<iterator>::equals(r.insert(t));
-}
-
-template <class X, class Key, class T>
-void unordered_map_functions(X&, Key const& k, T const&)
-{
- typedef typename X::mapped_type mapped_type;
-
- X a;
- test::check_return_type<mapped_type>::equals_ref(a[k]);
- test::check_return_type<mapped_type>::equals_ref(a.at(k));
-
- X const b = a;
- test::check_return_type<mapped_type const>::equals_ref(b.at(k));
-}
-
-template <class X, class Key, class T, class Hash, class Pred>
-void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
-{
- typedef typename X::key_type key_type;
- typedef typename X::hasher hasher;
- typedef typename X::key_equal key_equal;
- typedef typename X::size_type size_type;
-
- typedef typename X::iterator iterator;
- typedef typename X::const_iterator const_iterator;
- typedef typename X::local_iterator local_iterator;
- typedef typename X::const_local_iterator const_local_iterator;
-
- typedef typename boost::BOOST_ITERATOR_CATEGORY<iterator>::type iterator_category;
- typedef typename boost::iterator_difference<iterator>::type iterator_difference;
- typedef typename boost::iterator_pointer<iterator>::type iterator_pointer;
- typedef typename boost::iterator_reference<iterator>::type iterator_reference;
-
- typedef typename boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type local_iterator_category;
- typedef typename boost::iterator_difference<local_iterator>::type local_iterator_difference;
- typedef typename boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
- typedef typename boost::iterator_reference<local_iterator>::type local_iterator_reference;
-
- typedef typename boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type const_iterator_category;
- typedef typename boost::iterator_difference<const_iterator>::type const_iterator_difference;
- typedef typename boost::iterator_pointer<const_iterator>::type const_iterator_pointer;
- typedef typename boost::iterator_reference<const_iterator>::type const_iterator_reference;
-
- typedef typename boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type const_local_iterator_category;
- typedef typename boost::iterator_difference<const_local_iterator>::type const_local_iterator_difference;
- typedef typename boost::iterator_pointer<const_local_iterator>::type const_local_iterator_pointer;
- typedef typename boost::iterator_reference<const_local_iterator>::type const_local_iterator_reference;
-
- BOOST_MPL_ASSERT((boost::is_same<Key, key_type>));
- boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
- boost::function_requires<boost::AssignableConcept<key_type> >();
-
- BOOST_MPL_ASSERT((boost::is_same<Hash, hasher>));
- test::check_return_type<std::size_t>::equals(hf(k));
-
- BOOST_MPL_ASSERT((boost::is_same<Pred, key_equal>));
- test::check_return_type<bool>::convertible(eq(k, k));
-
- boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
- BOOST_MPL_ASSERT((boost::is_same<local_iterator_category, iterator_category>));
- BOOST_MPL_ASSERT((boost::is_same<local_iterator_difference, iterator_difference>));
- BOOST_MPL_ASSERT((boost::is_same<local_iterator_pointer, iterator_pointer>));
- BOOST_MPL_ASSERT((boost::is_same<local_iterator_reference, iterator_reference>));
-
- boost::function_requires<boost::InputIteratorConcept<const_local_iterator> >();
- BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_category, const_iterator_category>));
- BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_difference, const_iterator_difference>));
- BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_pointer, const_iterator_pointer>));
- BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_reference, const_iterator_reference>));
-
- X(10, hf, eq);
- X a(10, hf, eq);
- X(10, hf);
- X a2(10, hf);
- X(10);
- X a3(10);
- X();
- X a4;
-
- typename X::value_type* i = 0;
- typename X::value_type* j = 0;
-
- X(i, j, 10, hf, eq);
- X a5(i, j, 10, hf, eq);
- X(i, j, 10, hf);
- X a6(i, j, 10, hf);
- X(i, j, 10);
- X a7(i, j, 10);
- X(i, j);
- X a8(i, j);
-
- X const b;
- sink(X(b));
- X a9(b);
- a = b;
-
- test::check_return_type<hasher>::equals(b.hash_function());
- test::check_return_type<key_equal>::equals(b.key_eq());
-
- const_iterator q = a.cbegin();
- test::check_return_type<iterator>::equals(a.insert(q, t));
-
- a.insert(i, j);
- test::check_return_type<size_type>::equals(a.erase(k));
-
- BOOST_TEST(a.empty());
- if(a.empty()) {
- a.insert(t);
- q = a.cbegin();
- test::check_return_type<iterator>::equals(a.erase(q));
- }
-
- const_iterator q1 = a.cbegin(), q2 = a.cend();
- test::check_return_type<iterator>::equals(a.erase(q1, q2));
-
- a.clear();
-
- test::check_return_type<iterator>::equals(a.find(k));
- test::check_return_type<const_iterator>::equals(b.find(k));
- test::check_return_type<size_type>::equals(b.count(k));
- test::check_return_type<std::pair<iterator, iterator> >::equals(
- a.equal_range(k));
- test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
- b.equal_range(k));
- test::check_return_type<size_type>::equals(b.bucket_count());
- test::check_return_type<size_type>::equals(b.max_bucket_count());
- test::check_return_type<size_type>::equals(b.bucket(k));
- test::check_return_type<size_type>::equals(b.bucket_size(0));
-
- test::check_return_type<local_iterator>::equals(a.begin(0));
- test::check_return_type<const_local_iterator>::equals(b.begin(0));
- test::check_return_type<local_iterator>::equals(a.end(0));
- test::check_return_type<const_local_iterator>::equals(b.end(0));
-
- test::check_return_type<const_local_iterator>::equals(a.cbegin(0));
- test::check_return_type<const_local_iterator>::equals(b.cbegin(0));
- test::check_return_type<const_local_iterator>::equals(a.cend(0));
- test::check_return_type<const_local_iterator>::equals(b.cend(0));
-
- test::check_return_type<float>::equals(b.load_factor());
- test::check_return_type<float>::equals(b.max_load_factor());
- a.max_load_factor((float) 2.0);
- a.rehash(100);
-}
-
-void test1()
-{
- boost::hash<int> hash;
- std::equal_to<int> equal_to;
- int value = 0;
- std::pair<int const, int> map_value(0, 0);
-
- std::cout<<"Test unordered_set.\n";
-
- boost::unordered_set<int> set;
-
- unordered_unique_test(set, value);
- unordered_set_test(set, value);
- unordered_test(set, value, value, hash, equal_to);
-
- std::cout<<"Test unordered_multiset.\n";
-
- boost::unordered_multiset<int> multiset;
-
- unordered_equivalent_test(multiset, value);
- unordered_set_test(multiset, value);
- unordered_test(multiset, value, value, hash, equal_to);
-
- std::cout<<"Test unordered_map.\n";
-
- boost::unordered_map<int, int> map;
-
- unordered_unique_test(map, map_value);
- unordered_map_test(map, value, value);
- unordered_test(map, value, map_value, hash, equal_to);
- unordered_map_functions(map, value, value);
-
- std::cout<<"Test unordered_multimap.\n";
-
- boost::unordered_multimap<int, int> multimap;
-
- unordered_equivalent_test(multimap, map_value);
- unordered_map_test(multimap, value, value);
- unordered_test(multimap, value, map_value, hash, equal_to);
-}
-
-void test2()
-{
- test::minimal::assignable assignable
- = test::minimal::assignable::create();
- test::minimal::copy_constructible copy_constructible
- = test::minimal::copy_constructible::create();
- test::minimal::hash<test::minimal::assignable> hash
- = test::minimal::hash<test::minimal::assignable>::create();
- test::minimal::equal_to<test::minimal::assignable> equal_to
- = test::minimal::equal_to<test::minimal::assignable>::create();
-
- typedef std::pair<test::minimal::assignable const,
- test::minimal::copy_constructible> map_value_type;
- map_value_type map_value(assignable, copy_constructible);
-
- std::cout<<"Test unordered_set.\n";
-
- boost::unordered_set<
- test::minimal::assignable,
- test::minimal::hash<test::minimal::assignable>,
- test::minimal::equal_to<test::minimal::assignable>,
- test::minimal::allocator<test::minimal::assignable> > set;
-
- unordered_unique_test(set, assignable);
- unordered_set_test(set, assignable);
- unordered_test(set, assignable, assignable, hash, equal_to);
-
- std::cout<<"Test unordered_multiset.\n";
-
- boost::unordered_multiset<
- test::minimal::assignable,
- test::minimal::hash<test::minimal::assignable>,
- test::minimal::equal_to<test::minimal::assignable>,
- test::minimal::allocator<test::minimal::assignable> > multiset;
-
- unordered_equivalent_test(multiset, assignable);
- unordered_set_test(multiset, assignable);
- unordered_test(multiset, assignable, assignable, hash, equal_to);
-
- std::cout<<"Test unordered_map.\n";
-
- boost::unordered_map<
- test::minimal::assignable,
- test::minimal::copy_constructible,
- test::minimal::hash<test::minimal::assignable>,
- test::minimal::equal_to<test::minimal::assignable>,
- test::minimal::allocator<map_value_type> > map;
-
- unordered_unique_test(map, map_value);
- unordered_map_test(map, assignable, copy_constructible);
- unordered_test(map, assignable, map_value, hash, equal_to);
-
-
- boost::unordered_map<
- test::minimal::assignable,
- test::minimal::default_copy_constructible,
- test::minimal::hash<test::minimal::assignable>,
- test::minimal::equal_to<test::minimal::assignable>,
- test::minimal::allocator<map_value_type> > map2;
-
- test::minimal::default_copy_constructible default_copy_constructible;
-
- unordered_map_functions(map2, assignable, default_copy_constructible);
-
- std::cout<<"Test unordered_multimap.\n";
-
- boost::unordered_multimap<
- test::minimal::assignable,
- test::minimal::copy_constructible,
- test::minimal::hash<test::minimal::assignable>,
- test::minimal::equal_to<test::minimal::assignable>,
- test::minimal::allocator<map_value_type> > multimap;
-
- unordered_equivalent_test(multimap, map_value);
- unordered_map_test(multimap, assignable, copy_constructible);
- unordered_test(multimap, assignable, map_value, hash, equal_to);
-}
-
-int main() {
- test1();
- test2();
-
- return boost::report_errors();
-}

Modified: branches/unordered/dev/libs/unordered/test/unordered/constructor_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/constructor_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/constructor_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -20,9 +20,9 @@
 template <class T>
 void constructor_tests1(T* = 0)
 {
- typename T::hasher hf;
- typename T::key_equal eq;
- typename T::allocator_type al;
+ BOOST_DEDUCED_TYPENAME T::hasher hf;
+ BOOST_DEDUCED_TYPENAME T::key_equal eq;
+ BOOST_DEDUCED_TYPENAME T::allocator_type al;
 
     std::cerr<<"Construct 1\n";
     {
@@ -139,15 +139,15 @@
 template <class T>
 void constructor_tests2(T* = 0)
 {
- typename T::hasher hf;
- typename T::hasher hf1(1);
- typename T::hasher hf2(2);
- typename T::key_equal eq;
- typename T::key_equal eq1(1);
- typename T::key_equal eq2(2);
- typename T::allocator_type al;
- typename T::allocator_type al1(1);
- typename T::allocator_type al2(2);
+ BOOST_DEDUCED_TYPENAME T::hasher hf;
+ BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
+ BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
+ BOOST_DEDUCED_TYPENAME T::key_equal eq;
+ BOOST_DEDUCED_TYPENAME T::key_equal eq1(1);
+ BOOST_DEDUCED_TYPENAME T::key_equal eq2(2);
+ BOOST_DEDUCED_TYPENAME T::allocator_type al;
+ BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
+ BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
 
     std::cerr<<"Construct 1\n";
     {

Modified: branches/unordered/dev/libs/unordered/test/unordered/copy_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/copy_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/copy_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -17,9 +17,9 @@
 template <class T>
 void copy_construct_tests1(T* = 0)
 {
- typename T::hasher hf;
- typename T::key_equal eq;
- typename T::allocator_type al;
+ BOOST_DEDUCED_TYPENAME T::hasher hf;
+ BOOST_DEDUCED_TYPENAME T::key_equal eq;
+ BOOST_DEDUCED_TYPENAME T::allocator_type al;
 
     {
         T x;
@@ -64,9 +64,9 @@
 {
     copy_construct_tests1(ptr);
 
- typename T::hasher hf(1);
- typename T::key_equal eq(1);
- typename T::allocator_type al(1);
+ BOOST_DEDUCED_TYPENAME T::hasher hf(1);
+ BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
+ BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
 
     {
         T x(10000, hf, eq, al);

Modified: branches/unordered/dev/libs/unordered/test/unordered/erase_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/erase_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/erase_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -24,7 +24,7 @@
     {
         test::random_values<Container> v(1000);
         Container x(v.begin(), v.end());
- for(typename test::random_values<Container>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator it = v.begin();
             it != v.end(); ++it)
         {
             std::size_t count = x.count(test::get_key<Container>(*it));
@@ -43,9 +43,9 @@
         std::size_t size = x.size();
         while(size > 0 && !x.empty())
         {
- typename Container::key_type key = test::get_key<Container>(*x.begin());
+ BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*x.begin());
             std::size_t count = x.count(key);
- typename Container::iterator pos = x.erase(x.begin());
+ BOOST_DEDUCED_TYPENAME Container::iterator pos = x.erase(x.begin());
             --size;
             BOOST_TEST(pos == x.begin());
             BOOST_TEST(x.count(key) == count - 1);
@@ -63,7 +63,7 @@
         {
             using namespace std;
             int index = rand() % x.size();
- typename Container::const_iterator prev, pos, next;
+ BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
             if(index == 0) {
                 prev = pos = x.begin();
             }
@@ -72,13 +72,13 @@
                 pos = boost::next(prev);
             }
             next = boost::next(pos);
- typename Container::key_type key = test::get_key<Container>(*pos);
+ BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*pos);
             std::size_t count = x.count(key);
             BOOST_TEST(next == x.erase(pos));
             --size;
             if(size > 0)
- BOOST_TEST(next ==
- (index == 0 ? x.begin() : boost::next(prev)));
+ BOOST_TEST(index == 0 ? next == x.begin() :
+ next == boost::next(prev));
             BOOST_TEST(x.count(key) == count - 1);
             BOOST_TEST(x.size() == size);
         }

Modified: branches/unordered/dev/libs/unordered/test/unordered/find_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/find_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/find_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -16,7 +16,7 @@
 template <class X>
 void find_tests1(X*)
 {
- typedef typename X::iterator iterator;
+ typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 
     {
         test::random_values<X> v(500);
@@ -25,12 +25,12 @@
         test::ordered<X> tracker = test::create_ordered(x);
         tracker.insert_range(v.begin(), v.end());
 
- for(typename test::ordered<X>::const_iterator it1 =
+ for(BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 =
                 tracker.begin(); it1 != tracker.end(); ++it1)
         {
- typename X::key_type key = test::get_key<X>(*it1);
+ BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
             iterator pos = x.find(key);
- typename X::const_iterator const_pos = x_const.find(key);
+ BOOST_DEDUCED_TYPENAME X::const_iterator const_pos = x_const.find(key);
             BOOST_TEST(pos != x.end() &&
                     x.key_eq()(key, test::get_key<X>(*pos)));
             BOOST_TEST(const_pos != x_const.end() &&
@@ -40,17 +40,17 @@
 
             test::compare_pairs(x.equal_range(key),
                     tracker.equal_range(key),
- (typename test::non_const_value_type<X>::type*) 0);
+ (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
             test::compare_pairs(x_const.equal_range(key),
                     tracker.equal_range(key),
- (typename test::non_const_value_type<X>::type*) 0);
+ (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
         }
 
         test::random_values<X> v2(500);
- for(typename test::random_values<X>::const_iterator it2 =
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 =
                 v2.begin(); it2 != v2.end(); ++it2)
         {
- typename X::key_type key = test::get_key<X>(*it2);
+ BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2);
             if(tracker.find(test::get_key<X>(key)) == tracker.end())
             {
                 BOOST_TEST(x.find(key) == x.end());
@@ -66,10 +66,10 @@
         X x;
 
         test::random_values<X> v2(5);
- for(typename test::random_values<X>::const_iterator it3 =
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 =
                 v2.begin(); it3 != v2.end(); ++it3)
         {
- typename X::key_type key = test::get_key<X>(*it3);
+ BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
             BOOST_TEST(x.find(key) == x.end());
             BOOST_TEST(x.count(key) == 0);
             std::pair<iterator, iterator> range = x.equal_range(key);

Modified: branches/unordered/dev/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/insert_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/insert_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -21,9 +21,8 @@
 template <class X>
 void unique_insert_tests1(X* = 0)
 {
- typedef typename X::iterator iterator;
+ typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     typedef test::ordered<X> ordered;
- typedef typename test::ordered<X>::iterator ordered_iterator;
 
     std::cerr<<"insert(value) tests for containers with unique keys.\n";
 
@@ -31,14 +30,16 @@
     test::ordered<X> tracker = test::create_ordered(x);
 
     test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
             it != v.end(); ++it)
     {
- typename X::size_type old_bucket_count = x.bucket_count();
+
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
         float b = x.max_load_factor();
 
         std::pair<iterator, bool> r1 = x.insert(*it);
- std::pair<ordered_iterator, bool> r2 = tracker.insert(*it);
+ std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
 
         BOOST_TEST(r1.second == r2.second);
         BOOST_TEST(*r1.first == *r2.first);
@@ -61,14 +62,14 @@
     test::ordered<X> tracker = test::create_ordered(x);
 
     test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
             it != v.end(); ++it)
     {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
         float b = x.max_load_factor();
 
- typename X::iterator r1 = x.insert(*it);
- typename test::ordered<X>::iterator r2 = tracker.insert(*it);
+ BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
+ BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
 
         BOOST_TEST(*r1 == *r2);
 
@@ -84,10 +85,10 @@
 template <class X>
 void insert_tests2(X* = 0)
 {
- typedef typename test::ordered<X> tracker_type;
- typedef typename X::iterator iterator;
- typedef typename X::const_iterator const_iterator;
- typedef typename tracker_type::iterator tracker_iterator;
+ typedef BOOST_DEDUCED_TYPENAME test::ordered<X> tracker_type;
+ typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
+ typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
+ typedef BOOST_DEDUCED_TYPENAME tracker_type::iterator tracker_iterator;
 
     std::cerr<<"insert(begin(), value) tests.\n";
 
@@ -96,10 +97,10 @@
         tracker_type tracker = test::create_ordered(x);
 
         test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
                 it != v.end(); ++it)
         {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
             float b = x.max_load_factor();
 
             iterator r1 = x.insert(x.begin(), *it);
@@ -122,10 +123,10 @@
         tracker_type tracker = test::create_ordered(x);
 
         test::random_values<X> v(100);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
                 it != v.end(); ++it)
         {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
             float b = x.max_load_factor();
 
             const_iterator r1 = x.insert(x_const.end(), *it);
@@ -148,10 +149,10 @@
         tracker_type tracker = test::create_ordered(x);
 
         test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
                 it != v.end(); ++it)
         {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
             float b = x.max_load_factor();
 
             pos = x.insert(pos, *it);
@@ -173,10 +174,10 @@
         tracker_type tracker = test::create_ordered(x);
 
         test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
                 it != v.end(); ++it)
         {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
             float b = x.max_load_factor();
 
             x.insert(it, boost::next(it));
@@ -224,10 +225,10 @@
     test::ordered<X> tracker = test::create_ordered(x);
 
     test::random_values<X> v(1000);
- for(typename test::random_values<X>::iterator it = v.begin();
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
             it != v.end(); ++it)
     {
- typename X::size_type old_bucket_count = x.bucket_count();
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
         float b = x.max_load_factor();
 
         x[it->first] = it->second;
@@ -296,6 +297,5 @@
     associative_insert_range_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
     associative_insert_range_test((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
     associative_insert_range_test((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
-
     return boost::report_errors();
 }

Modified: branches/unordered/dev/libs/unordered/test/unordered/load_factor_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/load_factor_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/load_factor_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -39,10 +39,10 @@
 
     test::random_values<X> values(1000);
 
- for(typename test::random_values<X>::const_iterator
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
             it = values.begin(), end = values.end(); it != end; ++it)
     {
- typename X::size_type old_size = x.size(),
+ BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(),
                  old_bucket_count = x.bucket_count();
         x.insert(*it);
         if(old_size + 1 < b * old_bucket_count)

Modified: branches/unordered/dev/libs/unordered/test/unordered/rehash_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/rehash_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/rehash_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -12,7 +12,7 @@
 test::seed_t seed(2974);
 
 template <class X>
-bool postcondition(X const& x, typename X::size_type n)
+bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
 {
     return x.bucket_count() > x.size() / x.max_load_factor() && x.bucket_count() >= n;
 }

Modified: branches/unordered/dev/libs/unordered/test/unordered/swap_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/swap_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/swap_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -61,9 +61,9 @@
 {
     swap_tests1(ptr);
 
- typedef typename X::hasher hasher;
- typedef typename X::key_equal key_equal;
- typedef typename X::allocator_type allocator_type;
+ typedef BOOST_DEDUCED_TYPENAME X::hasher hasher;
+ typedef BOOST_DEDUCED_TYPENAME X::key_equal key_equal;
+ typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
 
     {
         X x(0, hasher(1), key_equal(1));

Modified: branches/unordered/dev/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- branches/unordered/dev/libs/unordered/test/unordered/unnecessary_copy_tests.cpp (original)
+++ branches/unordered/dev/libs/unordered/test/unordered/unnecessary_copy_tests.cpp 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -7,51 +7,52 @@
 #include <boost/unordered_map.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
-struct count_copies
-{
- static int count;
- count_copies() { ++count; }
- count_copies(count_copies const&) { ++count; }
-private:
- count_copies& operator=(count_copies const&);
-};
-
-#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
-namespace boost {
-#endif
-
-std::size_t hash_value(count_copies const&) {
- return 0;
+namespace test {
+ struct count_copies
+ {
+ static int count;
+ count_copies() { ++count; }
+ count_copies(count_copies const&) { ++count; }
+ private:
+ count_copies& operator=(count_copies const&);
+ };
+
+ bool operator==(test::count_copies const&, test::count_copies const&) {
+ return true;
+ }
 }
 
 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
-}
+namespace boost {
+#else
+namespace test {
 #endif
-
-bool operator==(count_copies const&, count_copies const&) {
- return true;
+ std::size_t hash_value(test::count_copies const&) {
+ return 0;
+ }
 }
 
-int count_copies::count;
+namespace test {
+ int count_copies::count;
 
-template <class T>
-void unnecessary_copy_test(T*)
-{
- count_copies::count = 0;
- T x;
- typename T::value_type a;
- BOOST_TEST(count_copies::count == 1);
- x.insert(a);
- BOOST_TEST(count_copies::count == 2);
+ template <class T>
+ void unnecessary_copy_test(T*)
+ {
+ count_copies::count = 0;
+ T x;
+ BOOST_DEDUCED_TYPENAME T::value_type a;
+ BOOST_TEST(count_copies::count == 1);
+ x.insert(a);
+ BOOST_TEST(count_copies::count == 2);
+ }
 }
 
-
 int main()
 {
- unnecessary_copy_test((boost::unordered_set<count_copies>*) 0);
- unnecessary_copy_test((boost::unordered_multiset<count_copies>*) 0);
- unnecessary_copy_test((boost::unordered_map<int, count_copies>*) 0);
- unnecessary_copy_test((boost::unordered_multimap<int, count_copies>*) 0);
+ test::unnecessary_copy_test((boost::unordered_set<test::count_copies>*) 0);
+ test::unnecessary_copy_test((boost::unordered_multiset<test::count_copies>*) 0);
+ test::unnecessary_copy_test((boost::unordered_map<int, test::count_copies>*) 0);
+ test::unnecessary_copy_test((boost::unordered_multimap<int, test::count_copies>*) 0);
 
     return boost::report_errors();
 }

Modified: branches/unordered/dev/release.sh
==============================================================================
--- branches/unordered/dev/release.sh (original)
+++ branches/unordered/dev/release.sh 2008-01-13 13:07:04 EST (Sun, 13 Jan 2008)
@@ -1,4 +1,4 @@
-TARBALL_DIR=../tarballs
+TARBALL_DIR=../../../../tarballs
 UNORDERED_DST=$TARBALL_DIR/unordered
 
 mkdir -p $TARBALL_DIR


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