-
Notifications
You must be signed in to change notification settings - Fork 9
/
flat_multimap.hpp
137 lines (112 loc) · 4.05 KB
/
flat_multimap.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright Pubby 2016
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
#ifndef LIB_FLAT_FLAT_MULTIMAP_HPP
#define LIB_FLAT_FLAT_MULTIMAP_HPP
#include "impl/flat_impl.hpp"
namespace fc {
namespace impl {
template<typename D, typename Key, typename Container, typename Compare,
typename = void>
class flat_multimap_base
: public flat_container_base<D, Key, Container, Compare>
{
#include "impl/container_traits.hpp"
using mapped_type = typename value_type::second_type;
using B = flat_container_base<D, Key, Container, Compare>;
D const* self() const { return static_cast<D const*>(this); }
D* self() { return static_cast<D*>(this); }
public:
using value_compare = first_compare<value_type, Compare>;
value_compare value_comp() const { return value_compare(B::key_comp()); }
using B::B;
using B::insert;
using B::erase;
// Modifiers
iterator insert(value_type const& value)
{
iterator it = self()->upper_bound(value.first);
return self()->container.insert(it.underlying, value);
}
iterator insert(value_type&& value)
{
iterator it = self()->upper_bound(value.first);
return self()->container.insert(it.underlying, std::move(value));
}
template<class InputIt>
void insert(InputIt first, InputIt last, delay_sort_t)
{ this->ds_insert_(first, last); }
size_type erase(key_type const& key)
{
auto it_pair = self()->equal_range(key);
std::size_t ret = std::distance(it_pair.first, it_pair.second);
self()->container.erase(it_pair.first.underlying,
it_pair.second.underlying);
return ret;
}
// Lookup
size_type count(key_type const& key) const
{
auto it_pair = self()->equal_range(key);
return std::distance(it_pair.first, it_pair.second);
}
};
template<typename D, typename Key, typename Container, typename Compare>
class flat_multimap_base<D, Key, Container, Compare,
std::void_t<typename Compare::is_transparent>>
: public flat_multimap_base<D, Key, Container, Compare, int>
{
#include "impl/container_traits.hpp"
using mapped_type = typename value_type::second_type;
using B = flat_multimap_base<D, Key, Container, Compare, int>;
D const* self() const { return static_cast<D const*>(this); }
D* self() { return static_cast<D*>(this); }
public:
using B::B;
using B::insert;
using B::count;
// Modifiers
template<class P>
iterator insert(P&& value)
{
iterator it = self()->upper_bound(value.first);
return self()->container.insert(it.underlying,
std::forward<P>(value));
}
// Lookup
template<typename K>
size_type count(K const& key) const
{
auto it_pair = self()->equal_range(key);
return std::distance(it_pair.first, it_pair.second);
}
};
} // namespace impl
template<typename Container, typename Compare = std::less<void>>
class flat_multimap
: public impl::flat_multimap_base<flat_multimap<Container, Compare>,
typename Container::value_type::first_type, Container, Compare>
{
using B = impl::flat_multimap_base<flat_multimap<Container, Compare>,
typename Container::value_type::first_type, Container, Compare>;
#define FLATNAME flat_multimap
#define FLATKEY typename Container::value_type::first_type
#include "impl/class_def.hpp"
#undef FLATNAME
#undef FLATKEY
};
template<typename Key, typename T, typename Compare = std::less<void>>
using vector_multimap
= flat_multimap<std::vector<std::pair<Key, T>>, Compare>;
template<typename Container, typename Compare>
inline bool operator==(const flat_multimap<Container, Compare>& lhs, const flat_multimap<Container, Compare>& rhs)
{
return lhs.container == rhs.container;
}
template<typename Container, typename Compare>
inline bool operator!=(const flat_multimap<Container, Compare>& lhs, const flat_multimap<Container, Compare>& rhs)
{
return lhs.container != rhs.container;
}
} // namespace fc
#endif