psemek/libs/util/include/psemek/util/resource_container.hpp

88 lines
1.4 KiB
C++

#pragma once
#include <psemek/util/hstring.hpp>
#include <vector>
#include <string>
#include <string_view>
#include <cstdint>
#include <unordered_map>
#include <optional>
namespace psemek::util
{
template <typename T, typename Index = std::uint32_t>
struct resource_container
{
using object_id = Index;
using iterator = T *;
using const_iterator = T const *;
struct object
{
std::string const name;
T value;
object(std::string name, T value)
: name(std::move(name))
, value(std::move(value))
{}
};
object & operator[] (Index id)
{
return objects_[id];
}
object const & operator[] (Index id) const
{
return objects_[id];
}
Index add(std::string name, T value)
{
Index id = objects_.size();
name_map_[name] = id;
objects_.emplace_back(std::move(name), std::move(value));
return id;
}
std::optional<object_id> find(std::string_view const & name) const
{
if (auto it = name_map_.find(name); it != name_map_.end())
return it->second;
return std::nullopt;
}
std::size_t size() const
{
return objects_.size();
}
T * begin()
{
return objects_.data();
}
T * end()
{
return begin() + size();
}
T const * begin() const
{
return objects_.data();
}
T const * end() const
{
return begin() + size();
}
private:
std::vector<object> objects_;
std::unordered_map<util::hstring, Index> name_map_;
};
}