1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-16 04:05:16 +00:00

Extends Reflection::Struct slightly to capture the lengths of arrays.

This commit is contained in:
Thomas Harte 2020-05-14 22:59:44 -04:00
parent 8b76d4007e
commit 4481386a3d
2 changed files with 33 additions and 4 deletions

View File

@ -56,6 +56,14 @@ class MultiStruct: public Reflection::Struct {
return nullptr;
}
size_t count_of(const std::string &name) const final {
for(auto &options: options_) {
auto info = options->type_of(name);
if(info) return options->count_of(name);
}
return 0;
}
const void *get(const std::string &name) const final {
for(auto &options: options_) {
auto value = options->get(name);

View File

@ -27,6 +27,7 @@ namespace Reflection {
struct Struct {
virtual std::vector<std::string> all_keys() const = 0;
virtual const std::type_info *type_of(const std::string &name) const = 0;
virtual size_t count_of(const std::string &name) const = 0;
virtual void set(const std::string &name, const void *value) = 0;
virtual const void *get(const std::string &name) const = 0;
virtual std::vector<std::string> values_for(const std::string &name) const = 0;
@ -144,6 +145,15 @@ template <typename Owner> class StructImpl: public Struct {
return iterator->second.type;
}
/*!
@returns The number of instances of objects of the same type as @c name that sit consecutively in memory.
*/
size_t count_of(const std::string &name) const final {
const auto iterator = contents_.find(name);
if(iterator == contents_.end()) return 0;
return iterator->second.count;
}
/*!
@returns a list of the valid enum value names for field @c name if it is a declared enum field of this struct;
the empty list otherwise.
@ -206,9 +216,19 @@ template <typename Owner> class StructImpl: public Struct {
it'll be the struct that's exposed.
*/
template <typename Type> void declare(Type *t, const std::string &name) {
// If the declared item is a class, see whether it can be dynamically cast
// to a reflectable for emplacement. If so, exit early.
if constexpr (std::is_class<Type>()) {
if(declare_reflectable(t, name)) return;
}
// If the declared item is an array, record it as a pointer to the
// first element plus a size.
if constexpr (std::is_array<Type>()) {
declare_emplace(&t[0], name, sizeof(*t) / sizeof(*t[0]));
return;
}
declare_emplace(t, name);
}
@ -278,11 +298,11 @@ template <typename Owner> class StructImpl: public Struct {
return false;
}
template <typename Type> void declare_emplace(Type *t, const std::string &name) {
template <typename Type> void declare_emplace(Type *t, const std::string &name, size_t count = 1) {
contents_.emplace(
std::make_pair(
name,
Field(typeid(Type), reinterpret_cast<uint8_t *>(t) - reinterpret_cast<uint8_t *>(this), sizeof(Type))
Field(typeid(Type), reinterpret_cast<uint8_t *>(t) - reinterpret_cast<uint8_t *>(this), sizeof(Type), count)
));
}
@ -290,8 +310,9 @@ template <typename Owner> class StructImpl: public Struct {
const std::type_info *type;
ssize_t offset;
size_t size;
Field(const std::type_info &type, ssize_t offset, size_t size) :
type(&type), offset(offset), size(size) {}
size_t count;
Field(const std::type_info &type, ssize_t offset, size_t size, size_t count) :
type(&type), offset(offset), size(size), count(count) {}
};
static inline std::unordered_map<std::string, Field> contents_;
static inline std::unordered_map<std::string, std::vector<bool>> permitted_enum_values_;