Fix a couple of typos.

[SVN r4406]
This commit is contained in:
Daniel James
2007-05-31 22:32:06 +00:00
parent 42f319eb6d
commit ddb67a849d
2 changed files with 302 additions and 0 deletions

162
doc/comparison.qbk Normal file
View File

@ -0,0 +1,162 @@
[/ 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) ]
[section:comparison Comparison with Associative Containers]
[table Interface differences.
[[Associative Containers] [Unordered Associative Containers]]
[
[Parameterized by an ordering relation `Compare`]
[Parameterized by a function object `Hash` and an equivalence relation
`Pred`]
]
[
[`Compare` exposed by member typedef `key_compare`, accessed by member function `key_comp()`]
[`Hash` exposed by member typedef `hasher`, accessed by member function `hash_function()`.\n`Pred` by member typedef `key_equal` and member function `key_eq()`.]
]
[
[Member typedef `value_compare` supplies an ordering comparison for member elements, accessed by member function `value_comp()`.]
[No equivalent. No idea why.]
]
[/TODO: Mention a range? This is meant to be differences but this doesn't
seem to be complete.]
[
[Constructors have optional extra parameters for the comparison object.]
[Constructors have optional extra parameters for the initial minimum
number of buckets, a hash function and an equality object.]
]
[
[Keys `k1`, `k2` are considered equivalent if
`!Compare(k1, k2) && !Compare(k2, k1)`]
[Keys `k1`, `k2` are considered equivalent if `Pred(k1, k2)`]
]
[
[Member function `lower_bound(k)` and `upper_bound(k)`]
[No equivalent. Since the elements aren't ordered `lower_bound` and
`upper_bound` would be meaningless.]
]
[
[`equal_range(k)` returns an empty range at the position that k
would be inserted if k isn't present in the container.]
[`equal_range(k)` returns a range at the end of the container if
k isn't present in the container. It can't return a positioned
range as k could be inserted into multiple place. To find out the
bucket that k would be inserted into use `bucket(k)`. But remember
that an insert can cause the container to rehash - meaning that the
element can be inserted into a different bucket.]
]
[
[`iterator`, `const_iterator` are of the biderctional category.]
[`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 iterate through the container in the order defined by
the comparison object.]
[Iterators iterate through the container in an arbitrary order, that
can change as elements are inserted. Although, equivalent elements
are always adjacent.]
]
[
[No equivalent]
[Local iterators can be used to iterate through individual buckets.
(I don't think that the order of local iterators and iterators are
required to have any correspondence.)]
]
[
[Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators]
[No comparison operators are defined]
]
[
[]
[When inserting with a hint, implementations are permitted to ignore
the hint.]
]
[
[`erase` never throws an exception]
[The containers hash or predicate function can throw exceptions
from `erase`]
]
]
[table Complexity Guarantees
[[Operation] [Associative Containers] [Unordered Associative Containers]]
[
[Construction of empty container]
[constant]
[/TODO: Do I meet this?]
[O(/n/) where /n/ is the minimum number of buckets.]
]
[
[Construction of container from a range of /N/ elements]
[O(/N/ log /N/), O(/N/) if the range is sorted with `value_comp()`]
[Average case O(/N/), worst case
O(/N/'''<superscript>2</superscript>''')]
]
[
[Insert a single element]
[logarithmic]
[Average case constant, worst case linear]
]
[
[Insert a single element with a hint]
[Amortized constant if t elements inserted right after hint,
logarithmic otherwise]
[Average case constant, worst case linear (ie. the same as
a normal insert).]
]
[
[Inserting a range of /N/ elements]
[/N/ log(`size()`+/N/)]
[Average case O(/N/), worst case O(/N/ * 'size()')]
]
[
[Erase by key, `k`]
[O(log(`size()`) + `count(k)`)]
[Average case: O(`count(k)`), Worst case: O(`size()`)]
]
[
[Erase a single element by iterator]
[Amortized constant]
[Average case: O(1), Worst case: O(`size()`)]
]
[
[Erase a range of /N/ elements]
[O(log(`size()`) + /N/)]
[Average case: O(/N/), Worst case: O(`size()`)]
]
[
[Clearing the container]
[O(`size()`)]
[O(`size()`)]
]
[
[Find]
[logarithmic]
[Average case: O(/N/), Worst case: O(`size()`)]
]
[/ TODO: Average case is probably wrong. ]
[
[Count]
[O(log(`size()`) + `count(k)`)]
[Average case: O(1), Worst case: O(`size()`)]
]
[
[`equal_range(k)`]
[logarithmic]
[Average case: O(`count(k)`), Worst case: O(`size()`)]
]
[
[`lower_bound`,`upper_bound`]
[logarithmic]
[n/a]
]
]
[endsect]

140
doc/hash_equality.qbk Normal file
View File

@ -0,0 +1,140 @@
[/ 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) ]
[section:hash_equality Equality Predicates and Hash Functions]
[/TODO: A better introduction to hash functions?]
While the associative containers use an ordering relation to specify how the
elements are stored, the unordered associative containers use an equality
predicate and a hash function. For example [classref boost::unordered_set]
is declared as:
template<typename Value,
typename Hash = ``[classref boost::hash]``<Value>,
typename Pred = std::equal_to<Value>,
typename Alloc = std::allocator<Value> >
class ``[classref boost::unordered_set unordered_set]``;
The hash function comes first as you might want to change the hash function
but not the equality predicate, while if you were to change the behaviour
of the equality predicate you would have to change the hash function to match
it.
For example, if you wanted to use the
[@http://www.isthe.com/chongo/tech/comp/fnv/ FNV-1 hash] you could write:
``[classref boost::unordered_set]``<std::string, hash::fnv_1> words;
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. For example, a
case-insensitive dictionary:
struct iequal_to
: std::binary_function<std::string, std::string, bool>
{
bool operator()(std::string const& x,
std::string const& y) const
{
return boost::algorithm::iequals(x, y);
}
};
struct ihash
: std::unary_function<std::string, bool>
{
bool operator()(std::string const& x) const
{
std::size_t seed = 0;
for(std::string::const_iterator it = x.begin();
it != x.end(); ++it)
{
boost::hash_combine(seed, std::toupper(*it));
}
return seed;
}
};
struct word_info;
boost::unordered_map<std::string, word_info, ihash, iequal_to>
idictionary;
A more generic version of this example is available at:
[@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
[h2 Custom Types]
Similarly, a custom hash function can be used for custom types:
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
struct point_hash
: std::unary_function<point, std::size_t>
{
std::size_t operator()(point const& p) const
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
}
boost::unordered_multiset<point, std::equal_to<point>, point_hash>
points;
Although, customizing Boost.Hash is probably a better solution:
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
std::size_t hash_value(point const& x) {
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
// Now the default functions work.
boost::unordered_multiset<point> points;
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.
[table Methods for accessing the hash and equality functions.
[[Method] [Description]]
[
[``hasher hash_function() const``]
[Returns the container's hash function.]
]
[
[``key_equal key_eq() const``]
[Returns the container's key equality function.]
]
]
[endsect]