mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-09 02:31:22 +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;
|
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 {
|
const void *get(const std::string &name) const final {
|
||||||
for(auto &options: options_) {
|
for(auto &options: options_) {
|
||||||
auto value = options->get(name);
|
auto value = options->get(name);
|
||||||
|
@ -27,6 +27,7 @@ namespace Reflection {
|
|||||||
struct Struct {
|
struct Struct {
|
||||||
virtual std::vector<std::string> all_keys() const = 0;
|
virtual std::vector<std::string> all_keys() const = 0;
|
||||||
virtual const std::type_info *type_of(const std::string &name) 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 void set(const std::string &name, const void *value) = 0;
|
||||||
virtual const void *get(const std::string &name) const = 0;
|
virtual const void *get(const std::string &name) const = 0;
|
||||||
virtual std::vector<std::string> values_for(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;
|
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;
|
@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.
|
the empty list otherwise.
|
||||||
@ -206,9 +216,19 @@ template <typename Owner> class StructImpl: public Struct {
|
|||||||
it'll be the struct that's exposed.
|
it'll be the struct that's exposed.
|
||||||
*/
|
*/
|
||||||
template <typename Type> void declare(Type *t, const std::string &name) {
|
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 constexpr (std::is_class<Type>()) {
|
||||||
if(declare_reflectable(t, name)) return;
|
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);
|
declare_emplace(t, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,11 +298,11 @@ template <typename Owner> class StructImpl: public Struct {
|
|||||||
return false;
|
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(
|
contents_.emplace(
|
||||||
std::make_pair(
|
std::make_pair(
|
||||||
name,
|
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;
|
const std::type_info *type;
|
||||||
ssize_t offset;
|
ssize_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
Field(const std::type_info &type, ssize_t offset, size_t size) :
|
size_t count;
|
||||||
type(&type), offset(offset), size(size) {}
|
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, Field> contents_;
|
||||||
static inline std::unordered_map<std::string, std::vector<bool>> permitted_enum_values_;
|
static inline std::unordered_map<std::string, std::vector<bool>> permitted_enum_values_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user