Make rtengine::Cache
build again with hashable keys
While STL containers are not guaranteed to build with incomplete types, `rtengine::Cache` used to build with `std::map` as well as `std::unordered_map` when I first implemented it. With GCC 6.3 I recently realized, that this was no longer the case for hashable keys (i.e. `std::unordered_map` as `Store`). The recommended workaround is to use a `std::unique_ptr`.
This commit is contained in:
@@ -19,11 +19,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
@@ -87,9 +88,9 @@ public:
|
|||||||
lru_list.splice(
|
lru_list.splice(
|
||||||
lru_list.begin(),
|
lru_list.begin(),
|
||||||
lru_list,
|
lru_list,
|
||||||
store_it->second.lru_list_it
|
store_it->second->lru_list_it
|
||||||
);
|
);
|
||||||
value = store_it->second.value;
|
value = store_it->second->value;
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ public:
|
|||||||
mutex.lock();
|
mutex.lock();
|
||||||
if (hook) {
|
if (hook) {
|
||||||
for (const auto& entry : store) {
|
for (const auto& entry : store) {
|
||||||
hook->onRemove(entry.first, entry.second.value);
|
hook->onRemove(entry.first, entry.second->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lru_list.clear();
|
lru_list.clear();
|
||||||
@@ -152,13 +153,13 @@ private:
|
|||||||
|
|
||||||
using Store = typename std::conditional<
|
using Store = typename std::conditional<
|
||||||
cache_helper::has_hash<K>::value,
|
cache_helper::has_hash<K>::value,
|
||||||
std::unordered_map<K, Value>,
|
std::unordered_map<K, std::unique_ptr<Value>>,
|
||||||
std::map<K, Value>
|
std::map<K, std::unique_ptr<Value>>
|
||||||
>::type;
|
>::type;
|
||||||
using StoreIterator = typename Store::iterator;
|
using StoreIterator = typename Store::iterator;
|
||||||
using StoreConstIterator = typename Store::const_iterator;
|
using StoreConstIterator = typename Store::const_iterator;
|
||||||
|
|
||||||
typedef std::list<StoreIterator> LruList;
|
using LruList = std::list<StoreIterator>;
|
||||||
using LruListIterator = typename LruList::iterator;
|
using LruListIterator = typename LruList::iterator;
|
||||||
|
|
||||||
struct Value {
|
struct Value {
|
||||||
@@ -176,7 +177,7 @@ private:
|
|||||||
{
|
{
|
||||||
const StoreIterator store_it = lru_list.back();
|
const StoreIterator store_it = lru_list.back();
|
||||||
if (hook) {
|
if (hook) {
|
||||||
hook->onDiscard(store_it->first, store_it->second.value);
|
hook->onDiscard(store_it->first, store_it->second->value);
|
||||||
}
|
}
|
||||||
store.erase(store_it);
|
store.erase(store_it);
|
||||||
lru_list.pop_back();
|
lru_list.pop_back();
|
||||||
@@ -193,23 +194,25 @@ private:
|
|||||||
discard();
|
discard();
|
||||||
}
|
}
|
||||||
lru_list.push_front(store.end());
|
lru_list.push_front(store.end());
|
||||||
const Value v = {
|
std::unique_ptr<Value> v(
|
||||||
value,
|
new Value{
|
||||||
lru_list.begin()
|
value,
|
||||||
};
|
lru_list.begin()
|
||||||
lru_list.front() = store.emplace(key, v).first;
|
}
|
||||||
|
);
|
||||||
|
lru_list.front() = store.emplace(key, std::move(v)).first;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mode == Mode::UNCOND || mode == Mode::KNOWN) {
|
if (mode == Mode::UNCOND || mode == Mode::KNOWN) {
|
||||||
if (hook) {
|
if (hook) {
|
||||||
hook->onDisplace(key, store_it->second.value);
|
hook->onDisplace(key, store_it->second->value);
|
||||||
}
|
}
|
||||||
lru_list.splice(
|
lru_list.splice(
|
||||||
lru_list.begin(),
|
lru_list.begin(),
|
||||||
lru_list,
|
lru_list,
|
||||||
store_it->second.lru_list_it
|
store_it->second->lru_list_it
|
||||||
);
|
);
|
||||||
store_it->second.value = value;
|
store_it->second->value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
@@ -220,9 +223,9 @@ private:
|
|||||||
void remove(const StoreIterator& store_it)
|
void remove(const StoreIterator& store_it)
|
||||||
{
|
{
|
||||||
if (hook) {
|
if (hook) {
|
||||||
hook->onRemove(store_it->first, store_it->second.value);
|
hook->onRemove(store_it->first, store_it->second->value);
|
||||||
}
|
}
|
||||||
lru_list.erase(store_it->second.lru_list_it);
|
lru_list.erase(store_it->second->lru_list_it);
|
||||||
store.erase(store_it);
|
store.erase(store_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user