150 lines
4.5 KiB
C++
150 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#include <unordered_map>
|
|
#include <filesystem>
|
|
#include <ranges>
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include <shared_mutex>
|
|
|
|
template<typename ID>
|
|
class file_id_lookup
|
|
{
|
|
public:
|
|
using container_type = std::unordered_map<std::filesystem::path, ID>;
|
|
using key_type = typename container_type::key_type;
|
|
using mapped_type = typename container_type::mapped_type;
|
|
using value_type = typename container_type::value_type;
|
|
using size_type = typename container_type::size_type;
|
|
using difference_type = typename container_type::difference_type;
|
|
using hasher = typename container_type::hasher;
|
|
using key_equal = typename container_type::key_equal;
|
|
using allocator_type = typename container_type::allocator_type;
|
|
using reference = typename container_type::reference;
|
|
using const_reference = typename container_type::const_reference;
|
|
using pointer = typename container_type::pointer;
|
|
using const_pointer = typename container_type::const_pointer;
|
|
using iterator = typename container_type::iterator;
|
|
using const_iterator = typename container_type::const_iterator;
|
|
using local_iterator = typename container_type::local_iterator;
|
|
using const_local_iterator = typename container_type::const_local_iterator;
|
|
using node_type = typename container_type::node_type;
|
|
using insert_return_type = typename container_type::insert_return_type;
|
|
|
|
|
|
std::pair<iterator, bool> try_emplace(const key_type& path)
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
auto it = m_container.find(path);
|
|
const auto is_new = it == m_container.end();
|
|
if (is_new) {
|
|
it = m_container.emplace_hint(it, path, ID::next());
|
|
}
|
|
return { it, is_new };
|
|
}
|
|
|
|
[[nodiscard]] bool empty() const noexcept
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.empty();
|
|
}
|
|
[[nodiscard]] size_type size() const noexcept
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.size();
|
|
}
|
|
[[nodiscard]] size_type max_size() const noexcept
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.max_size();
|
|
}
|
|
|
|
void by_extension(const std::string_view extension, std::vector<const_pointer>& dst) const
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
std::ranges::copy(
|
|
m_container |
|
|
std::views::filter([
|
|
&](const value_type& entry) {
|
|
return entry.first.extension() == extension;
|
|
}
|
|
) |
|
|
std::views::transform([
|
|
&](const value_type& entry) {
|
|
return &entry;
|
|
}
|
|
),
|
|
std::back_inserter(dst)
|
|
);
|
|
}
|
|
|
|
|
|
[[nodiscard]] bool contains(const key_type& key) const
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.contains(key);
|
|
}
|
|
[[nodiscard]] size_type count(const key_type& key) const
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.count(key);
|
|
}
|
|
[[nodiscard]] iterator find(const key_type& key)
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.find(key);
|
|
}
|
|
[[nodiscard]] const_iterator find(const key_type& key) const
|
|
{
|
|
std::shared_lock lock(m_mutex);
|
|
return m_container.find(key);
|
|
}
|
|
|
|
iterator erase(iterator pos)
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
return m_container.erase(pos);
|
|
}
|
|
iterator erase(const_iterator pos)
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
return m_container.erase(pos);
|
|
}
|
|
iterator erase(const_iterator first, const_iterator last)
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
return m_container.erase(first, last);
|
|
}
|
|
size_type erase(const key_type& key)
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
return m_container.erase(key);
|
|
}
|
|
void clear() noexcept
|
|
{
|
|
std::unique_lock lock(m_mutex);
|
|
m_container.clear();
|
|
}
|
|
|
|
[[nodiscard]] iterator begin() noexcept { return m_container.begin(); }
|
|
[[nodiscard]] const_iterator begin() const noexcept { return m_container.begin(); }
|
|
[[nodiscard]] const_iterator cbegin() const noexcept { return m_container.cbegin(); }
|
|
[[nodiscard]] iterator end() noexcept { return m_container.end(); }
|
|
[[nodiscard]] const_iterator end() const noexcept { return m_container.end(); }
|
|
[[nodiscard]] const_iterator cend() const noexcept { return m_container.cend(); }
|
|
|
|
|
|
private:
|
|
static auto extension_filter(const std::string_view& extension)
|
|
{
|
|
return std::views::filter(
|
|
[extension](const key_type& path)
|
|
{
|
|
return path.extension() == extension;
|
|
}
|
|
);
|
|
}
|
|
|
|
container_type m_container;
|
|
mutable std::shared_mutex m_mutex;
|
|
}; |