aboutsummaryrefslogtreecommitdiff
path: root/include/map
diff options
context:
space:
mode:
authorDavid Chisnall <theraven@FreeBSD.org>2013-07-10 10:49:31 +0000
committerDavid Chisnall <theraven@FreeBSD.org>2013-07-10 10:49:31 +0000
commit1c9014238e909c768bf84564733b5441d5c9ea2b (patch)
treeee42ff7378fd2433cb88e1cfa25b2a65035b0c43 /include/map
parent527d9fcb66574fdd657c3235c0d7cba7c5439d5c (diff)
downloadsrc-1c9014238e909c768bf84564733b5441d5c9ea2b.tar.gz
src-1c9014238e909c768bf84564733b5441d5c9ea2b.zip
Pull new libc++ into vendor branch.vendor/libc++/r185801
Notes
Notes: svn path=/vendor/libc++/dist/; revision=253146 svn path=/vendor/libc++/r185801/; revision=253147; tag=vendor/libc++/r185801
Diffstat (limited to 'include/map')
-rw-r--r--include/map389
1 files changed, 165 insertions, 224 deletions
diff --git a/include/map b/include/map
index abc07a35d0ea..953743a6c740 100644
--- a/include/map
+++ b/include/map
@@ -381,7 +381,7 @@ swap(multimap<Key, T, Compare, Allocator>& x,
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Key, class _Tp, class _Compare, bool = is_empty<_Compare>::value
+template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
#if __has_feature(is_final)
&& !__is_final(_Compare)
#endif
@@ -389,8 +389,6 @@ template <class _Key, class _Tp, class _Compare, bool = is_empty<_Compare>::valu
class __map_value_compare
: private _Compare
{
- typedef pair<typename std::remove_const<_Key>::type, _Tp> _Pp;
- typedef pair<const _Key, _Tp> _CP;
public:
_LIBCPP_INLINE_VISIBILITY
__map_value_compare()
@@ -404,41 +402,20 @@ public:
const _Compare& key_comp() const _NOEXCEPT {return *this;}
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _CP& __x, const _CP& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _CP& __x, const _Pp& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
+ {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _CP& __x, const _Key& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _CP& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _Pp& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _Key& __y) const
- {return static_cast<const _Compare&>(*this)(__x.first, __y);}
+ {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
- {return static_cast<const _Compare&>(*this)(__x, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Key& __x, const _Pp& __y) const
- {return static_cast<const _Compare&>(*this)(__x, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Key& __x, const _Key& __y) const
- {return static_cast<const _Compare&>(*this)(__x, __y);}
+ {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
};
-template <class _Key, class _Tp, class _Compare>
-class __map_value_compare<_Key, _Tp, _Compare, false>
+template <class _Key, class _CP, class _Compare>
+class __map_value_compare<_Key, _CP, _Compare, false>
{
_Compare comp;
- typedef pair<typename std::remove_const<_Key>::type, _Tp> _Pp;
- typedef pair<const _Key, _Tp> _CP;
-
public:
_LIBCPP_INLINE_VISIBILITY
__map_value_compare()
@@ -453,31 +430,13 @@ public:
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _CP& __x, const _CP& __y) const
- {return comp(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _CP& __x, const _Pp& __y) const
- {return comp(__x.first, __y.first);}
+ {return comp(__x.__cc.first, __y.__cc.first);}
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _CP& __x, const _Key& __y) const
- {return comp(__x.first, __y);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _CP& __y) const
- {return comp(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _Pp& __y) const
- {return comp(__x.first, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Pp& __x, const _Key& __y) const
- {return comp(__x.first, __y);}
+ {return comp(__x.__cc.first, __y);}
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
- {return comp(__x, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Key& __x, const _Pp& __y) const
- {return comp(__x, __y.first);}
- _LIBCPP_INLINE_VISIBILITY
- bool operator()(const _Key& __x, const _Key& __y) const
- {return comp(__x, __y);}
+ {return comp(__x, __y.__cc.first);}
};
template <class _Allocator>
@@ -489,8 +448,8 @@ class __map_node_destructor
public:
typedef typename __alloc_traits::pointer pointer;
private:
- typedef typename value_type::first_type first_type;
- typedef typename value_type::second_type second_type;
+ typedef typename value_type::value_type::first_type first_type;
+ typedef typename value_type::value_type::second_type second_type;
allocator_type& __na_;
@@ -522,9 +481,9 @@ public:
void operator()(pointer __p) _NOEXCEPT
{
if (__second_constructed)
- __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
+ __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
if (__first_constructed)
- __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
+ __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
if (__p)
__alloc_traits::deallocate(__na_, __p, 1);
}
@@ -542,8 +501,8 @@ class _LIBCPP_TYPE_VIS __map_iterator
_TreeIterator __i_;
typedef typename _TreeIterator::__pointer_traits __pointer_traits;
- typedef const typename _TreeIterator::value_type::first_type __key_type;
- typedef typename _TreeIterator::value_type::second_type __mapped_type;
+ typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+ typedef typename _TreeIterator::value_type::value_type::second_type __mapped_type;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef pair<__key_type, __mapped_type> value_type;
@@ -564,9 +523,9 @@ public:
__map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
_LIBCPP_INLINE_VISIBILITY
- reference operator*() const {return *operator->();}
+ reference operator*() const {return __i_->__cc;}
_LIBCPP_INLINE_VISIBILITY
- pointer operator->() const {return (pointer)__i_.operator->();}
+ pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
_LIBCPP_INLINE_VISIBILITY
__map_iterator& operator++() {++__i_; return *this;}
@@ -607,8 +566,8 @@ class _LIBCPP_TYPE_VIS __map_const_iterator
_TreeIterator __i_;
typedef typename _TreeIterator::__pointer_traits __pointer_traits;
- typedef const typename _TreeIterator::value_type::first_type __key_type;
- typedef typename _TreeIterator::value_type::second_type __mapped_type;
+ typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+ typedef typename _TreeIterator::value_type::value_type::second_type __mapped_type;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef pair<__key_type, __mapped_type> value_type;
@@ -634,9 +593,9 @@ public:
: __i_(__i.__i_) {}
_LIBCPP_INLINE_VISIBILITY
- reference operator*() const {return *operator->();}
+ reference operator*() const {return __i_->__cc;}
_LIBCPP_INLINE_VISIBILITY
- pointer operator->() const {return (pointer)__i_.operator->();}
+ pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
_LIBCPP_INLINE_VISIBILITY
__map_const_iterator& operator++() {++__i_; return *this;}
@@ -679,6 +638,7 @@ public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const key_type, mapped_type> value_type;
+ typedef pair<key_type, mapped_type> __nc_value_type;
typedef _Compare key_compare;
typedef _Allocator allocator_type;
typedef value_type& reference;
@@ -699,8 +659,51 @@ public:
};
private:
- typedef pair<key_type, mapped_type> __value_type;
- typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
+
+#if __cplusplus >= 201103L
+ union __value_type
+ {
+ typedef typename map::value_type value_type;
+ typedef typename map::__nc_value_type __nc_value_type;
+ value_type __cc;
+ __nc_value_type __nc;
+
+ template <class ..._Args>
+ __value_type(_Args&& ...__args)
+ : __cc(std::forward<_Args>(__args)...) {}
+
+ __value_type(const __value_type& __v)
+ : __cc(std::move(__v.__cc)) {}
+
+ __value_type(__value_type&& __v)
+ : __nc(std::move(__v.__nc)) {}
+
+ __value_type& operator=(const __value_type& __v)
+ {__nc = __v.__cc; return *this;}
+
+ __value_type& operator=(__value_type&& __v)
+ {__nc = std::move(__v.__nc); return *this;}
+
+ ~__value_type() {__cc.~value_type();}
+ };
+#else
+ struct __value_type
+ {
+ typedef typename map::value_type value_type;
+ value_type __cc;
+
+ __value_type() {}
+
+ template <class _A0>
+ __value_type(const _A0& __a0)
+ : __cc(__a0) {}
+
+ template <class _A0, class _A1>
+ __value_type(const _A0& __a0, const _A1& __a1)
+ : __cc(__a0, __a1) {}
+ };
+#endif
+ typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
typedef typename allocator_traits<allocator_type>::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind_alloc<__value_type>
@@ -764,7 +767,14 @@ public:
_LIBCPP_INLINE_VISIBILITY
map& operator=(const map& __m)
{
+#if __cplusplus >= 201103L
__tree_ = __m.__tree_;
+#else
+ __tree_.clear();
+ __tree_.value_comp() = __m.__tree_.value_comp();
+ __tree_.__copy_assign_alloc(__m.__tree_);
+ insert(__m.begin(), __m.end());
+#endif
return *this;
}
@@ -986,32 +996,17 @@ private:
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
__node_holder __construct_node();
template <class _A0>
- typename enable_if
- <
- is_constructible<value_type, _A0>::value,
- __node_holder
- >::type
- __construct_node(_A0&& __a0);
- template <class _A0>
- typename enable_if
- <
- is_constructible<key_type, _A0>::value,
- __node_holder
- >::type
- __construct_node(_A0&& __a0);
+ __node_holder __construct_node(_A0&& __a0);
+ __node_holder __construct_node_with_key(key_type&& __k);
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class _A1, class ..._Args>
__node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
#endif // _LIBCPP_HAS_NO_VARIADICS
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- __node_holder __construct_node(const key_type& __k);
#endif
+ __node_holder __construct_node_with_key(const key_type& __k);
__node_base_pointer&
__find_equal_key(__node_base_pointer& __parent, const key_type& __k);
- __node_base_pointer&
- __find_equal_key(const_iterator __hint,
- __node_base_pointer& __parent, const key_type& __k);
__node_base_const_pointer
__find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;
};
@@ -1030,97 +1025,37 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __pa
{
while (true)
{
- if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
+ if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
{
if (__nd->__left_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__left_);
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return __parent->__left_;
}
}
- else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
+ else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
{
if (__nd->__right_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__right_);
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return __parent->__right_;
}
}
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return __parent;
}
}
}
- __parent = __tree_.__end_node();
+ __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
return __parent->__left_;
}
-// Find place to insert if __k doesn't exist
-// First check prior to __hint.
-// Next check after __hint.
-// Next do O(log N) search.
-// Set __parent to parent of null leaf
-// Return reference to null leaf
-// If __k exists, set parent to node of __k and return reference to node of __k
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
-map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(const_iterator __hint,
- __node_base_pointer& __parent,
- const key_type& __k)
-{
- if (__hint == end() || __tree_.value_comp().key_comp()(__k, __hint->first)) // check before
- {
- // __k < *__hint
- const_iterator __prior = __hint;
- if (__prior == begin() || __tree_.value_comp().key_comp()((--__prior)->first, __k))
- {
- // *prev(__hint) < __k < *__hint
- if (__hint.__ptr_->__left_ == nullptr)
- {
- __parent = const_cast<__node_pointer&>(__hint.__ptr_);
- return __parent->__left_;
- }
- else
- {
- __parent = const_cast<__node_pointer&>(__prior.__ptr_);
- return __parent->__right_;
- }
- }
- // __k <= *prev(__hint)
- return __find_equal_key(__parent, __k);
- }
- else if (__tree_.value_comp().key_comp()(__hint->first, __k)) // check after
- {
- // *__hint < __k
- const_iterator __next = _VSTD::next(__hint);
- if (__next == end() || __tree_.value_comp().key_comp()(__k, __next->first))
- {
- // *__hint < __k < *next(__hint)
- if (__hint.__ptr_->__right_ == nullptr)
- {
- __parent = const_cast<__node_pointer&>(__hint.__ptr_);
- return __parent->__right_;
- }
- else
- {
- __parent = const_cast<__node_pointer&>(__next.__ptr_);
- return __parent->__left_;
- }
- }
- // *next(__hint) <= __k
- return __find_equal_key(__parent, __k);
- }
- // else __k == *__hint
- __parent = const_cast<__node_pointer&>(__hint.__ptr_);
- return __parent;
-}
-
// Find __k
// Set __parent to parent of null leaf and
// return reference to null leaf iv __k does not exist.
@@ -1135,34 +1070,34 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer
{
while (true)
{
- if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
+ if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
{
if (__nd->__left_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__left_);
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return const_cast<const __node_base_const_pointer&>(__parent->__left_);
}
}
- else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
+ else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
{
if (__nd->__right_ != nullptr)
__nd = static_cast<__node_pointer>(__nd->__right_);
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return const_cast<const __node_base_const_pointer&>(__parent->__right_);
}
}
else
{
- __parent = __nd;
+ __parent = static_cast<__node_base_pointer>(__nd);
return __parent;
}
}
}
- __parent = __tree_.__end_node();
+ __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
return const_cast<const __node_base_const_pointer&>(__parent->__left_);
}
@@ -1187,20 +1122,16 @@ map<_Key, _Tp, _Compare, _Allocator>::__construct_node()
{
__node_allocator& __na = __tree_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
__h.get_deleter().__first_constructed = true;
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
__h.get_deleter().__second_constructed = true;
return __h;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
template <class _A0>
-typename enable_if
-<
- is_constructible<pair<const _Key, _Tp>, _A0>::value,
- typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __tree_.__node_alloc();
@@ -1212,21 +1143,16 @@ map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-template <class _A0>
-typename enable_if
-<
- is_constructible<_Key, _A0>::value,
- typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
-map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k)
{
__node_allocator& __na = __tree_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), _VSTD::forward<_A0>(__a0));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
__h.get_deleter().__first_constructed = true;
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
__h.get_deleter().__second_constructed = true;
- return __h;
+ return _VSTD::move(__h);
}
#ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1248,23 +1174,21 @@ map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _
#endif // _LIBCPP_HAS_NO_VARIADICS
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Key, class _Tp, class _Compare, class _Allocator>
typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
-map<_Key, _Tp, _Compare, _Allocator>::__construct_node(const key_type& __k)
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
{
__node_allocator& __na = __tree_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
__h.get_deleter().__first_constructed = true;
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
__h.get_deleter().__second_constructed = true;
return _VSTD::move(__h);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp&
map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
@@ -1274,11 +1198,11 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
__node_pointer __r = static_cast<__node_pointer>(__child);
if (__child == nullptr)
{
- __node_holder __h = __construct_node(__k);
- __tree_.__insert_node_at(__parent, __child, __h.get());
+ __node_holder __h = __construct_node_with_key(__k);
+ __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
__r = __h.release();
}
- return __r->__value_.second;
+ return __r->__value_.__cc.second;
}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1292,11 +1216,11 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
__node_pointer __r = static_cast<__node_pointer>(__child);
if (__child == nullptr)
{
- __node_holder __h = __construct_node(_VSTD::move(__k));
- __tree_.__insert_node_at(__parent, __child, __h.get());
+ __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
+ __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
__r = __h.release();
}
- return __r->__value_.second;
+ return __r->__value_.__cc.second;
}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1311,7 +1235,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
if (__child == nullptr)
throw out_of_range("map::at: key not found");
#endif // _LIBCPP_NO_EXCEPTIONS
- return static_cast<__node_pointer>(__child)->__value_.second;
+ return static_cast<__node_pointer>(__child)->__value_.__cc.second;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
@@ -1324,7 +1248,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
if (__child == nullptr)
throw out_of_range("map::at: key not found");
#endif // _LIBCPP_NO_EXCEPTIONS
- return static_cast<__node_const_pointer>(__child)->__value_.second;
+ return static_cast<__node_const_pointer>(__child)->__value_.__cc.second;
}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1429,6 +1353,7 @@ public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const key_type, mapped_type> value_type;
+ typedef pair<key_type, mapped_type> __nc_value_type;
typedef _Compare key_compare;
typedef _Allocator allocator_type;
typedef value_type& reference;
@@ -1450,8 +1375,50 @@ public:
};
private:
- typedef pair<key_type, mapped_type> __value_type;
- typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
+#if __cplusplus >= 201103L
+ union __value_type
+ {
+ typedef typename multimap::value_type value_type;
+ typedef typename multimap::__nc_value_type __nc_value_type;
+ value_type __cc;
+ __nc_value_type __nc;
+
+ template <class ..._Args>
+ __value_type(_Args&& ...__args)
+ : __cc(std::forward<_Args>(__args)...) {}
+
+ __value_type(const __value_type& __v)
+ : __cc(std::move(__v.__cc)) {}
+
+ __value_type(__value_type&& __v)
+ : __nc(std::move(__v.__nc)) {}
+
+ __value_type& operator=(const __value_type& __v)
+ {__nc = __v.__cc; return *this;}
+
+ __value_type& operator=(__value_type&& __v)
+ {__nc = std::move(__v.__nc); return *this;}
+
+ ~__value_type() {__cc.~value_type();}
+ };
+#else
+ struct __value_type
+ {
+ typedef typename multimap::value_type value_type;
+ value_type __cc;
+
+ __value_type() {}
+
+ template <class _A0>
+ __value_type(const _A0& __a0)
+ : __cc(__a0) {}
+
+ template <class _A0, class _A1>
+ __value_type(const _A0& __a0, const _A1& __a1)
+ : __cc(__a0, __a1) {}
+ };
+#endif
+ typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
typedef typename allocator_traits<allocator_type>::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind_alloc<__value_type>
@@ -1516,7 +1483,14 @@ public:
_LIBCPP_INLINE_VISIBILITY
multimap& operator=(const multimap& __m)
{
+#if __cplusplus >= 201103L
__tree_ = __m.__tree_;
+#else
+ __tree_.clear();
+ __tree_.value_comp() = __m.__tree_.value_comp();
+ __tree_.__copy_assign_alloc(__m.__tree_);
+ insert(__m.begin(), __m.end());
+#endif
return *this;
}
@@ -1725,18 +1699,7 @@ private:
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
__node_holder __construct_node();
template <class _A0>
- typename enable_if
- <
- is_constructible<value_type, _A0>::value,
- __node_holder
- >::type
- __construct_node(_A0&& __a0);
- template <class _A0>
- typename enable_if
- <
- is_constructible<key_type, _A0>::value,
- __node_holder
- >::type
+ __node_holder
__construct_node(_A0&& __a0);
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class _A1, class ..._Args>
@@ -1766,20 +1729,16 @@ multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node()
{
__node_allocator& __na = __tree_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
__h.get_deleter().__first_constructed = true;
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+ __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
__h.get_deleter().__second_constructed = true;
return __h;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
template <class _A0>
-typename enable_if
-<
- is_constructible<pair<const _Key, _Tp>, _A0>::value,
- typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
+typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __tree_.__node_alloc();
@@ -1790,24 +1749,6 @@ multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
return __h;
}
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-template <class _A0>
-typename enable_if
-<
- is_constructible<_Key, _A0>::value,
- typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
-multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
-{
- __node_allocator& __na = __tree_.__node_alloc();
- __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), _VSTD::forward<_A0>(__a0));
- __h.get_deleter().__first_constructed = true;
- __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
- __h.get_deleter().__second_constructed = true;
- return __h;
-}
-
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Compare, class _Allocator>