mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-08 06:15:23 +00:00
Add new method ObjTable::emplace_back
This commit is contained in:
parent
4badc78aea
commit
7777ea84e7
@ -28,6 +28,7 @@ template <class T>
|
||||
class ObjTable: public std::vector<T>
|
||||
{
|
||||
public:
|
||||
using reference = T&;
|
||||
ObjTable() = default;
|
||||
ObjTable(const ObjTable&) = delete;
|
||||
ObjTable(ObjTable&&) = delete;
|
||||
@ -99,6 +100,18 @@ class ObjTable: public std::vector<T>
|
||||
return element(id);
|
||||
}
|
||||
|
||||
// emplace_back to the end of the vector. If there are any conflicting sparse elements, emplace
|
||||
// them to the back of the vector before adding the current element.
|
||||
template <class... Args>
|
||||
inline T&
|
||||
emplace_back(Args&&... args)
|
||||
{
|
||||
if (min_sparse == std::vector<T>::size()) {
|
||||
return emplace_back_large(std::forward<Args&&...>(args...));
|
||||
}
|
||||
return std::vector<T>::emplace_back(std::forward<Args&&...>(args...));
|
||||
}
|
||||
|
||||
void
|
||||
resize(size_t a_size)
|
||||
{
|
||||
@ -168,6 +181,22 @@ class ObjTable: public std::vector<T>
|
||||
throw std::runtime_error("Impossibly large object id encountered accessing ObjTable");
|
||||
return element(0); // doesn't return
|
||||
}
|
||||
|
||||
// Must only be called by emplace_back. Separated out from emplace_back to keep inlined code
|
||||
// tight.
|
||||
template <class... Args>
|
||||
T&
|
||||
emplace_back_large(Args&&... args)
|
||||
{
|
||||
auto it = sparse_elements.begin();
|
||||
auto end = sparse_elements.end();
|
||||
while (it != end && it->first == std::vector<T>::size()) {
|
||||
std::vector<T>::emplace_back(std::move(it->second));
|
||||
it = sparse_elements.erase(it);
|
||||
}
|
||||
min_sparse = (it == end) ? std::numeric_limits<size_t>::max() : it->first;
|
||||
return std::vector<T>::emplace_back(std::forward<Args&&...>(args...));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OBJTABLE_HH
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
struct Test
|
||||
{
|
||||
Test() = default;
|
||||
Test(int value) :
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
int value{0};
|
||||
};
|
||||
|
||||
@ -24,11 +29,15 @@ class Table: public ObjTable<Test>
|
||||
(*this)[i].value = 2 * i;
|
||||
}
|
||||
resize(100);
|
||||
for (int i: {1, 99, 100, 105, 110, 120, 220}) {
|
||||
for (int i: {1, 99, 100, 105, 110, 120, 205, 206, 207, 210}) {
|
||||
(*this)[i].value = 3 * i;
|
||||
}
|
||||
resize(200);
|
||||
|
||||
for (int i = 1; i < 10; ++i) {
|
||||
emplace_back(i);
|
||||
}
|
||||
|
||||
forEach([](auto i, auto const& item) -> void {
|
||||
if (item.value) {
|
||||
std::cout << std::to_string(i) << " : " << std::to_string(item.value) << "\n";
|
||||
|
@ -22,7 +22,19 @@
|
||||
199 : 398
|
||||
200 : 400
|
||||
201 : 402
|
||||
220 : 660
|
||||
202 : 1
|
||||
203 : 2
|
||||
204 : 3
|
||||
205 : 615
|
||||
206 : 618
|
||||
207 : 621
|
||||
208 : 4
|
||||
209 : 5
|
||||
210 : 630
|
||||
211 : 6
|
||||
212 : 7
|
||||
213 : 8
|
||||
214 : 9
|
||||
1000 : 2000
|
||||
1001 : 2002
|
||||
1002 : 2004
|
||||
|
Loading…
Reference in New Issue
Block a user