Files
MicrOBU/microbu-esp32c5/external/vanetza-idf/vanetza/common/object_container.hpp
T
Ashin Walpola 0e9525162d Keep the colleague's microbu-esp32c5 tree in this repository
obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but
that tree was gitignored, so a clone of this repository could not build the
firmware it ships. It is now committed here as ordinary files in its own
folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP
bridge's signature verification (--trust) used on the bench. Nothing is
fetched from or pushed to the colleague's repository; this repository and
its remotes carry everything. The folder's own .gitignore keeps build output,
downloaded components and private key material out, as it did there; the
committed file set is identical to that repository's tracked files.

The ESP32-C5 is still flashed from obu-firmware/, which only takes
vanetza-idf from microbu-esp32c5/, so the two stay separate folders.
FLASHING.md says how to take a newer version of the colleague's tree (copy
it over the folder, rebuild, test, commit).
2026-09-23 17:46:40 +02:00

112 lines
2.7 KiB
C++

#ifndef OBJECT_CONTAINER_HPP_25SOHVUH
#define OBJECT_CONTAINER_HPP_25SOHVUH
#include <functional>
#include <map>
#include <memory>
#include <typeindex>
#include <type_traits>
namespace vanetza
{
class ObjectContainer
{
private:
struct object_handle
{
template<typename T>
object_handle(std::unique_ptr<T> obj) :
object(obj.release()),
deleter([](void* ptr) { std::default_delete<T>()(static_cast<T*>(ptr)); })
{
}
~object_handle() {
deleter(object);
object = nullptr;
}
void* object;
std::function<void(void*)> deleter;
};
using container_type = std::map<std::type_index, object_handle>;
public:
ObjectContainer() = default;
// no copy
ObjectContainer(const ObjectContainer&) = delete;
ObjectContainer& operator=(const ObjectContainer&) = delete;
// allow move
ObjectContainer(ObjectContainer&&) = default;
ObjectContainer& operator=(ObjectContainer&&) = default;
bool empty() const { return m_container.empty(); }
std::size_t size() const { return m_container.size(); }
void clear() { m_container.clear(); }
template<typename T>
void erase()
{
m_container.erase(std::type_index(typeid(T)));
}
template<typename T>
T* find()
{
T* result = nullptr;
auto found = m_container.find(std::type_index(typeid(T)));
if (found != m_container.end()) {
result = static_cast<T*>(found->second.object);
}
return result;
}
template<typename T>
const T* find() const
{
const T* result = nullptr;
auto found = m_container.find(std::type_index(typeid(T)));
if (found != m_container.end()) {
result = static_cast<const T*>(found->second.object);
}
return result;
}
template<typename T>
bool insert(std::unique_ptr<T> obj)
{
static_assert(std::is_object<T>() && !std::is_const<T>(),
"Only non-const objects are supported by ObjectContainer");
return m_container.emplace(std::type_index(typeid(T)), std::move(obj)).second;
}
template<typename T>
T& get()
{
static_assert(std::is_default_constructible<T>(),
"Only default constructible types are accessible through ObjectContainer::get");
T* result = find<T>();
if (!result) {
std::unique_ptr<T> obj { new T() };
result = obj.get();
if (!insert(std::move(obj)))
result = nullptr;
}
assert(result);
return *result;
}
private:
container_type m_container;
};
} // namespace vanetza
#endif /* OBJECT_CONTAINER_HPP_25SOHVUH */