Files
Z3D/include/util/file_id_lookup.hpp
2025-04-01 21:51:56 +02:00

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;
};