Skip to content

Commit

Permalink
feat(core): define reflection for std::vector
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Sep 19, 2023
1 parent 742a020 commit 49ca5b5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
1 change: 1 addition & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ set(CUBOS_CORE_INCLUDE
"include/cubos/core/reflection/traits/constructible.hpp"
"include/cubos/core/reflection/traits/array.hpp"
"include/cubos/core/reflection/external/primitives.hpp"
"include/cubos/core/reflection/external/vector.hpp"

"include/cubos/core/data/serializer.hpp"
"include/cubos/core/data/deserializer.hpp"
Expand Down
62 changes: 62 additions & 0 deletions core/include/cubos/core/reflection/external/vector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/// @file
/// @brief Reflection declaration for `std::vector`.
/// @ingroup core-reflection

#pragma once

#include <vector>

#include <cubos/core/reflection/traits/array.hpp>
#include <cubos/core/reflection/traits/constructible_utils.hpp>
#include <cubos/core/reflection/type.hpp>

CUBOS_REFLECT_EXTERNAL_TEMPLATE((typename T), (std::vector<T>))
{
// This is a bit scary but isn't doing anything too crazy.
// We are supplying, first, the element type, and then a getter for the length and another for
// the address of an element.

auto arrayTrait = ArrayTrait(
reflect<T>(),
[](const void* instance) -> std::size_t { return static_cast<const std::vector<T>*>(instance)->size(); },
[](const void* instance, std::size_t index) -> uintptr_t {
return reinterpret_cast<uintptr_t>(static_cast<const std::vector<T>*>(instance)->data() + index);
});

// We supply the insert functions depending on the constructibility of the element type.

if constexpr (std::is_default_constructible<T>::value)
{
arrayTrait.insertDefault([](void* instance, std::size_t index) {
auto* vec = static_cast<std::vector<T>*>(instance);
vec->emplace(vec->begin() + static_cast<std::ptrdiff_t>(index));
});
}

if constexpr (std::is_copy_constructible<T>::value)
{
arrayTrait.insertCopy([](void* instance, std::size_t index, const void* value) {
auto* vec = static_cast<std::vector<T>*>(instance);
vec->emplace(vec->begin() + static_cast<std::ptrdiff_t>(index), *static_cast<const T*>(value));
});
}

if constexpr (std::is_move_constructible<T>::value)
{
arrayTrait.insertMove([](void* instance, std::size_t index, void* value) {
auto* vec = static_cast<std::vector<T>*>(instance);
vec->emplace(vec->begin() + static_cast<std::ptrdiff_t>(index), std::move(*static_cast<T*>(value)));
});
}

// We supply the erase function always, as it is always possible to erase an element of a vector.

arrayTrait.erase([](void* instance, std::size_t index) {
auto* vec = static_cast<std::vector<T>*>(instance);
vec->erase(vec->begin() + static_cast<std::ptrdiff_t>(index));
});

return Type::create("std::vector<" + reflect<T>().name() + ">")
.with(arrayTrait)
.with(autoConstructibleTrait<std::vector<T>>());
}

0 comments on commit 49ca5b5

Please sign in to comment.