diff --git a/doc/comparison.qbk b/doc/comparison.qbk index 3fc88b0b..77c503b9 100644 --- a/doc/comparison.qbk +++ b/doc/comparison.qbk @@ -1,27 +1,164 @@ [section:comparison Comparison with Associative Containers] -* The elements in an unordered container are organised into buckets, in an - unpredictable order. There are member functions to access these buckets which - was described earlier. -* The unordered associative containers don't support any comparison operators. -* Instead of being parameterized by an ordering relation `Compare`, - the unordered associative container are parameterized by a function object - `Hash` and an equivalence realtion `Pred`. The member types and accessor - member functions reflect this. -* Because of this, equivalent keys for unordered container are defined in - terms of `Pred`, while for the associative containers it's defined in terms - of `Compare`. -* Unordered associative containers' iterators can be invalidated by rehashing - or by inserting elements. -* Unordered associative containers' iterators are of at least the forward - iterator category. Associative containers' iterators are bidirectional. -* The unordered associative containers' constructors have extra parameters - for the number of buckets, the hash function and the equality predicate. -* The unordered associative container don't have a `lower_bound` or - `upper_bound` method - they wouldn't make any sense since the elements - aren't ordered. -* TODO: Complexity guarantees. -* TODO: Behaviour when exceptions throw. The unordered containers seem - a lot stronger defined here? +TODO: This page probably contains too much information. Some of the comparisons +can probably be paired down (especially the complexity stuff) and some of the +extra details belong elsewhere. + +TODO: I've omitted some similarities - perhaps I should include them. + +[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 Guarantess + [[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/'''2''')] + ] + [ + [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]