...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
insert
in non-unique ordered indices to preserve insertion order
of equivalent elements
(issue #68).
std::size_t
instead of unsigned long
to save and load the size of a multi_index_container
(unsigned long
is smaller than std::size_t
in LLP64 data models).
multi_index_container
serialization
class version has been
bumped from 3 to 4 to reflect this change.
unsigned long
instead of
collection_size_type
,
and multi_index_container
serialization
class version has been
bumped from 2 to 3 to reflect this change.
Reading old archives may fail for custom archive types giving special treatment to
collection_size_type
values: if this is the case, globally define
the macro BOOST_MULTI_INDEX_ENABLE_SERIALIZATION_COMPATIBILITY_V2
to ensure backwards compatibility in reading operations.
count
operations in ranked indices from
O(log(n) + count)
to O(log(n))
.
Contributed by Damian Sawicki.
contains
to key-based indices
(issue #35).
merge
operations to key-based indices. The functionality goes beyond
the standard specification for (unordered) associative containers in a number of ways,
most notably:
x.merge(y,first,last)
merges only the elements of y
within [first
,last
).
splice
for sequenced and random access indices
were destructive, i.e. elements were copy-inserted into the destination and then erased
from the source. Now, splice
is based on node transfer much as merge
in key-based indices, and has been similarly extended to accept source indices of any type:
in fact, splice
can be regarded as a frontend to the same functionality
provided by merge
in key-based indices. For reasons of backwards compatibility,
the destructive behavior of splice
has been retained in the case that the
source and destination containers have unequal allocators.
node_type
and the position of the index in its multi_index_container
,
(except for hashed indices, where uniqueness/non-uniqueness is also a dependency). This has
implications on the validity of iterators to elements transferred by merge
or
splice
. This property is a variant of what has been called
SCARY iterators in the C++ standard mailing lists.
SCARYness is currently (August 2021) not mandated for standard containers.
multi_index_container
is now
AllocatorAware
.
KeyFromValue
, Compare
, Hash
and Pred
objects now selects the appropriate swap
function between std::swap
and ADL candidates,
in accordance with standard specifications in [swappable.requirements]
(issue #29).
const_mem_fun
and mem_fun
for
differently qualified member functions
(issue #24).
noexcept
-specified member functions
(issue #24).
size_type
and difference_type
are now
defined as the allocator's same-named types. This will not make any
difference in the vast majority of cases, but allows for some degree
of control of resulting internal structures via user-defined allocator
types (see
issue #17
for motivation). For the moment being, this change is not
documented in the reference section (i.e., it has semi-official status).
multi_index_container
's default constructor is no longer
explicit
(ticket #13518).
operator&
are now fully accepted
(ticket #13307).
Thanks to Daniel Frey for his updating
Boost.Operators to help
fix this issue.
std::allocator
members deprecated in C++17.
Contributed by Daniela Engert.
modify
and modify_key
more robust so that
the modified element is erased if the modifier throws or the rollback
functor does not properly restore the element (full discussion at
ticket #12542).
This is technically backwards incompatible; for instance, the following code:
keeps the containerc.modify(c.begin(),[](auto&){throw 0;});
c
untouched in former versions of Boost whereas
now c.begin()
is erased. Thanks to Jon Kalb for raising the issue.
foreach
in this framework.
key_type
. Consider for instance
the following code:
In previous versions of the library, thetypedef multi_index_container< std::string, indexed_by< ordered_unique<identity<std::string> > > > multi_t; ... multi_t m=...; m.find("boost"); // passed a const char*, not a std::string
find
operation generates
several temporary std::string
s (one every time an internal comparison is made).
In sufficiently advanced compilers, this is now avoided so that only one temporary is
created.
std::tuple
s are available, these can be used for lookup operations
in indices equipped with composite keys. boost::tuple
s are also supported
for backwards compatibility.
erase(iterator)
member function of hashed indices
used to have poor performance under low load conditions due to the requirement
that an iterator to the next element must be returned (see ticket
#4264). In accordance with
the resolution of LWG
issue #579, this problem has been fixed while maintaining the interface of
erase
, at the expense of using one more
word of memory per element. In fact, C++ complexity requirements on unordered
associative containers have been improved for hashed indices so that
O(n)
but O(ndist)
,
where ndist
is the number of non-equivalent elements in the index.
reserve
.noexcept
specifications
where appropriate (for compliant compilers).
multi_index_container
.BOOST_BIND_NO_PLACEHOLDERS
(ticket #9798).
multi_index_container
is now efficiently movable.std::unique_ptr<T>
) supported. This includes
insertion of a range [first
,last
) where the iterators point to a type that is
convertible to that of the element: no copy construction happens in the process.
shrink_to_fit()
.
composite_key_compare
related with Boost.Ref.
modify_key
with
rollback in ordered and
hashed indices when
Modifier
and Rollback
are different types
(ticket #4130).
save_construct_data
and
load_construct_data
.
multi_index_container
serialization
class version has been
bumped from 1 to 2.
collection_size_type
type instead of the original std::size_t
(ticket
#3365).
multi_index_container
serialization
class version has been
bumped from 0 to 1.
nth_index_iterator<MultiIndexContainer,N>::type
,multi_index_container<...>::nth_index_iterator<N>::type
,nth_index_const_iterator<MultiIndexContainer,N>::type
,multi_index_container<...>::nth_index_const_iterator<N>::type
,index_iterator<MultiIndexContainer,Tag>::type
,multi_index_container<...>::index_iterator<Tag>::type
,index_const_iterator<MultiIndexContainer,Tag>::type
,multi_index_container<...>::index_const_iterator<Tag>::type
.nth_index<MultiIndexContainer,N>::type::iterator
,multi_index_container<...>::nth_index<N>::type::iterator
,nth_index<MultiIndexContainer,N>::type::const_iterator
,multi_index_container<...>::nth_index<N>::type::const_iterator
,index<MultiIndexContainer,Tag>::type::iterator
,multi_index_container<...>::index<Tag>::type::iterator
,index<MultiIndexContainer,Tag>::type::const_iterator
,multi_index_container<...>::index<Tag>::type::const_iterator
.
multi_index_container::multi_index_container(const allocator_type&)
to mimic the equivalent interface in STL sequence containers.
global_fun
predefined key extractor.
iterator_to
facility.
multi_index_container
s placeable in shared memory.
modify
and modify_key
with
rollback, as described in the
tutorial.
cbegin
, cend
and,
when applicable, crbegin
and crend
member functions, in accordance with the latest drafts of the next
revision of the C++ standard.
assign(f,l)
and insert(p,f,l)
(23.1.1/9): if
f
and l
are of the same integral type, the
iterator-based overloads of these member functions are avoided:
typedef multi_index_container< int,indexed_by<sequenced<> > > sequenced_container; std::list<int> l(...); sequenced_container c; // iterator-based overload of assign c.assign(l.begin(),l.end()); // The following is equivalent to // c.assign( // static_cast<sequenced_container::size_type>(10),100); // that is, "10" and "100" are not taken to be iterators as // in the previous expression. c.assign(10,100);
range
and
equal_range
has been improved.
T
can handle objects of types
derived from or convertible to T
(and
chained pointers
to those). Previously, only objects of the exact type specified (along with
reference_wrapper
s and chained pointers to them) were accepted.
composite_key_compare
and related classes accept operands not included in tuples as if they were passed
in a tuple of length 1; this allows the user to omit tuple enclosing in
lookup operations involving composite keys when only the first key is provided.
erase(it)
and
erase(first,last)
now return an iterator to the element
following those being deleted (previously nothing was returned), in
accordance with the C++ Standard Library
Defect
Report 130 and issue 6.19 of TR1
Issues
List.
multi_index_container
s and clear
memfuns now perform faster.
Revised March 15th 2024
© Copyright 2003-2024 Joaquín M López Muñoz. 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)