-
Notifications
You must be signed in to change notification settings - Fork 7
/
sorted_vector.h
179 lines (162 loc) · 4.37 KB
/
sorted_vector.h
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#ifndef RDESTL_SORTED_VECTOR_H
#define RDESTL_SORTED_VECTOR_H
#include "functional.h"
#include "pair.h"
#include "sort.h"
#include "vector.h"
namespace rde
{
namespace internal
{
//=========================================================================
template<class TPair, class TFunctor>
struct compare_func
{
bool operator()(const TPair& lhs, const TPair& rhs) const
{
return TFunctor()(lhs.first, rhs.first);
}
bool operator()(const TPair& lhs, const typename TPair::first_type& rhs) const
{
return TFunctor()(lhs.first, rhs);
}
bool operator()(const typename TPair::first_type& lhs, const TPair& rhs) const
{
return TFunctor()(lhs, rhs.first);
}
};
} // namespace internal
//=============================================================================
template<typename TKey, typename TValue,
class TCompare = rde::less<TKey>,
class TAllocator = rde::allocator,
class TStorage = rde::standard_vector_storage<pair<TKey, TValue>, TAllocator>
>
class sorted_vector: private vector<pair<TKey, TValue>, TAllocator, TStorage>
{
typedef vector<pair<TKey, TValue>, TAllocator, TStorage> Base;
public:
typedef TKey key_type;
typedef TValue mapped_type;
typedef typename Base::size_type size_type;
typedef typename Base::value_type value_type;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::allocator_type allocator_type;
explicit sorted_vector(const allocator_type& allocator = allocator_type())
: Base(allocator)
{
/**/
}
template <class InputIterator>
sorted_vector(InputIterator first, InputIterator last,
const allocator_type& allocator = allocator_type())
: Base(first, last, allocator)
{
rde::quick_sort(begin(), end(), m_compare);
RDE_ASSERT(invariant());
}
// @note: no non-const operator[], it may cause performance problems.
// use explicit ways: insert or find.
using Base::begin;
using Base::end;
using Base::size;
using Base::empty;
using Base::capacity;
pair<iterator, bool> insert(const value_type& val)
{
RDE_ASSERT(invariant());
bool found(true);
iterator it = lower_bound(val.first);
if (it == end() || m_compare(val, *it))
{
it = Base::insert(it, val);
found = false;
}
RDE_ASSERT(invariant());
return pair<iterator, bool>(it, !found);
}
// @extension
RDE_FORCEINLINE pair<iterator, bool> insert(const key_type& k, const mapped_type& v)
{
return insert(value_type(k, v));
}
iterator find(const key_type& k)
{
RDE_ASSERT(invariant());
iterator i(lower_bound(k));
if (i != end() && m_compare(k, *i))
{
i = end();
}
return i;
}
const_iterator find(const key_type& k) const
{
RDE_ASSERT(invariant());
const_iterator i(lower_bound(k));
if (i != end() && m_compare(k, *i))
{
i = end();
}
return i;
}
RDE_FORCEINLINE iterator erase(iterator it)
{
RDE_ASSERT(invariant());
return Base::erase(it);
}
size_type erase(const key_type& k)
{
iterator i(find(k));
if (i == end())
return 0;
erase(i);
RDE_ASSERT(invariant());
return 1;
}
using Base::clear;
using Base::get_allocator;
using Base::set_allocator;
iterator lower_bound(const key_type& k)
{
return rde::lower_bound(begin(), end(), k, m_compare);
}
const_iterator lower_bound(const key_type& k) const
{
return rde::lower_bound(begin(), end(), k, m_compare);
}
iterator upper_bound(const key_type& k)
{
return rde::upper_bound(begin(), end(), k, m_compare);
}
const_iterator upper_bound(const key_type& k) const
{
return rde::upper_bound(begin(), end(), k, m_compare);
}
private:
// @note: block copying for the time being.
sorted_vector(const sorted_vector&);
sorted_vector& operator=(const sorted_vector&);
bool invariant() const
{
// Make sure we're sorted according to m_compare.
const_iterator first = begin();
const_iterator last = end();
RDE_ASSERT(last >= first);
if (first != last)
{
const_iterator next = first;
if (++next != last)
{
RDE_ASSERT(m_compare(*first, *next));
first = next;
}
}
return true;
}
internal::compare_func<value_type, TCompare> m_compare;
};
} // namespace rde
//-----------------------------------------------------------------------------
#endif // #ifndef RDESTL_SORTED_VECTOR_H