mirror of
https://github.com/boostorg/container.git
synced 2026-01-19 04:02:17 +00:00
Add C++26 transparent "try_emplace" to map and flat_map
This commit is contained in:
@@ -1046,7 +1046,7 @@ class flat_tree
|
|||||||
{
|
{
|
||||||
std::pair<iterator,bool> ret;
|
std::pair<iterator,bool> ret;
|
||||||
insert_commit_data data;
|
insert_commit_data data;
|
||||||
const key_type & k = key;
|
const typename remove_cvref<KeyType>::type & k = key; //Support emulated rvalue references
|
||||||
ret.second = hint == const_iterator()
|
ret.second = hint == const_iterator()
|
||||||
? this->priv_insert_unique_prepare(k, data)
|
? this->priv_insert_unique_prepare(k, data)
|
||||||
: this->priv_insert_unique_prepare(hint, k, data);
|
: this->priv_insert_unique_prepare(hint, k, data);
|
||||||
@@ -1112,7 +1112,7 @@ class flat_tree
|
|||||||
{\
|
{\
|
||||||
std::pair<iterator,bool> ret;\
|
std::pair<iterator,bool> ret;\
|
||||||
insert_commit_data data;\
|
insert_commit_data data;\
|
||||||
const key_type & k = key;\
|
const typename remove_cvref<KeyType>::type & k = key;\
|
||||||
ret.second = hint == const_iterator()\
|
ret.second = hint == const_iterator()\
|
||||||
? this->priv_insert_unique_prepare(k, data)\
|
? this->priv_insert_unique_prepare(k, data)\
|
||||||
: this->priv_insert_unique_prepare(hint, k, data);\
|
: this->priv_insert_unique_prepare(hint, k, data);\
|
||||||
|
|||||||
@@ -1007,10 +1007,10 @@ class tree
|
|||||||
(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
|
(const_iterator hint, BOOST_FWD_REF(KeyType) key, BOOST_FWD_REF(Args)... args)
|
||||||
{
|
{
|
||||||
insert_commit_data data;
|
insert_commit_data data;
|
||||||
const key_type & k = key; //Support emulated rvalue references
|
const typename remove_cvref<KeyType>::type & k = key; //Support emulated rvalue references
|
||||||
std::pair<iiterator, bool> ret =
|
std::pair<iiterator, bool> ret =
|
||||||
hint == const_iterator() ? this->icont().insert_unique_check( k, data)
|
hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)
|
||||||
: this->icont().insert_unique_check(hint.get(), k, data);
|
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);
|
||||||
if(ret.second){
|
if(ret.second){
|
||||||
ret.first = this->icont().insert_unique_commit
|
ret.first = this->icont().insert_unique_commit
|
||||||
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key), boost::forward<Args>(args)...), data);
|
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key), boost::forward<Args>(args)...), data);
|
||||||
@@ -1055,10 +1055,10 @@ class tree
|
|||||||
try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
try_emplace(const_iterator hint, BOOST_FWD_REF(KeyType) key BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||||
{\
|
{\
|
||||||
insert_commit_data data;\
|
insert_commit_data data;\
|
||||||
const key_type & k = key;\
|
const typename remove_cvref<KeyType>::type & k = key;\
|
||||||
std::pair<iiterator, bool> ret =\
|
std::pair<iiterator, bool> ret =\
|
||||||
hint == const_iterator() ? this->icont().insert_unique_check( k, data)\
|
hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)\
|
||||||
: this->icont().insert_unique_check(hint.get(), k, data);\
|
: this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);\
|
||||||
if(ret.second){\
|
if(ret.second){\
|
||||||
ret.first = this->icont().insert_unique_commit\
|
ret.first = this->icont().insert_unique_commit\
|
||||||
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\
|
(*AllocHolder::create_node(try_emplace_t(), boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\
|
||||||
|
|||||||
@@ -842,12 +842,14 @@ class flat_map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Logarithmic in the size of the container.
|
//! <b>Complexity</b>: Logarithmic in the size of the container.
|
||||||
template <class K, class M>
|
template <class K, class M>
|
||||||
BOOST_CONTAINER_DOC1ST
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
( std::pair<iterator BOOST_MOVE_I bool>
|
(std::pair<iterator BOOST_MOVE_I bool>
|
||||||
, typename dtl::enable_if_transparent< key_compare
|
, typename dtl::enable_if_c<
|
||||||
BOOST_MOVE_I K
|
dtl::is_transparent<key_compare>::value && //transparent
|
||||||
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool>
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||||
>::type) //transparent
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||||
|
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool>
|
||||||
|
>::type)
|
||||||
insert_or_assign(BOOST_FWD_REF(K) k, BOOST_FWD_REF(M) obj)
|
insert_or_assign(BOOST_FWD_REF(K) k, BOOST_FWD_REF(M) obj)
|
||||||
{
|
{
|
||||||
return dtl::force_copy< std::pair<iterator, bool> >
|
return dtl::force_copy< std::pair<iterator, bool> >
|
||||||
@@ -1086,6 +1088,61 @@ class flat_map
|
|||||||
<impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
|
<impl_const_iterator>(hint), boost::move(k), boost::forward<Args>(args)...).first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Precondition</b>: This overload is available only if key_compare::is_transparent exists.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||||
|
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||||
|
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||||
|
//! forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Returns</b>: The bool component of the returned pair is true if and only if the
|
||||||
|
//! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Logarithmic search time plus linear insertion time in case the key is not present.
|
||||||
|
template <class K, class... Args>
|
||||||
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
|
(std::pair<iterator BOOST_MOVE_I bool>
|
||||||
|
, typename dtl::enable_if_c<
|
||||||
|
dtl::is_transparent<key_compare>::value && //transparent
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||||
|
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool>
|
||||||
|
>::type)
|
||||||
|
try_emplace(BOOST_FWD_REF(K) k, BOOST_FWD_REF(Args)... args)
|
||||||
|
{
|
||||||
|
return dtl::force_copy< std::pair<iterator, bool> >
|
||||||
|
(m_flat_tree.try_emplace(impl_const_iterator(), boost::forward<K>(k), boost::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! <b>Precondition</b>: This overload is available only if key_compare::is_transparent exists.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||||
|
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||||
|
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||||
|
//! forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
|
||||||
|
//! is inserted right before p. Linear insertion time in case no equivalent key is present.
|
||||||
|
template <class K, class... Args>
|
||||||
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
|
( iterator
|
||||||
|
, typename dtl::enable_if_transparent< key_compare
|
||||||
|
BOOST_MOVE_I K
|
||||||
|
BOOST_MOVE_I iterator
|
||||||
|
>::type) //transparent
|
||||||
|
try_emplace(const_iterator hint, BOOST_FWD_REF(K) k, BOOST_FWD_REF(Args)... args)
|
||||||
|
{
|
||||||
|
return dtl::force_copy<iterator>
|
||||||
|
(m_flat_tree.try_emplace(dtl::force_copy
|
||||||
|
<impl_const_iterator>(hint), boost::forward<K>(k), boost::forward<Args>(args)...).first);
|
||||||
|
}
|
||||||
|
|
||||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
#define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
|
#define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
|
||||||
@@ -1125,6 +1182,31 @@ class flat_map
|
|||||||
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||||
{ return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
|
{ return dtl::force_copy<iterator>(m_flat_tree.try_emplace\
|
||||||
(dtl::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
|
(dtl::force_copy<impl_const_iterator>(hint), boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); }\
|
||||||
|
\
|
||||||
|
template <class K BOOST_MOVE_I##N BOOST_MOVE_CLASS##N> \
|
||||||
|
typename dtl::enable_if_c< \
|
||||||
|
dtl::is_transparent<key_compare>::value && \
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && \
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value \
|
||||||
|
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool> \
|
||||||
|
>::type \
|
||||||
|
try_emplace(BOOST_FWD_REF(K) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
|
||||||
|
{ \
|
||||||
|
return dtl::force_copy< std::pair<iterator BOOST_MOVE_I bool> > \
|
||||||
|
(m_flat_tree.try_emplace(impl_const_iterator() BOOST_MOVE_I boost::forward<K>(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template <class K BOOST_MOVE_I##N BOOST_MOVE_CLASS##N> \
|
||||||
|
typename dtl::enable_if_transparent< key_compare \
|
||||||
|
BOOST_MOVE_I K \
|
||||||
|
BOOST_MOVE_I iterator \
|
||||||
|
>::type \
|
||||||
|
try_emplace(const_iterator hint BOOST_MOVE_I BOOST_FWD_REF(K) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
|
||||||
|
{ \
|
||||||
|
return dtl::force_copy<iterator> \
|
||||||
|
(m_flat_tree.try_emplace(dtl::force_copy \
|
||||||
|
<impl_const_iterator>(hint) BOOST_MOVE_I boost::forward<K>(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first); \
|
||||||
|
}
|
||||||
//
|
//
|
||||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
|
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
|
||||||
#undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
|
#undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
|
||||||
@@ -1363,12 +1445,12 @@ class flat_map
|
|||||||
//! <b>Returns</b>: Returns the number of erased elements.
|
//! <b>Returns</b>: Returns the number of erased elements.
|
||||||
template <class K>
|
template <class K>
|
||||||
inline BOOST_CONTAINER_DOC1ST
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
(size_type
|
(size_type
|
||||||
, typename dtl::enable_if_c<
|
, typename dtl::enable_if_c<
|
||||||
dtl::is_transparent<key_compare>::value && //transparent
|
dtl::is_transparent<key_compare>::value && //transparent
|
||||||
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||||
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||||
BOOST_MOVE_I size_type>::type)
|
BOOST_MOVE_I size_type>::type)
|
||||||
erase(BOOST_FWD_REF(K) x)
|
erase(BOOST_FWD_REF(K) x)
|
||||||
{ return m_flat_tree.erase_unique(x); }
|
{ return m_flat_tree.erase_unique(x); }
|
||||||
|
|
||||||
|
|||||||
@@ -800,42 +800,6 @@ class map
|
|||||||
{ return this->base_t::emplace_hint_unique(p, boost::forward<Pair>(x)); }
|
{ return this->base_t::emplace_hint_unique(p, boost::forward<Pair>(x)); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
|
|
||||||
//! no element in the container with key equivalent to the key of x.
|
|
||||||
//! p is a hint pointing to where the insert should start to search.
|
|
||||||
//!
|
|
||||||
//! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
|
||||||
//! to the key of x.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
|
||||||
//! is inserted right before p.
|
|
||||||
inline iterator insert(const_iterator p, BOOST_RV_REF(nonconst_value_type) x)
|
|
||||||
{ return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructs a new value from x if and only if there is
|
|
||||||
//! no element in the container with key equivalent to the key of x.
|
|
||||||
//! p is a hint pointing to where the insert should start to search.
|
|
||||||
//!
|
|
||||||
//! <b>Returns</b>: An iterator pointing to the element with key equivalent
|
|
||||||
//! to the key of x.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
|
|
||||||
//! is inserted right before p.
|
|
||||||
inline iterator insert(const_iterator p, BOOST_RV_REF(movable_value_type) x)
|
|
||||||
{ return this->try_emplace(p, boost::move(x.first), boost::move(x.second)); }
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Inserts a copy of x in the container.
|
|
||||||
//! p is a hint pointing to where the insert should start to search.
|
|
||||||
//!
|
|
||||||
//! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Logarithmic.
|
|
||||||
inline iterator insert(const_iterator p, const nonconst_value_type& x)
|
|
||||||
{ return this->try_emplace(p, x.first, x.second); }
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
//! <b>Requires</b>: first, last are not iterators into *this.
|
//! <b>Requires</b>: first, last are not iterators into *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: inserts each element from the range [first,last) if and only
|
//! <b>Effects</b>: inserts each element from the range [first,last) if and only
|
||||||
@@ -978,6 +942,54 @@ class map
|
|||||||
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
|
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
|
||||||
{ return this->base_t::try_emplace(hint, boost::move(k), boost::forward<Args>(args)...).first; }
|
{ return this->base_t::try_emplace(hint, boost::move(k), boost::forward<Args>(args)...).first; }
|
||||||
|
|
||||||
|
//! <b>Precondition</b>: This overload is available only if key_compare::is_transparent exists.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||||
|
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||||
|
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||||
|
//! forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Returns</b>: The bool component of the returned pair is true if and only if the
|
||||||
|
//! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Logarithmic search time plus linear insertion time in case the key is not present.
|
||||||
|
template <class K, class... Args>
|
||||||
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
|
(std::pair<iterator BOOST_MOVE_I bool>
|
||||||
|
, typename dtl::enable_if_c<
|
||||||
|
dtl::is_transparent<key_compare>::value && //transparent
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
|
||||||
|
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool>
|
||||||
|
>::type)
|
||||||
|
try_emplace(BOOST_FWD_REF(K) k, BOOST_FWD_REF(Args)... args)
|
||||||
|
{ return this->base_t::try_emplace(const_iterator(), boost::forward<K>(k), boost::forward<Args>(args)...); }
|
||||||
|
|
||||||
|
//! <b>Precondition</b>: This overload is available only if key_compare::is_transparent exists.
|
||||||
|
//!
|
||||||
|
//! <b>Requires</b>: value_type shall be EmplaceConstructible into map from piecewise_construct,
|
||||||
|
//! forward_as_tuple(move(k)), forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: If the map already contains an element whose key is equivalent to k, there is no effect. Otherwise
|
||||||
|
//! inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(move(k)),
|
||||||
|
//! forward_as_tuple(forward<Args>(args)...).
|
||||||
|
//!
|
||||||
|
//! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
|
||||||
|
//! is inserted right before p. Linear insertion time in case no equivalent key is present.
|
||||||
|
template <class K, class... Args>
|
||||||
|
inline BOOST_CONTAINER_DOC1ST
|
||||||
|
( iterator
|
||||||
|
, typename dtl::enable_if_transparent< key_compare
|
||||||
|
BOOST_MOVE_I K
|
||||||
|
BOOST_MOVE_I iterator
|
||||||
|
>::type) //transparent
|
||||||
|
try_emplace(const_iterator hint, BOOST_FWD_REF(K) k, BOOST_FWD_REF(Args)... args)
|
||||||
|
{ return this->base_t::try_emplace(hint, boost::forward<K>(k), boost::forward<Args>(args)...).first; }
|
||||||
|
|
||||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
#define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
|
#define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
|
||||||
@@ -1004,6 +1016,24 @@ class map
|
|||||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||||
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
inline iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||||
{ return this->base_t::try_emplace(hint, boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; }\
|
{ return this->base_t::try_emplace(hint, boost::move(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; }\
|
||||||
|
\
|
||||||
|
template <class K BOOST_MOVE_I##N BOOST_MOVE_CLASS##N> \
|
||||||
|
typename dtl::enable_if_c< \
|
||||||
|
dtl::is_transparent<key_compare>::value && \
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && \
|
||||||
|
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value \
|
||||||
|
BOOST_MOVE_I std::pair<iterator BOOST_MOVE_I bool> \
|
||||||
|
>::type \
|
||||||
|
try_emplace(BOOST_FWD_REF(K) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
|
||||||
|
{ return this->base_t::try_emplace(const_iterator() BOOST_MOVE_I boost::forward<K>(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); } \
|
||||||
|
\
|
||||||
|
template <class K BOOST_MOVE_I##N BOOST_MOVE_CLASS##N> \
|
||||||
|
typename dtl::enable_if_transparent< key_compare \
|
||||||
|
BOOST_MOVE_I K \
|
||||||
|
BOOST_MOVE_I iterator \
|
||||||
|
>::type \
|
||||||
|
try_emplace(const_iterator hint BOOST_MOVE_I BOOST_FWD_REF(K) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
|
||||||
|
{ return this->base_t::try_emplace(hint BOOST_MOVE_I boost::forward<K>(k) BOOST_MOVE_I##N BOOST_MOVE_FWD##N).first; } \
|
||||||
//
|
//
|
||||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
|
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
|
||||||
#undef BOOST_CONTAINER_MAP_EMPLACE_CODE
|
#undef BOOST_CONTAINER_MAP_EMPLACE_CODE
|
||||||
|
|||||||
@@ -274,142 +274,6 @@ struct get_real_stored_allocator<flat_multimap<Key, T, Compare, Allocator> >
|
|||||||
typedef typename flat_multimap<Key, T, Compare, Allocator>::impl_stored_allocator_type type;
|
typedef typename flat_multimap<Key, T, Compare, Allocator>::impl_stored_allocator_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool test_heterogeneous_lookups()
|
|
||||||
{
|
|
||||||
BOOST_CONTAINER_STATIC_ASSERT((dtl::is_transparent<less_transparent>::value));
|
|
||||||
{
|
|
||||||
typedef flat_map<int, char, less_transparent> map_t;
|
|
||||||
typedef flat_multimap<int, char, less_transparent> mmap_t;
|
|
||||||
typedef map_t::value_type value_type;
|
|
||||||
|
|
||||||
map_t map1;
|
|
||||||
mmap_t mmap1;
|
|
||||||
|
|
||||||
const map_t &cmap1 = map1;
|
|
||||||
const mmap_t &cmmap1 = mmap1;
|
|
||||||
|
|
||||||
if(!map1.insert_or_assign(1, 'a').second)
|
|
||||||
return false;
|
|
||||||
if( map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
if(!map1.insert_or_assign(2, 'c').second)
|
|
||||||
return false;
|
|
||||||
if( map1.insert_or_assign(2, 'd').second)
|
|
||||||
return false;
|
|
||||||
if(!map1.insert_or_assign(3, 'e').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(map1.insert_or_assign(1, 'a').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(2, 'c').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(2, 'd').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(3, 'e').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mmap1.insert(value_type(1, 'a'));
|
|
||||||
mmap1.insert(value_type(1, 'b'));
|
|
||||||
mmap1.insert(value_type(2, 'c'));
|
|
||||||
mmap1.insert(value_type(2, 'd'));
|
|
||||||
mmap1.insert(value_type(3, 'e'));
|
|
||||||
|
|
||||||
const test::non_copymovable_int find_me(2);
|
|
||||||
|
|
||||||
//find
|
|
||||||
if(map1.find(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.find(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(mmap1.find(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.find(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//count
|
|
||||||
if(map1.count(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if(cmap1.count(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if(mmap1.count(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
if(cmmap1.count(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//contains
|
|
||||||
if(!map1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!cmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!mmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!cmmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//lower_bound
|
|
||||||
if(map1.lower_bound(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.lower_bound(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(mmap1.lower_bound(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.lower_bound(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//upper_bound
|
|
||||||
if(map1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(cmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(mmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//equal_range
|
|
||||||
if(map1.equal_range(find_me).first->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.equal_range(find_me).second->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(mmap1.equal_range(find_me).first->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.equal_range(find_me).second->second != 'e')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//erase
|
|
||||||
if (map1.erase(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if (map1.erase(find_me) != 0)
|
|
||||||
return false;
|
|
||||||
if (mmap1.erase(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
if (mmap1.erase(find_me) != 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
typedef flat_map<test::movable_int, char, less_transparent> map_t;
|
|
||||||
|
|
||||||
map_t map1;
|
|
||||||
|
|
||||||
//insert_or_assign
|
|
||||||
if(!map1.insert_or_assign(1, 'e').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//insert_or_assign with hint
|
|
||||||
if(map1.find(2) != map1.end())
|
|
||||||
return false;
|
|
||||||
map_t::iterator i = map1.insert_or_assign(map1.begin(), 2, 'e');
|
|
||||||
if(i != map1.insert_or_assign(map1.end(), 2, 'b'))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ordered sequence of std:pair is also ordered by std::pair::first.
|
// An ordered sequence of std:pair is also ordered by std::pair::first.
|
||||||
struct with_lookup_by_first
|
struct with_lookup_by_first
|
||||||
{
|
{
|
||||||
@@ -486,7 +350,15 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_heterogeneous_lookups())
|
if (!test::test_heterogeneous_lookup
|
||||||
|
< flat_map<int, char, less_transparent>
|
||||||
|
, flat_multimap<int, char, less_transparent>
|
||||||
|
>())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!test::test_heterogeneous_insert
|
||||||
|
< flat_map<test::movable_int, char, less_transparent>
|
||||||
|
>())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!test_heterogeneous_lookup_by_partial_key())
|
if (!test_heterogeneous_lookup_by_partial_key())
|
||||||
|
|||||||
@@ -192,6 +192,33 @@ bool node_type_test()
|
|||||||
if(dst.size() != 5)
|
if(dst.size() != 5)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
typedef map<test::movable_int, char, test::less_transparent> map_t;
|
||||||
|
typedef multimap<test::movable_int, char, test::less_transparent> mmap_t;
|
||||||
|
|
||||||
|
map_t map1;
|
||||||
|
mmap_t mmap1;
|
||||||
|
|
||||||
|
//extract
|
||||||
|
map1.clear();
|
||||||
|
map1.try_emplace(1, 'a');
|
||||||
|
mmap1.clear();
|
||||||
|
mmap1.emplace(1, 'a');
|
||||||
|
mmap1.emplace(1, 'b');
|
||||||
|
|
||||||
|
if (!map1.extract(1))
|
||||||
|
return false;
|
||||||
|
if (map1.extract(1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mmap1.extract(1))
|
||||||
|
return false;
|
||||||
|
if (!mmap1.extract(1))
|
||||||
|
return false;
|
||||||
|
if (mmap1.extract(1))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,161 +286,6 @@ void test_merge_from_different_comparison()
|
|||||||
map1.merge(map2);
|
map1.merge(map2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_heterogeneous_lookups()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
typedef map<int, char, less_transparent> map_t;
|
|
||||||
typedef multimap<int, char, less_transparent> mmap_t;
|
|
||||||
typedef map_t::value_type value_type;
|
|
||||||
|
|
||||||
map_t map1;
|
|
||||||
mmap_t mmap1;
|
|
||||||
|
|
||||||
const map_t &cmap1 = map1;
|
|
||||||
const mmap_t &cmmap1 = mmap1;
|
|
||||||
|
|
||||||
if(!map1.insert_or_assign(1, 'a').second)
|
|
||||||
return false;
|
|
||||||
if( map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
if(!map1.insert_or_assign(2, 'c').second)
|
|
||||||
return false;
|
|
||||||
if( map1.insert_or_assign(2, 'd').second)
|
|
||||||
return false;
|
|
||||||
if(!map1.insert_or_assign(3, 'e').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(map1.insert_or_assign(1, 'a').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(2, 'c').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(2, 'd').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(3, 'e').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mmap1.insert(value_type(1, 'a'));
|
|
||||||
mmap1.insert(value_type(1, 'b'));
|
|
||||||
mmap1.insert(value_type(2, 'c'));
|
|
||||||
mmap1.insert(value_type(2, 'd'));
|
|
||||||
mmap1.insert(value_type(3, 'e'));
|
|
||||||
|
|
||||||
const test::non_copymovable_int find_me(2);
|
|
||||||
|
|
||||||
//find
|
|
||||||
if(map1.find(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.find(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(mmap1.find(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.find(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//count
|
|
||||||
if(map1.count(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if(cmap1.count(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if(mmap1.count(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
if(cmmap1.count(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//contains
|
|
||||||
if(!map1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!cmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!mmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
if(!cmmap1.contains(find_me))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//lower_bound
|
|
||||||
if(map1.lower_bound(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.lower_bound(find_me)->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(mmap1.lower_bound(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.lower_bound(find_me)->second != 'c')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//upper_bound
|
|
||||||
if(map1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(cmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(mmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.upper_bound(find_me)->second != 'e')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//equal_range
|
|
||||||
if(map1.equal_range(find_me).first->second != 'd')
|
|
||||||
return false;
|
|
||||||
if(cmap1.equal_range(find_me).second->second != 'e')
|
|
||||||
return false;
|
|
||||||
if(mmap1.equal_range(find_me).first->second != 'c')
|
|
||||||
return false;
|
|
||||||
if(cmmap1.equal_range(find_me).second->second != 'e')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//erase
|
|
||||||
if (map1.erase(find_me) != 1)
|
|
||||||
return false;
|
|
||||||
if (map1.erase(find_me) != 0)
|
|
||||||
return false;
|
|
||||||
if (mmap1.erase(find_me) != 2)
|
|
||||||
return false;
|
|
||||||
if (mmap1.erase(find_me) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//extract
|
|
||||||
map1.clear();
|
|
||||||
map1.insert(value_type(1, 'a'));
|
|
||||||
mmap1.clear();
|
|
||||||
mmap1.insert(value_type(1, 'a'));
|
|
||||||
mmap1.insert(value_type(1, 'b'));
|
|
||||||
|
|
||||||
const test::non_copymovable_int extract_me(1);
|
|
||||||
|
|
||||||
if (!map1.extract(extract_me))
|
|
||||||
return false;
|
|
||||||
if (map1.extract(extract_me))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!mmap1.extract(extract_me))
|
|
||||||
return false;
|
|
||||||
if (!mmap1.extract(extract_me))
|
|
||||||
return false;
|
|
||||||
if (mmap1.extract(extract_me))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
typedef map<test::movable_int, char, less_transparent> map_t;
|
|
||||||
|
|
||||||
map_t map1;
|
|
||||||
|
|
||||||
//insert_or_assign
|
|
||||||
if(!map1.insert_or_assign(1, 'e').second)
|
|
||||||
return false;
|
|
||||||
if(map1.insert_or_assign(1, 'b').second)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//insert_or_assign with hint
|
|
||||||
if(map1.find(2) != map1.end())
|
|
||||||
return false;
|
|
||||||
map_t::iterator i = map1.insert_or_assign(map1.begin(), 2, 'e');
|
|
||||||
if(i != map1.insert_or_assign(map1.end(), 2, 'b'))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool constructor_template_auto_deduction_test()
|
bool constructor_template_auto_deduction_test()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -518,6 +390,7 @@ bool constructor_template_auto_deduction_test()
|
|||||||
|
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
|
using namespace boost::container::test;
|
||||||
//Recursive container instantiation
|
//Recursive container instantiation
|
||||||
{
|
{
|
||||||
map<recursive_map, recursive_map> map_;
|
map<recursive_map, recursive_map> map_;
|
||||||
@@ -678,7 +551,15 @@ int main ()
|
|||||||
|
|
||||||
test::test_merge_from_different_comparison();
|
test::test_merge_from_different_comparison();
|
||||||
|
|
||||||
if(!test::test_heterogeneous_lookups())
|
if (!test::test_heterogeneous_lookup
|
||||||
|
< map<int, char, less_transparent>
|
||||||
|
, multimap<int, char, less_transparent>
|
||||||
|
>())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!test::test_heterogeneous_insert
|
||||||
|
< map<test::movable_int, char, less_transparent>
|
||||||
|
>())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
|||||||
@@ -1542,6 +1542,165 @@ bool instantiate_constructors()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename IntMapType, typename IntMultimapType>
|
||||||
|
bool test_heterogeneous_lookup()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef IntMapType map_t;
|
||||||
|
typedef IntMultimapType mmap_t;
|
||||||
|
typedef typename map_t::value_type value_type;
|
||||||
|
|
||||||
|
map_t map1;
|
||||||
|
const map_t &cmap1 = map1;
|
||||||
|
|
||||||
|
if(!map1.insert_or_assign(1, 'a').second)
|
||||||
|
return false;
|
||||||
|
if( map1.insert_or_assign(1, 'b').second)
|
||||||
|
return false;
|
||||||
|
if(!map1.insert_or_assign(2, 'c').second)
|
||||||
|
return false;
|
||||||
|
if( map1.insert_or_assign(2, 'd').second)
|
||||||
|
return false;
|
||||||
|
if(!map1.insert_or_assign(3, 'e').second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mmap_t mmap1;
|
||||||
|
const mmap_t &cmmap1 = mmap1;
|
||||||
|
|
||||||
|
mmap1.insert(value_type(1, 'a'));
|
||||||
|
mmap1.insert(value_type(1, 'b'));
|
||||||
|
mmap1.insert(value_type(2, 'c'));
|
||||||
|
mmap1.insert(value_type(2, 'd'));
|
||||||
|
mmap1.insert(value_type(3, 'e'));
|
||||||
|
|
||||||
|
const test::non_copymovable_int find_me(2);
|
||||||
|
|
||||||
|
//find
|
||||||
|
if(map1.find(find_me)->second != 'd')
|
||||||
|
return false;
|
||||||
|
if(cmap1.find(find_me)->second != 'd')
|
||||||
|
return false;
|
||||||
|
if(mmap1.find(find_me)->second != 'c')
|
||||||
|
return false;
|
||||||
|
if(cmmap1.find(find_me)->second != 'c')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//count
|
||||||
|
if(map1.count(find_me) != 1)
|
||||||
|
return false;
|
||||||
|
if(cmap1.count(find_me) != 1)
|
||||||
|
return false;
|
||||||
|
if(mmap1.count(find_me) != 2)
|
||||||
|
return false;
|
||||||
|
if(cmmap1.count(find_me) != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//contains
|
||||||
|
if(!map1.contains(find_me))
|
||||||
|
return false;
|
||||||
|
if(!cmap1.contains(find_me))
|
||||||
|
return false;
|
||||||
|
if(!mmap1.contains(find_me))
|
||||||
|
return false;
|
||||||
|
if(!cmmap1.contains(find_me))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//lower_bound
|
||||||
|
if(map1.lower_bound(find_me)->second != 'd')
|
||||||
|
return false;
|
||||||
|
if(cmap1.lower_bound(find_me)->second != 'd')
|
||||||
|
return false;
|
||||||
|
if(mmap1.lower_bound(find_me)->second != 'c')
|
||||||
|
return false;
|
||||||
|
if(cmmap1.lower_bound(find_me)->second != 'c')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//upper_bound
|
||||||
|
if(map1.upper_bound(find_me)->second != 'e')
|
||||||
|
return false;
|
||||||
|
if(cmap1.upper_bound(find_me)->second != 'e')
|
||||||
|
return false;
|
||||||
|
if(mmap1.upper_bound(find_me)->second != 'e')
|
||||||
|
return false;
|
||||||
|
if(cmmap1.upper_bound(find_me)->second != 'e')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//equal_range
|
||||||
|
if(map1.equal_range(find_me).first->second != 'd')
|
||||||
|
return false;
|
||||||
|
if(cmap1.equal_range(find_me).second->second != 'e')
|
||||||
|
return false;
|
||||||
|
if(mmap1.equal_range(find_me).first->second != 'c')
|
||||||
|
return false;
|
||||||
|
if(cmmap1.equal_range(find_me).second->second != 'e')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//erase
|
||||||
|
if (map1.erase(find_me) != 1)
|
||||||
|
return false;
|
||||||
|
if (map1.erase(find_me) != 0)
|
||||||
|
return false;
|
||||||
|
if (mmap1.erase(find_me) != 2)
|
||||||
|
return false;
|
||||||
|
if (mmap1.erase(find_me) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MovableIntMapType>
|
||||||
|
bool test_heterogeneous_insert()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef MovableIntMapType map_t;
|
||||||
|
|
||||||
|
map_t map1;
|
||||||
|
const map_t &cmap1 = map1;
|
||||||
|
|
||||||
|
//insert_or_assign
|
||||||
|
if(!map1.insert_or_assign(1, 'e').second)
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(1)->second != 'e')
|
||||||
|
return false;
|
||||||
|
if(map1.insert_or_assign(1, 'b').second)
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(1)->second != 'b')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//insert_or_assign with hint
|
||||||
|
if(map1.find(2) != map1.end())
|
||||||
|
return false;
|
||||||
|
typename map_t::iterator i = map1.insert_or_assign(map1.begin(), 2, 'f');
|
||||||
|
if(i != map1.insert_or_assign(map1.end(), 2, 'g'))
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(2)->second != 'g')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//try_emplace
|
||||||
|
map1.clear();
|
||||||
|
if(!map1.try_emplace(1, 'a').second)
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(1)->second != 'a')
|
||||||
|
return false;
|
||||||
|
if( map1.try_emplace(1, 'b').second)
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(1)->second != 'a')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//try_emplace with hint
|
||||||
|
i = map1.try_emplace(map1.end(), 2, 'c');
|
||||||
|
if (cmap1.find(2)->second != 'c')
|
||||||
|
return false;
|
||||||
|
if (i != map1.try_emplace(map1.begin(), 2, 'd'))
|
||||||
|
return false;
|
||||||
|
if (cmap1.find(2)->second != 'c')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace test{
|
} //namespace test{
|
||||||
} //namespace container {
|
} //namespace container {
|
||||||
} //namespace boost{
|
} //namespace boost{
|
||||||
|
|||||||
Reference in New Issue
Block a user