diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index a4512c08..99cd6cf1 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -3,6 +3,9 @@ # 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) +path-constant images_location : ../ ; +path-constant admonishment_location : ../../../../doc/src/images ; + xml unordered : unordered.qbk ; boostbook standalone : unordered : admon.graphics.path=images/ @@ -16,8 +19,38 @@ boostbook standalone : unordered : toc.section.depth=1 toc.max.depth=1 + boost.compact.typedef=0 + boost.compact.function=0 + boost.compact.enum=0 + css images + + # PDF Options: + # TOC Generation: this is needed for FOP-0.9 and later: + fop1.extensions=0 + pdf:xep.extensions=1 + # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9! + pdf:fop.extensions=0 + # No indent on body text: + pdf:body.start.indent=0pt + # Margin size: + pdf:page.margin.inner=0.5in + # Margin size: + pdf:page.margin.outer=0.5in + # Paper type = A4 + pdf:paper.type=A4 + # Yes, we want graphics for admonishments: + admon.graphics=1 + # Set this one for PDF generation *only*: + # default png graphics are awful in PDF form, + # better use SVG's instead: + pdf:admon.graphics.extension=".svg" + pdf:use.role.for.mediaobject=1 + pdf:preferred.mediaobject.role=print + pdf:img.src.path=$(images_location)/ + #pdf:admon.graphics.path=$(admonishment_location) + pdf:draft.mode="no" ; install css : [ glob $(BOOST_ROOT)/doc/src/*.css ] diff --git a/doc/bibliography.xml b/doc/bibliography.xml index 9b06b624..9a874073 100644 --- a/doc/bibliography.xml +++ b/doc/bibliography.xml @@ -1,6 +1,6 @@ -
+
+Bibliography - Bibliography C/C++ Users Journal diff --git a/doc/buckets.qbk b/doc/buckets.qbk index b1496dce..92695ad0 100644 --- a/doc/buckets.qbk +++ b/doc/buckets.qbk @@ -10,7 +10,7 @@ boost::unordered_set unordered_set] with 7 buckets containing 5 elements, `A`, `B`, `C`, `D` and `E` (this is just for illustration, containers will typically have more buckets). -[$../../libs/unordered/doc/diagrams/buckets.png] +[diagram buckets] In order to decide which bucket to place an element in, the container applies the hash function, `Hash`, to the element's key (for `unordered_set` and @@ -35,37 +35,53 @@ When looking for elements in this bucket up to 2 comparisons are made, making the search slower. This is known as a collision. To keep things fast we try to keep collisions to a minimum. -[table Methods for Accessing Buckets - [[Method] [Description]] - - [ - [``size_type bucket_count() const``] - [The number of buckets.] - ] - [ - [``size_type max_bucket_count() const``] - [An upper bound on the number of buckets.] - ] - [ - [``size_type bucket_size(size_type n) const``] - [The number of elements in bucket `n`.] - ] - [ - [``size_type bucket(key_type const& k) const``] - [Returns the index of the bucket which would contain k] - ] - [ - [`` - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - ``] - [Return begin and end iterators for bucket `n`.] - ] -] +''' +Methods for Accessing Buckets + + + Method + Description + + + + '''`size_type bucket_count() const`''' + '''The number of buckets.''' + + + '''`size_type max_bucket_count() const`''' + '''An upper bound on the number of buckets.''' + + + '''`size_type bucket_size(size_type n) const`''' + '''The number of elements in bucket `n`.''' + + + '''`size_type bucket(key_type const& k) const`''' + '''Returns the index of the bucket which would contain k''' + + + '''`local_iterator begin(size_type n);`''' + '''Return begin and end iterators for bucket `n`.''' + + + '''`local_iterator end(size_type n);`''' + + + '''`const_local_iterator begin(size_type n) const;`''' + + + '''`const_local_iterator end(size_type n) const;`''' + + + '''`const_local_iterator cbegin(size_type n) const;`''' + + + '''`const_local_iterator cend(size_type n) const;`''' + + + +
+''' [h2 Controlling the number of buckets] @@ -100,19 +116,19 @@ or close to the hint - unless your hint is unreasonably small or large. [[Method] [Description]] [ - [``float load_factor() const``] + [`float load_factor() const`] [The average number of elements per bucket.] ] [ - [``float max_load_factor() const``] + [`float max_load_factor() const`] [Returns the current maximum load factor.] ] [ - [``float max_load_factor(float z)``] + [`float max_load_factor(float z)`] [Changes the container's maximum load factor, using `z` as a hint.] ] [ - [``void rehash(size_type n)``] + [`void rehash(size_type n)`] [Changes the number of buckets so that there at least n buckets, and so that the load factor is less than the maximum load factor.] ] diff --git a/doc/diagrams/buckets.dia b/doc/diagrams/buckets.dia deleted file mode 100644 index b28596c9..00000000 Binary files a/doc/diagrams/buckets.dia and /dev/null differ diff --git a/doc/diagrams/buckets.png b/doc/diagrams/buckets.png index 971c5c29..ba14df79 100644 Binary files a/doc/diagrams/buckets.png and b/doc/diagrams/buckets.png differ diff --git a/doc/diagrams/buckets.svg b/doc/diagrams/buckets.svg new file mode 100644 index 00000000..d16b432c --- /dev/null +++ b/doc/diagrams/buckets.svg @@ -0,0 +1,313 @@ + + + + + + + + Bucket 1 + + + + Bucket 2 + + + + Bucket 3 + + + + Bucket 4 + + + + Bucket 5 + + + + Bucket 6 + + + + Bucket 7 + + + + A + + + B + + + C + + + D + + + E + diff --git a/doc/hash_equality.qbk b/doc/hash_equality.qbk index d9d00ef5..ca69f61f 100644 --- a/doc/hash_equality.qbk +++ b/doc/hash_equality.qbk @@ -63,11 +63,11 @@ won't work on other implementations of the unordered associative containers. [[Method] [Description]] [ - [``hasher hash_function() const``] + [`hasher hash_function() const`] [Returns the container's hash function.] ] [ - [``key_equal key_eq() const``] + [`key_equal key_eq() const`] [Returns the container's key equality function.] ] ] diff --git a/doc/unordered.qbk b/doc/unordered.qbk index c5d77915..e4f2ce6d 100644 --- a/doc/unordered.qbk +++ b/doc/unordered.qbk @@ -17,6 +17,16 @@ ] ] +[template diagram[name] ''' + + + + + + +'''] + + [include:unordered intro.qbk] [include:unordered buckets.qbk] [include:unordered hash_equality.qbk] diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index 5b0776cd..530f5025 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -1648,6 +1648,7 @@ namespace boost { #if BOOST_UNORDERED_EQUIVALENT_KEYS +#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)) // Insert (equivalent key containers) // if hash function throws, basic exception safety @@ -1676,7 +1677,8 @@ namespace boost { return insert_hint_impl(it, a); } -#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL) +#else + // Insert (equivalent key containers) // (I'm using an overloaded insert for both 'insert' and 'emplace') @@ -1850,6 +1852,8 @@ namespace boost { } } +#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)) + // Insert (unique keys) // if hash function throws, basic exception safety @@ -1902,7 +1906,8 @@ namespace boost { return insert(v).first; } -#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL) +#else + // Insert (unique keys) // (I'm using an overloaded insert for both 'insert' and 'emplace') // @@ -1949,10 +1954,8 @@ namespace boost { // Nothing after this point can throw. - link_ptr n = data_.link_node_in_bucket(a, bucket); - - return std::pair( - iterator_base(bucket, n), true); + return std::pair(iterator_base(bucket, + data_.link_node_in_bucket(a, bucket)), true); } } @@ -1993,7 +1996,7 @@ namespace boost { // if hash function throws, basic exception safety // strong otherwise template - iterator_base insert_hint(iterator_base const& it, Args&&... args) + iterator_base insert_hint(iterator_base const&, Args&&... args) { // Life is complicated - just call the normal implementation. return insert(std::forward(args)...).first; @@ -2148,7 +2151,7 @@ private: return it1 == end1 && it2 == end2; } #else - static inline bool group_equals(link_ptr it1, link_ptr it2, + static inline bool group_equals(link_ptr, link_ptr, type_wrapper*) { return true; diff --git a/test/exception/Jamfile.v2 b/test/exception/Jamfile.v2 index b41e9d97..92e25055 100644 --- a/test/exception/Jamfile.v2 +++ b/test/exception/Jamfile.v2 @@ -11,7 +11,7 @@ alias framework : ; project unordered-test/exception-tests : requirements intel-linux:"-strict_ansi -cxxlib-icc" - gcc:-Wsign-promo + gcc:"-Wsign-promo -Wunused-parameter" ; test-suite unordered-exception diff --git a/test/helpers/exception_test.hpp b/test/helpers/exception_test.hpp index b26042f0..8d216cdd 100644 --- a/test/helpers/exception_test.hpp +++ b/test/helpers/exception_test.hpp @@ -210,7 +210,7 @@ namespace test { } template - void exception_safety(Test const& f, char const* name) { + void exception_safety(Test const& f, char const* /*name*/) { test_runner runner(f); iteration = 0; diff --git a/test/objects/memory.hpp b/test/objects/memory.hpp index da2b26ed..29424d84 100644 --- a/test/objects/memory.hpp +++ b/test/objects/memory.hpp @@ -153,12 +153,12 @@ namespace test if(count_allocations > 0) --count_allocations; } - void track_construct(void* ptr, std::size_t /*size*/, int tag) + void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/) { ++count_constructions; } - void track_destroy(void* ptr, std::size_t /*size*/, int tag) + void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/) { BOOST_CHECK(count_constructions > 0); if(count_constructions > 0) --count_constructions; diff --git a/test/unordered/Jamfile.v2 b/test/unordered/Jamfile.v2 index 5851c98d..d913e8e8 100644 --- a/test/unordered/Jamfile.v2 +++ b/test/unordered/Jamfile.v2 @@ -8,7 +8,7 @@ import testing ; project unordered-test/unordered : requirements intel-linux:"-strict_ansi -cxxlib-icc" - gcc:-Wsign-promo + gcc:"-Wsign-promo -Wunused-parameter" #msvc:/W4 ; diff --git a/test/unordered/bucket_tests.cpp b/test/unordered/bucket_tests.cpp index 181ff67c..d8b93d09 100644 --- a/test/unordered/bucket_tests.cpp +++ b/test/unordered/bucket_tests.cpp @@ -16,11 +16,11 @@ namespace bucket_tests { test::seed_t seed(54635); template -void tests(X* = 0) +void tests(X* = 0, test::random_generator generator = test::default_generator) { typedef BOOST_DEDUCED_TYPENAME X::size_type size_type; typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator; - test::random_values v(1000); + test::random_values v(1000, generator); X x(v.begin(), v.end()); diff --git a/test/unordered/compile_tests.hpp b/test/unordered/compile_tests.hpp index c64c67f8..5e65a72d 100644 --- a/test/unordered/compile_tests.hpp +++ b/test/unordered/compile_tests.hpp @@ -149,6 +149,8 @@ void unordered_map_test(X& r, Key const& k, T const& v) typedef BOOST_DEDUCED_TYPENAME X::key_type key_type; BOOST_MPL_ASSERT((boost::is_same >)); + r.insert(std::pair(k, v)); + #if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL) Key k_lvalue(k); T v_lvalue(v); diff --git a/test/unordered/constructor_tests.cpp b/test/unordered/constructor_tests.cpp index 0069ca1f..bdf5cd10 100644 --- a/test/unordered/constructor_tests.cpp +++ b/test/unordered/constructor_tests.cpp @@ -253,12 +253,12 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa } template -void map_constructor_test(T* = 0) +void map_constructor_test(T* = 0, test::random_generator const& generator = test::default_generator) { std::cerr<<"map_constructor_test\n"; typedef test::list > list; - test::random_values v(1000); + test::random_values v(1000, generator); list l(v.begin(), v.end()); T x(l.begin(), l.end()); diff --git a/test/unordered/copy_tests.cpp b/test/unordered/copy_tests.cpp index 7334ceee..30fe55a0 100644 --- a/test/unordered/copy_tests.cpp +++ b/test/unordered/copy_tests.cpp @@ -36,7 +36,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d } { - test::random_values v(1000); + test::random_values v(1000, generator); T x(v.begin(), v.end()); T y(x); @@ -50,7 +50,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d // is much lower than the load factor. The hash table is not allowed // to rehash, but the destination container should probably allocate // enough buckets to decrease the load factor appropriately. - test::random_values v(1000); + test::random_values v(1000, generator); T x(v.begin(), v.end()); x.max_load_factor(x.load_factor() / 4); T y(x); @@ -95,7 +95,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes } { - test::random_values v(1000); + test::random_values v(1000, generator); T x(v.begin(), v.end(), 0, hf, eq, al); T y(x); @@ -106,7 +106,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes } { - test::random_values v(500); + test::random_values v(500, generator); T x(v.begin(), v.end(), 0, hf, eq, al); T y(x, al2); diff --git a/test/unordered/load_factor_tests.cpp b/test/unordered/load_factor_tests.cpp index 0ace667b..d58c13d5 100644 --- a/test/unordered/load_factor_tests.cpp +++ b/test/unordered/load_factor_tests.cpp @@ -34,13 +34,13 @@ void set_load_factor_tests(X* = 0) } template -void insert_test(X*, float mlf) +void insert_test(X*, float mlf, test::random_generator generator = test::default_generator) { X x; x.max_load_factor(mlf); float b = x.max_load_factor(); - test::random_values values(1000); + test::random_values values(1000, generator); for(BOOST_DEDUCED_TYPENAME test::random_values::const_iterator it = values.begin(), end = values.end(); it != end; ++it) diff --git a/test/unordered/move_tests.cpp b/test/unordered/move_tests.cpp index 53f1d662..089f37f3 100644 --- a/test/unordered/move_tests.cpp +++ b/test/unordered/move_tests.cpp @@ -17,7 +17,7 @@ namespace move_tests test::seed_t seed(98624); template - T empty(T* ptr) { + T empty(T*) { return T(); } @@ -61,7 +61,7 @@ namespace move_tests } { - test::random_values v(1000); + test::random_values v(1000, generator); test::object_count count; T y(create(v, count)); BOOST_CHECK(count == test::global_object_count); @@ -71,10 +71,10 @@ namespace move_tests } template - void move_assign_tests1(T* ptr, test::random_generator const& generator = test::default_generator) + void move_assign_tests1(T*, test::random_generator const& generator = test::default_generator) { { - test::random_values v(500); + test::random_values v(500, generator); test::object_count count; T y; y = create(v, count); @@ -85,11 +85,9 @@ namespace move_tests } template - void move_construct_tests2(T* ptr, + void move_construct_tests2(T*, test::random_generator const& generator = test::default_generator) { - move_construct_tests1(ptr); - BOOST_DEDUCED_TYPENAME T::hasher hf(1); BOOST_DEDUCED_TYPENAME T::key_equal eq(1); BOOST_DEDUCED_TYPENAME T::allocator_type al(1); @@ -98,7 +96,7 @@ namespace move_tests test::object_count count; { - test::random_values v(500); + test::random_values v(500, generator); T y(create(v, count, hf, eq, al, 0.5)); BOOST_CHECK(count == test::global_object_count); test::check_container(y, v); @@ -111,7 +109,7 @@ namespace move_tests { // TODO: To do this correctly requires the fancy new allocator stuff. - test::random_values v(500); + test::random_values v(500, generator); T y(create(v, count, hf, eq, al, 2.0), al2); BOOST_CHECK(count != test::global_object_count); test::check_container(y, v); @@ -123,7 +121,7 @@ namespace move_tests } { - test::random_values v(25); + test::random_values v(25, generator); T y(create(v, count, hf, eq, al, 1.0), al); #if defined(BOOST_HAS_RVALUE_REFS) BOOST_CHECK(count == test::global_object_count); diff --git a/test/unordered/rehash_tests.cpp b/test/unordered/rehash_tests.cpp index f4c59822..cfcc41cb 100644 --- a/test/unordered/rehash_tests.cpp +++ b/test/unordered/rehash_tests.cpp @@ -33,9 +33,9 @@ void rehash_empty_test1(X* = 0) } template -void rehash_test1(X* = 0) +void rehash_test1(X* = 0, test::random_generator generator = test::default_generator) { - test::random_values v(1000); + test::random_values v(1000, generator); test::ordered tracker; tracker.insert_range(v.begin(), v.end()); X x(v.begin(), v.end()); diff --git a/test/unordered/swap_tests.cpp b/test/unordered/swap_tests.cpp index 4bc39bfb..a036362c 100644 --- a/test/unordered/swap_tests.cpp +++ b/test/unordered/swap_tests.cpp @@ -32,7 +32,7 @@ void swap_test_impl(X& x1, X& x2) } template -void swap_tests1(X* = 0) +void swap_tests1(X*, test::random_generator generator = test::default_generator) { { X x; @@ -45,14 +45,14 @@ void swap_tests1(X* = 0) } { - test::random_values v(1000); + test::random_values v(1000, generator); X x, y(v.begin(), v.end()); swap_test_impl(x, y); swap_test_impl(x, y); } { - test::random_values vx(1000), vy(1000); + test::random_values vx(1000, generator), vy(1000, generator); X x(vx.begin(), vx.end()), y(vy.begin(), vy.end()); swap_test_impl(x, y); swap_test_impl(x, y); @@ -60,7 +60,7 @@ void swap_tests1(X* = 0) } template -void swap_tests2(X* ptr = 0) +void swap_tests2(X* ptr = 0, test::random_generator generator = test::default_generator) { swap_tests1(ptr); @@ -75,14 +75,14 @@ void swap_tests2(X* ptr = 0) } { - test::random_values v(1000); + test::random_values v(1000, generator); X x(v.begin(), v.end(), 0, hasher(1), key_equal(1)); X y(0, hasher(2), key_equal(2)); swap_test_impl(x, y); } { - test::random_values vx(100), vy(50); + test::random_values vx(100, generator), vy(50, generator); X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1)); X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2)); swap_test_impl(x, y); @@ -91,7 +91,7 @@ void swap_tests2(X* ptr = 0) #if BOOST_UNORDERED_SWAP_METHOD == 1 { - test::random_values vx(100), vy(50); + test::random_values vx(100, generator), vy(50, generator); X x(vx.begin(), vx.end(), 0, hasher(), key_equal(), allocator_type(1)); X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2)); try { @@ -101,14 +101,14 @@ void swap_tests2(X* ptr = 0) } #else { - test::random_values vx(50), vy(100); + test::random_values vx(50, generator), vy(100, generator); X x(vx.begin(), vx.end(), 0, hasher(), key_equal(), allocator_type(1)); X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2)); swap_test_impl(x, y); } { - test::random_values vx(100), vy(100); + test::random_values vx(100, generator), vy(100, generator); X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1), allocator_type(1)); X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2), allocator_type(2)); swap_test_impl(x, y);