File Index Symbol Index

// map standard header
#pragma once
#ifndef _MAP_
#define _MAP_
#ifndef RC_INVOKED
#include <tuple>
#include <xtree>
#if _HAS_CXX17
#include <xpolymorphic_allocator.h> #endif /* _HAS_CXX17 */
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
// CLASS TEMPLATE _Tmap_traits
template
<
class
_Kty
,
// key type
class
_Ty
,
// mapped type
class
_Pr
,
// comparator predicate type
class
_Alloc
,
// actual allocator type (should be value allocator)
bool
_Mfl
>
// true if multiple equivalent keys are permitted
class
_Tmap_traits
{
// traits required to make _Tree behave like a map
public
:
using
key_type
=
_Kty
;
using
value_type
=
pair
<
const
_Kty
,
_Ty
>;
using
key_compare
=
_Pr
;
using
allocator_type
=
_Alloc
;
#if _HAS_CXX17
using node_type = _Node_handle<
_Tree_node<value_type, typename allocator_traits<_Alloc>::void_pointer>,
_Alloc, _Node_handle_map_base, _Kty, _Ty>; #endif /* _HAS_CXX17 */
enum
{
// make multi parameter visible as an enum constant
_Multi
=
_Mfl
};
class
value_compare
{
// functor for comparing two element values
public
:
bool
operator
(
)
(
const
value_type
&
_Left
,
const
value_type
&
_Right
)
const
{
// test if _Left precedes _Right by comparing just keys
return
(
comp
(
_Left
.
first
,
_Right
.
first
)); }
protected
:
friend
_Tree
<
_Tmap_traits
>;
value_compare
(
key_compare
_Pred
) : comp(
_Pred
) {
// construct with specified predicate
}
key_compare
comp
;
// the comparator predicate for keys
};
template
<
class
_Ty1
,
class
_Ty2
>
static
const
_Kty
&
_Kfn
(
const
pair
<
_Ty1
,
_Ty2
>&
_Val
) {
// extract key from element value
return
(
_Val
.
first
); } };
// CLASS TEMPLATE map
template
<
class
_Kty
,
class
_Ty
,
class
_Pr
=
less
<
_Kty
>,
class
_Alloc
=
allocator
<
pair
<
const
_Kty
,
_Ty
>>>
class
map
:
public
_Tree
<
_Tmap_traits
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
,
false
>> {
// ordered red-black tree of {key, mapped} values, unique keys
public
:
using
_Mybase
=
_Tree
<
_Tmap_traits
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
,
false
>>;
using
key_type
=
_Kty
;
using
mapped_type
=
_Ty
;
using
key_compare
=
_Pr
;
using
value_compare
=
typename
_Mybase
::
value_compare
;
using
value_type
=
typename
_Mybase
::
value_type
;
using
allocator_type
=
typename
_Mybase
::
allocator_type
;
using
size_type
=
typename
_Mybase
::
size_type
;
using
difference_type
=
typename
_Mybase
::
difference_type
;
using
pointer
=
typename
_Mybase
::
pointer
;
using
const_pointer
=
typename
_Mybase
::
const_pointer
;
using
reference
=
value_type
&;
using
const_reference
=
const
value_type
&;
using
iterator
=
typename
_Mybase
::
iterator
;
using
const_iterator
=
typename
_Mybase
::
const_iterator
;
using
reverse_iterator
=
typename
_Mybase
::
reverse_iterator
;
using
const_reverse_iterator
=
typename
_Mybase
::
const_reverse_iterator
;
using
_Alnode
=
typename
_Mybase
::
_Alnode
;
using
_Alnode_traits
=
typename
_Mybase
::
_Alnode_traits
;
using
_Pairib
=
typename
_Mybase
::
_Pairib
;
#if _HAS_CXX17
using insert_return_type = _Insert_return_type<iterator, typename _Mybase::node_type>; #endif /* _HAS_CXX17 */
map
() :
_Mybase
(
key_compare
()) {
// construct empty map from defaults
}
explicit
map
(
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct empty map from defaults, allocator
}
map
(
const
map
&
_Right
) :
_Mybase
(
_Right
,
_Alnode_traits
::
select_on_container_copy_construction
(
_Right
.
_Getal
())) {
// construct map by copying _Right
}
map
(
const
map
&
_Right
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Right
,
_Al
) {
// construct map by copying _Right, allocator
}
explicit
map
(
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct empty map from comparator
}
map
(
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct empty map from comparator and allocator
}
template
<
class
_Iter
>
map
(
_Iter
_First
,
_Iter
_Last
) :
_Mybase
(
key_compare
()) {
// construct map from [_First, _Last), defaults
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
map
(
_Iter
_First
,
_Iter
_Last
,
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct map from [_First, _Last), comparator
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
map
(
_Iter
_First
,
_Iter
_Last
,
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct map from [_First, _Last), allocator
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
map
(
_Iter
_First
,
_Iter
_Last
,
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct map from [_First, _Last), comparator, and allocator
insert
(
_First
,
_Last
); }
map
&
operator
=
(
const
map
&
_Right
) {
// assign by copying _Right
_Mybase
::
operator
=
(
_Right
);
return
(*
this
); }
map
(
map
&&
_Right
) {
// construct map by moving _Right
}
map
(
map
&&
_Right
,
const
allocator_type
&
_Al
) {
// construct map by moving _Right, allocator
}
map
&
operator
=
(
map
&&
_Right
) {
// assign by moving _Right
return
(*
this
); }
mapped_type
&
operator
[
]
(
key_type
&&
_Keyval
) {
// find element matching _Keyval or insert with default mapped
} {
// exchange contents with non-movable _Right
_Mybase
::
swap
(
_Right
); }
using
_Mybase
::
insert
;
template
<
class
_Valty
,
class
=
enable_if_t
<
is_constructible_v
<
value_type
,
_Valty
>>>
_Pairib
insert
(
_Valty
&&
_Val
) {
// insert _Val
}
template
<
class
_Valty
,
class
=
enable_if_t
<
is_constructible_v
<
value_type
,
_Valty
>>>
iterator
insert
(
const_iterator
_Where
,
_Valty
&&
_Val
) {
// insert _Val with hint
}
template
<
class
_Keyty
,
class
...
_Mappedty
>
_Pairib
_Try_emplace
(
_Keyty
&&
_Keyval
,
_Mappedty
&&...
_Mapval
) {
// fail if _Keyval present, else emplace
iterator
_Where
=
_Mybase
::
lower_bound
(
_Keyval
);
if
(
_Where
=
=
_Mybase
::
end
()
return
(
_Pairib
(
_Mybase
::
emplace_hint
(
_Where
,
piecewise_construct
,
true
));
else
return
(
_Pairib
(
_Where
,
false
)); }
template
<
class
...
_Mappedty
>
_Pairib
try_emplace
(
const
key_type
&
_Keyval
,
_Mappedty
&&...
_Mapval
) {
// fail if _Keyval present, else emplace
}
template
<
class
...
_Mappedty
>
iterator
try_emplace
(
const_iterator
,
const
key_type
&
_Keyval
,
_Mappedty
&&...
_Mapval
) {
// fail if _Keyval present, else emplace, ignore hint
return
(
_Try_emplace
(
_Keyval
, }
template
<
class
...
_Mappedty
>
_Pairib
try_emplace
(
key_type
&&
_Keyval
,
_Mappedty
&&...
_Mapval
) {
// fail if _Keyval present, else emplace
}
template
<
class
...
_Mappedty
>
iterator
try_emplace
(
const_iterator
,
key_type
&&
_Keyval
,
_Mappedty
&&...
_Mapval
) {
// fail if _Keyval present, else emplace, ignore hint
}
template
<
class
_Keyty
,
class
_Mappedty
>
_Pairib
_Insert_or_assign
(
_Keyty
&&
_Keyval
,
_Mappedty
&&
_Mapval
) {
// assign if _Keyval present, else insert
iterator
_Where
=
_Mybase
::
lower_bound
(
_Keyval
);
if
(
_Where
=
=
_Mybase
::
end
()
return
(
_Pairib
(
_Mybase
::
emplace_hint
(
_Where
,
true
));
else
{
// _Keyval present, assign new value
return
(
_Pairib
(
_Where
,
false
)); } }
template
<
class
_Mappedty
>
_Pairib
insert_or_assign
(
const
key_type
&
_Keyval
,
_Mappedty
&&
_Mapval
) {
// assign if _Keyval present, else insert
return
(
_Insert_or_assign
(
_Keyval
, }
template
<
class
_Mappedty
>
iterator
insert_or_assign
(
const_iterator
,
const
key_type
&
_Keyval
,
_Mappedty
&&
_Mapval
) {
// assign if _Keyval present, else insert, ignore hint
return
(
_Insert_or_assign
(
_Keyval
, }
template
<
class
_Mappedty
>
_Pairib
insert_or_assign
(
key_type
&&
_Keyval
,
_Mappedty
&&
_Mapval
) {
// assign if _Keyval present, else insert
}
template
<
class
_Mappedty
>
iterator
insert_or_assign
(
const_iterator
,
key_type
&&
_Keyval
,
_Mappedty
&&
_Mapval
) {
// assign if _Keyval present, else insert, ignore hint
}
map
(
initializer_list
<
value_type
>
_Ilist
) :
_Mybase
(
key_compare
()) {
// construct from initializer_list, defaults
insert
(
_Ilist
); }
map
(
initializer_list
<
value_type
>
_Ilist
,
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct from initializer_list, comparator
insert
(
_Ilist
); }
map
(
initializer_list
<
value_type
>
_Ilist
,
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct from initializer_list, allocator
insert
(
_Ilist
); }
map
(
initializer_list
<
value_type
>
_Ilist
,
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct from initializer_list, comparator, and allocator
insert
(
_Ilist
); }
map
&
operator
=
(
initializer_list
<
value_type
>
_Ilist
) {
// assign initializer_list
_Mybase
::
clear
();
insert
(
_Ilist
);
return
(*
this
); }
mapped_type
&
operator
[
]
(
const
key_type
&
_Keyval
) {
// find element matching _Keyval or insert with default mapped
return
(
try_emplace
(
_Keyval
).
first
-
>
second
); } {
// find element matching _Keyval
iterator
_Where
=
_Mybase
::
lower_bound
(
_Keyval
);
if
(
_Where
=
=
_Mybase
::
end
() ||
_Mybase
::
_Getcomp
()(
_Keyval
,
_Mybase
::
_Key
(
_Where
.
_Ptr
)))
_Xout_of_range
(
"invalid map<K, T> key"
);
return
(
_Where
-
>
second
); } {
// find element matching _Keyval
const_iterator
_Where
=
_Mybase
::
lower_bound
(
_Keyval
);
if
(
_Where
=
=
_Mybase
::
end
() ||
_Mybase
::
_Getcomp
()(
_Keyval
,
_Mybase
::
_Key
(
_Where
.
_Ptr
)))
_Xout_of_range
(
"invalid map<K, T> key"
);
return
(
_Where
-
>
second
); }
using
_Mybase
::
_Unchecked_begin
;
using
_Mybase
::
_Unchecked_end
; };
#if _HAS_CXX17
template<class _Iter,
class _Pr = less<_Guide_key_t<_Iter>>,
class _Alloc = allocator<_Guide_pair_t<_Iter>>,
enable_if_t<conjunction_v<
_Is_iterator<_Iter>,
negation<_Is_allocator<_Pr>>,
_Is_allocator<_Alloc>
>, int> = 0>
map(_Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc())
-> map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>;
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty>>,
enable_if_t<conjunction_v<
negation<_Is_allocator<_Pr>>,
_Is_allocator<_Alloc>
>, int> = 0>
map(initializer_list<pair<const _Kty, _Ty>>, _Pr = _Pr(), _Alloc = _Alloc())
-> map<_Kty, _Ty, _Pr, _Alloc>;
template<class _Iter,
class _Alloc,
enable_if_t<conjunction_v<
_Is_iterator<_Iter>,
_Is_allocator<_Alloc>
>, int> = 0>
map(_Iter, _Iter, _Alloc)
-> map<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, less<_Guide_key_t<_Iter>>, _Alloc>;
template<class _Kty,
class _Ty,
class _Alloc,
enable_if_t<_Is_allocator<_Alloc>::value, int> = 0>
map(initializer_list<pair<const _Kty, _Ty>>, _Alloc)
-> map<_Kty, _Ty, less<_Kty>, _Alloc>; #endif /* _HAS_CXX17 */
template
<
class
_Kty
,
class
_Ty
,
class
_Pr
,
class
_Alloc
>
inline
void
swap
(
map
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
>&
_Left
,
map
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
>&
_Right
) {
// swap _Left and _Right maps
_Left
.
swap
(
_Right
); }
// CLASS TEMPLATE multimap
template
<
class
_Kty
,
class
_Ty
,
class
_Pr
=
less
<
_Kty
>,
class
_Alloc
=
allocator
<
pair
<
const
_Kty
,
_Ty
>>>
class
multimap
:
public
_Tree
<
_Tmap_traits
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
,
true
>> {
// ordered red-black tree of {key, mapped} values, non-unique keys
public
:
using
_Mybase
=
_Tree
<
_Tmap_traits
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
,
true
>>;
using
key_type
=
_Kty
;
using
mapped_type
=
_Ty
;
using
key_compare
=
_Pr
;
using
value_compare
=
typename
_Mybase
::
value_compare
;
using
value_type
=
typename
_Mybase
::
value_type
;
using
allocator_type
=
typename
_Mybase
::
allocator_type
;
using
size_type
=
typename
_Mybase
::
size_type
;
using
difference_type
=
typename
_Mybase
::
difference_type
;
using
pointer
=
typename
_Mybase
::
pointer
;
using
const_pointer
=
typename
_Mybase
::
const_pointer
;
using
reference
=
value_type
&;
using
const_reference
=
const
value_type
&;
using
iterator
=
typename
_Mybase
::
iterator
;
using
const_iterator
=
typename
_Mybase
::
const_iterator
;
using
reverse_iterator
=
typename
_Mybase
::
reverse_iterator
;
using
const_reverse_iterator
=
typename
_Mybase
::
const_reverse_iterator
;
using
_Alnode
=
typename
_Mybase
::
_Alnode
;
using
_Alnode_traits
=
typename
_Mybase
::
_Alnode_traits
;
multimap
() :
_Mybase
(
key_compare
()) {
// construct empty map from defaults
}
explicit
multimap
(
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct empty map from defaults, allocator
}
multimap
(
const
multimap
&
_Right
) :
_Mybase
(
_Right
,
_Alnode_traits
::
select_on_container_copy_construction
(
_Right
.
_Getal
())) {
// construct map by copying _Right
}
multimap
(
const
multimap
&
_Right
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Right
,
_Al
) {
// construct map by copying _Right, allocator
}
explicit
multimap
(
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct empty map from comparator
}
multimap
(
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct empty map from comparator and allocator
}
template
<
class
_Iter
>
multimap
(
_Iter
_First
,
_Iter
_Last
) :
_Mybase
(
key_compare
()) {
// construct map from [_First, _Last), defaults
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
multimap
(
_Iter
_First
,
_Iter
_Last
,
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct map from [_First, _Last), comparator
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
multimap
(
_Iter
_First
,
_Iter
_Last
,
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct map from [_First, _Last), allocator
insert
(
_First
,
_Last
); }
template
<
class
_Iter
>
multimap
(
_Iter
_First
,
_Iter
_Last
,
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct map from [_First, _Last), comparator, and allocator
insert
(
_First
,
_Last
); }
multimap
&
operator
=
(
const
multimap
&
_Right
) {
// assign by copying _Right
_Mybase
::
operator
=
(
_Right
);
return
(*
this
); }
multimap
(
multimap
&&
_Right
) {
// construct map by moving _Right
}
multimap
(
multimap
&&
_Right
,
const
allocator_type
&
_Al
) {
// construct map by moving _Right
}
multimap
&
operator
=
(
multimap
&&
_Right
) {
// assign by moving _Right
return
(*
this
); }
template
<
class
...
_Valty
>
iterator
emplace
(
_Valty
&&...
_Val
) {
// try to insert value_type(_Val...), favoring right side
} {
// exchange contents with non-movable _Right
_Mybase
::
swap
(
_Right
); }
using
_Mybase
::
insert
;
template
<
class
_Valty
,
class
=
enable_if_t
<
is_constructible_v
<
value_type
,
_Valty
>>>
iterator
insert
(
_Valty
&&
_Val
) {
// insert _Val
}
template
<
class
_Valty
,
class
=
enable_if_t
<
is_constructible_v
<
value_type
,
_Valty
>>>
iterator
insert
(
const_iterator
_Where
,
_Valty
&&
_Val
) {
// insert _Val with hint
}
multimap
(
initializer_list
<
value_type
>
_Ilist
) :
_Mybase
(
key_compare
()) {
// construct from initializer_list, defaults
insert
(
_Ilist
); }
multimap
(
initializer_list
<
value_type
>
_Ilist
,
const
key_compare
&
_Pred
) :
_Mybase
(
_Pred
) {
// construct from initializer_list, comparator
insert
(
_Ilist
); }
multimap
(
initializer_list
<
value_type
>
_Ilist
,
const
allocator_type
&
_Al
) :
_Mybase
(
key_compare
(),
_Al
) {
// construct from initializer_list, allocator
insert
(
_Ilist
); }
multimap
(
initializer_list
<
value_type
>
_Ilist
,
const
key_compare
&
_Pred
,
const
allocator_type
&
_Al
) :
_Mybase
(
_Pred
,
_Al
) {
// construct from initializer_list, comparator, and allocator
insert
(
_Ilist
); }
multimap
&
operator
=
(
initializer_list
<
value_type
>
_Ilist
) {
// assign initializer_list
_Mybase
::
clear
();
insert
(
_Ilist
);
return
(*
this
); }
using
_Mybase
::
_Unchecked_begin
;
using
_Mybase
::
_Unchecked_end
; };
#if _HAS_CXX17
template<class _Iter,
class _Pr = less<_Guide_key_t<_Iter>>,
class _Alloc = allocator<_Guide_pair_t<_Iter>>,
enable_if_t<conjunction_v<
_Is_iterator<_Iter>,
negation<_Is_allocator<_Pr>>,
_Is_allocator<_Alloc>
>, int> = 0>
multimap(_Iter, _Iter, _Pr = _Pr(), _Alloc = _Alloc())
-> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, _Pr, _Alloc>;
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty>>,
enable_if_t<conjunction_v<
negation<_Is_allocator<_Pr>>,
_Is_allocator<_Alloc>
>, int> = 0>
multimap(initializer_list<pair<const _Kty, _Ty>>, _Pr = _Pr(), _Alloc = _Alloc())
-> multimap<_Kty, _Ty, _Pr, _Alloc>;
template<class _Iter,
class _Alloc,
enable_if_t<conjunction_v<
_Is_iterator<_Iter>,
_Is_allocator<_Alloc>
>, int> = 0>
multimap(_Iter, _Iter, _Alloc)
-> multimap<_Guide_key_t<_Iter>, _Guide_val_t<_Iter>, less<_Guide_key_t<_Iter>>, _Alloc>;
template<class _Kty,
class _Ty,
class _Alloc,
enable_if_t<_Is_allocator<_Alloc>::value, int> = 0>
multimap(initializer_list<pair<const _Kty, _Ty>>, _Alloc)
-> multimap<_Kty, _Ty, less<_Kty>, _Alloc>; #endif /* _HAS_CXX17 */
template
<
class
_Kty
,
class
_Ty
,
class
_Pr
,
class
_Alloc
>
inline
void
swap
(
multimap
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
>&
_Left
,
multimap
<
_Kty
,
_Ty
,
_Pr
,
_Alloc
>&
_Right
) {
// swap _Left and _Right multimaps
_Left
.
swap
(
_Right
); }
#if _HAS_CXX17
namespace pmr {
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>>
using map = _STD map<_Kty, _Ty, _Pr, polymorphic_allocator<pair<const _Kty, _Ty>>>;
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>>
using multimap = _STD multimap<_Kty, _Ty, _Pr, polymorphic_allocator<pair<const _Kty, _Ty>>>;
} // namespace pmr #endif /* _HAS_CXX17 */
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
/* * Copyright (c) by P.J. Plauger. All rights reserved. * Consult your license regarding permissions and restrictions. V6.50:0009 */