123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- [/ Copyright 2011 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:compliance Standard Compliance]
- The intent of Boost.Unordered is to implement a close (but imperfect)
- implementation of the C++17 standard, that will work with C++98 upwards.
- The wide compatibility does mean some comprimises have to be made.
- With a compiler and library that fully support C++11, the differences should
- be minor.
- [section:move Move emulation]
- Support for move semantics is implemented using Boost.Move. If rvalue
- references are available it will use them, but if not it uses a close,
- but imperfect emulation. On such compilers:
- * Non-copyable objects can be stored in the containers.
- They can be constructed in place using `emplace`, or if they support
- Boost.Move, moved into place.
- * The containers themselves are not movable.
- * Argument forwarding is not perfect.
- [endsect]
- [section:allocator_compliance Use of allocators]
- C++11 introduced a new allocator system. It's backwards compatible due to
- the lax requirements for allocators in the old standard, but might need
- some changes for allocators which worked with the old versions of the
- unordered containers.
- It uses a traits class, `allocator_traits` to handle the allocator
- adding extra functionality, and making some methods and types optional.
- During development a stable release of
- `allocator_traits` wasn't available so an internal partial implementation
- is always used in this version. Hopefully a future version will use the
- standard implementation where available.
- The member functions `construct`, `destroy` and `max_size` are now
- optional, if they're not available a fallback is used.
- A full implementation of `allocator_traits` requires sophisticated
- member function detection so that the fallback is used whenever the
- member function call is not well formed.
- This requires support for SFINAE expressions, which are available on
- GCC from version 4.4 and Clang.
- On other compilers, there's just a test to see if the allocator has
- a member, but no check that it can be called. So rather than using a
- fallback there will just be a compile error.
- `propagate_on_container_copy_assignment`,
- `propagate_on_container_move_assignment`,
- `propagate_on_container_swap` and
- `select_on_container_copy_construction` are also supported.
- Due to imperfect move emulation, some assignments might check
- `propagate_on_container_copy_assignment` on some compilers and
- `propagate_on_container_move_assignment` on others.
- [endsect]
- [section:construction Construction/Destruction using allocators]
- The following support is required for full use of C++11 style
- construction/destruction:
- * Variadic templates.
- * Piecewise construction of `std::pair`.
- * Either `std::allocator_traits` or expression SFINAE.
- This is detected using Boost.Config. The macro
- `BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0
- otherwise.
- When this is the case `allocator_traits::construct` and
- `allocator_traits::destroy` will always be used, apart from when piecewise
- constructing a `std::pair` using `boost::tuple` (see [link
- unordered.compliance.pairs below]), but that should be easily avoided.
- When support is not available `allocator_traits::construct` and
- `allocator_traits::destroy` are never called.
- [endsect]
- [section:pointer_traits Pointer Traits]
- `pointer_traits` aren't used. Instead, pointer types are obtained from
- rebound allocators, this can cause problems if the allocator can't be
- used with incomplete types. If `const_pointer` is not defined in the
- allocator, `boost::pointer_to_other<pointer, const value_type>::type`
- is used to obtain a const pointer.
- [endsect]
- [#unordered.compliance.pairs]
- [section:pairs Pairs]
- Since the containers use `std::pair` they're limited to the version
- from the current standard library. But since C++11 `std::pair`'s
- `piecewise_construct` based constructor is very useful, `emplace`
- emulates it with a `piecewise_construct` in the `boost::unordered`
- namespace. So for example, the following will work:
- boost::unordered_multimap<std::string, std::complex> x;
- x.emplace(
- boost::unordered::piecewise_construct,
- boost::make_tuple("key"), boost::make_tuple(1, 2));
- Older drafts of the standard also supported variadic constructors
- for `std::pair`, where the first argument would be used for the
- first part of the pair, and the remaining for the second part.
- [endsect]
- [section:misc Miscellaneous]
- When swapping, `Pred` and `Hash` are not currently swapped by calling
- `swap`, their copy constructors are used. As a consequence when swapping
- an exception may be thrown from their copy constructor.
- Variadic constructor arguments for `emplace` are only used when both
- rvalue references and variadic template parameters are available.
- Otherwise `emplace` can only take up to 10 constructors arguments.
- [endsect]
- [endsect]
|