125 lines
2.6 KiB
C++
125 lines
2.6 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include "Data/Concurent/MutexProtectedObject.hpp"
|
|
|
|
#undef MAP_TYPE
|
|
|
|
namespace OpenVulkano
|
|
{
|
|
template<typename KEY, typename VALUE>
|
|
class ThreadSafeMap
|
|
{
|
|
using MAP_TYPE = std::map<KEY, VALUE>;
|
|
using SMPO_TYPE = SharedMutexProtectedObject<MAP_TYPE, SpintexShared>;
|
|
SMPO_TYPE m_map;
|
|
|
|
public:
|
|
|
|
struct LockingIterator
|
|
{
|
|
typename MAP_TYPE::iterator iter;
|
|
typename SMPO_TYPE::SharedAccessor accessor;
|
|
|
|
LockingIterator(typename MAP_TYPE::iterator iter, typename SMPO_TYPE::SharedAccessor& accessor)
|
|
: iter(iter), accessor(std::move(accessor))
|
|
{}
|
|
|
|
typename MAP_TYPE::reference operator*() const noexcept
|
|
{ return *iter; }
|
|
|
|
typename MAP_TYPE::pointer operator->() const noexcept
|
|
{ return iter.operator->(); }
|
|
|
|
LockingIterator& operator++() noexcept
|
|
{
|
|
iter++;
|
|
return *this;
|
|
}
|
|
|
|
LockingIterator& operator++(int) noexcept
|
|
{
|
|
iter++;
|
|
return *this;
|
|
}
|
|
|
|
LockingIterator& operator--() noexcept
|
|
{
|
|
iter--;
|
|
return *this;
|
|
}
|
|
|
|
LockingIterator& operator--(int) noexcept
|
|
{
|
|
iter--;
|
|
return *this;
|
|
}
|
|
|
|
friend bool
|
|
operator==(const LockingIterator& lhs, const LockingIterator& rhs) noexcept
|
|
{ return lhs.iter == rhs.iter; }
|
|
|
|
friend bool
|
|
operator!=(const LockingIterator& lhs, const LockingIterator& rhs) noexcept
|
|
{ return lhs.iter != rhs.iter; }
|
|
};
|
|
|
|
std::optional<typename MAP_TYPE::iterator> find(KEY key)
|
|
{
|
|
auto access = m_map.SharedAccess();
|
|
auto result = access->find(key);
|
|
if (result == access->end()) return std::nullopt;
|
|
return result;
|
|
}
|
|
|
|
void erase(typename MAP_TYPE::iterator iter)
|
|
{
|
|
auto access = m_map.Access();
|
|
access->erase(iter);
|
|
}
|
|
|
|
void erase(KEY key)
|
|
{
|
|
auto access = m_map.Access();
|
|
access->erase(key);
|
|
}
|
|
|
|
LockingIterator begin()
|
|
{
|
|
auto access = m_map.SharedAccess();
|
|
return LockingIterator(access->begin(), access);
|
|
}
|
|
|
|
LockingIterator end()
|
|
{
|
|
auto access = m_map.SharedAccess();
|
|
return LockingIterator(access->end(), access);
|
|
}
|
|
|
|
template<typename... _Args>
|
|
std::pair<typename MAP_TYPE::iterator, bool> emplace(_Args&&... __args)
|
|
{
|
|
auto access = m_map.Access();
|
|
return access->emplace(std::forward<_Args>(__args)...);
|
|
}
|
|
|
|
[[nodiscard]] size_t size() const
|
|
{
|
|
return m_map.UnsafeAccess().size();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
auto access = m_map.Access();
|
|
access->clear();
|
|
}
|
|
};
|
|
}
|