mirror of
https://github.com/boostorg/container.git
synced 2025-08-03 22:44:26 +02:00
Add variant of map constructors to avoid useless extra allocator copy when using initializer list
Many existing constructors have this form: map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) The issue is that a temporary allocator_type is constructed, and passed to the base class where it is used to copy-constructed the rebound allocator. This temporary allocator_type here is always destroyed at the end of the map() constructor. For stateful allocators this is not desirable. The solution is to adopt what libc++ is doing and have to constructors: map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a) and map(std::initializer_list<value_type> il, const Compare& comp = Compare()) This way, unless an allocator is provided by the client, no extra temporary creation/destruction occurs.
This commit is contained in:
@@ -519,7 +519,7 @@ class tree
|
|||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||||
const allocator_type& a
|
const allocator_type& a = allocator_type()
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
, typename container_detail::enable_if_or
|
, typename container_detail::enable_if_or
|
||||||
< void
|
< void
|
||||||
@@ -548,7 +548,7 @@ class tree
|
|||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
|
||||||
const allocator_type& a
|
const allocator_type& a = allocator_type()
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
, typename container_detail::disable_if_or
|
, typename container_detail::disable_if_or
|
||||||
< void
|
< void
|
||||||
|
@@ -153,13 +153,24 @@ class map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
explicit map(const Compare& comp, const allocator_type& a = allocator_type())
|
explicit map(const Compare& comp, const allocator_type& a)
|
||||||
: base_t(comp, a)
|
: base_t(comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty map using the specified comparison object.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
explicit map(const Compare& comp)
|
||||||
|
: base_t(comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
|
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
@@ -178,14 +189,28 @@ class map
|
|||||||
//! comp and otherwise N logN, where N is last - first.
|
//! comp and otherwise N logN, where N is last - first.
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
map(InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
map(InputIterator first, InputIterator last, const Compare& comp,
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(true, first, last, comp, a)
|
: base_t(true, first, last, comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||||
|
//! inserts elements from the range [first ,last ).
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||||
|
//! comp and otherwise N logN, where N is last - first.
|
||||||
|
template <class InputIterator>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
map(InputIterator first, InputIterator last, const Compare& comp = Compare())
|
||||||
|
: base_t(true, first, last, comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs an empty map using the specified
|
//! <b>Effects</b>: Constructs an empty map using the specified
|
||||||
//! allocator, and inserts elements from the range [first ,last ).
|
//! allocator, and inserts elements from the range [first ,last ).
|
||||||
//!
|
//!
|
||||||
@@ -213,13 +238,33 @@ class map
|
|||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
map( ordered_unique_range_t, InputIterator first, InputIterator last
|
map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||||
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
, const Compare& comp, const allocator_type& a)
|
||||||
: base_t(ordered_range, first, last, comp, a)
|
: base_t(ordered_range, first, last, comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||||
|
//! inserts elements from the ordered unique range [first ,last). This function
|
||||||
|
//! is more efficient than the normal range creation for ordered ranges.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
|
||||||
|
//! unique values.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: Non-standard extension.
|
||||||
|
template <class InputIterator>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
map( ordered_unique_range_t, InputIterator first, InputIterator last
|
||||||
|
, const Compare& comp = Compare())
|
||||||
|
: base_t(ordered_range, first, last, comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||||
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
||||||
@@ -227,13 +272,26 @@ class map
|
|||||||
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||||
//! comp and otherwise N logN, where N is il.first() - il.end().
|
//! comp and otherwise N logN, where N is il.first() - il.end().
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
|
map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||||
: base_t(true, il.begin(), il.end(), comp, a)
|
: base_t(true, il.begin(), il.end(), comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||||
|
//! inserts elements from the range [il.begin(), il.end()).
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||||
|
//! comp and otherwise N logN, where N is il.first() - il.end().
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
map(std::initializer_list<value_type> il, const Compare& comp = Compare())
|
||||||
|
: base_t(true, il.begin(), il.end(), comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs an empty map using the specified
|
//! <b>Effects</b>: Constructs an empty map using the specified
|
||||||
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
||||||
//!
|
//!
|
||||||
@@ -259,12 +317,30 @@ class map
|
|||||||
//! <b>Note</b>: Non-standard extension.
|
//! <b>Note</b>: Non-standard extension.
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
|
||||||
|
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
|
||||||
|
//! is more efficient than the normal range creation for ordered ranges.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
|
||||||
|
//! unique values.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: Non-standard extension.
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare())
|
||||||
|
: base_t(ordered_range, il.begin(), il.end(), comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! <b>Effects</b>: Copy constructs a map.
|
//! <b>Effects</b>: Copy constructs a map.
|
||||||
@@ -1268,14 +1344,29 @@ class multimap
|
|||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
multimap(InputIterator first, InputIterator last,
|
multimap(InputIterator first, InputIterator last,
|
||||||
const Compare& comp = Compare(),
|
const Compare& comp,
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(false, first, last, comp, a)
|
: base_t(false, first, last, comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
||||||
|
//! inserts elements from the range [first ,last ).
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||||
|
//! comp and otherwise N logN, where N is last - first.
|
||||||
|
template <class InputIterator>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
multimap(InputIterator first, InputIterator last,
|
||||||
|
const Compare& comp = Compare())
|
||||||
|
: base_t(false, first, last, comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs an empty multimap using the specified
|
//! <b>Effects</b>: Constructs an empty multimap using the specified
|
||||||
//! allocator, and inserts elements from the range [first ,last ).
|
//! allocator, and inserts elements from the range [first ,last ).
|
||||||
//!
|
//!
|
||||||
@@ -1299,11 +1390,25 @@ class multimap
|
|||||||
//!
|
//!
|
||||||
//! <b>Note</b>: Non-standard extension.
|
//! <b>Note</b>: Non-standard extension.
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
|
BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp,
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(ordered_range, first, last, comp, a)
|
: base_t(ordered_range, first, last, comp, a)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
||||||
|
//! inserts elements from the ordered range [first ,last). This function
|
||||||
|
//! is more efficient than the normal range creation for ordered ranges.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: Non-standard extension.
|
||||||
|
template <class InputIterator>
|
||||||
|
BOOST_CONTAINER_FORCEINLINE multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare())
|
||||||
|
: base_t(ordered_range, first, last, comp)
|
||||||
|
{}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
||||||
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
||||||
@@ -1312,13 +1417,26 @@ class multimap
|
|||||||
//! comp and otherwise N logN, where N is il.first() - il.end().
|
//! comp and otherwise N logN, where N is il.first() - il.end().
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(false, il.begin(), il.end(), comp, a)
|
: base_t(false, il.begin(), il.end(), comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
||||||
|
//! inserts elements from the range [il.begin(), il.end()).
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||||
|
//! comp and otherwise N logN, where N is il.first() - il.end().
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
multimap(std::initializer_list<value_type> il, const Compare& comp = Compare())
|
||||||
|
: base_t(false, il.begin(), il.end(), comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs an empty multimap using the specified
|
//! <b>Effects</b>: Constructs an empty multimap using the specified
|
||||||
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
//! allocator, and inserts elements from the range [il.begin(), il.end()).
|
||||||
//!
|
//!
|
||||||
@@ -1343,12 +1461,29 @@ class multimap
|
|||||||
//! <b>Note</b>: Non-standard extension.
|
//! <b>Note</b>: Non-standard extension.
|
||||||
BOOST_CONTAINER_FORCEINLINE
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
|
||||||
const allocator_type& a = allocator_type())
|
const allocator_type& a)
|
||||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||||
{
|
{
|
||||||
//A type must be std::pair<CONST Key, T>
|
//A type must be std::pair<CONST Key, T>
|
||||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
|
||||||
|
//! inserts elements from the ordered range [il.begin(), il.end()). This function
|
||||||
|
//! is more efficient than the normal range creation for ordered ranges.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear in N.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: Non-standard extension.
|
||||||
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
|
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare())
|
||||||
|
: base_t(ordered_range, il.begin(), il.end(), comp)
|
||||||
|
{
|
||||||
|
//A type must be std::pair<CONST Key, T>
|
||||||
|
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! <b>Effects</b>: Copy constructs a multimap.
|
//! <b>Effects</b>: Copy constructs a multimap.
|
||||||
|
Reference in New Issue
Block a user