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:
parent
8b76d4007e
commit
4481386a3d
@ -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);
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user