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).
112 lines
2.7 KiB
C++
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 */
|
|
|