mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-22 08:16:42 +00:00
Ensures that reflection is completely blind; starts adding SDL instantiation logic.
This commit is contained in:
+28
-10
@@ -72,19 +72,20 @@ class Enum {
|
||||
}
|
||||
|
||||
members_by_type_.emplace(std::make_pair(&typeid(Type), result));
|
||||
names_by_type_.emplace(std::make_pair(&typeid(Type), std::string(name)));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns the declared name of the enum @c Type if it has been registered; the empty string otherwise.
|
||||
*/
|
||||
template <typename Type> const std::string &name() {
|
||||
template <typename Type> static const std::string &name() {
|
||||
return name(typeid(Type));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns the declared name of the enum with type_info @c type if it has been registered; the empty string otherwise.
|
||||
*/
|
||||
const std::string &name(const std::type_info &type) {
|
||||
static const std::string &name(const std::type_info &type) {
|
||||
const auto entry = names_by_type_.find(&type);
|
||||
if(entry == names_by_type_.end()) return empty_string_;
|
||||
return entry->second;
|
||||
@@ -93,14 +94,14 @@ class Enum {
|
||||
/*!
|
||||
@returns the number of members of the enum @c Type if it has been registered; 0 otherwise.
|
||||
*/
|
||||
template <typename Type> size_t size() {
|
||||
template <typename Type> static size_t size() {
|
||||
return size(typeid(Type));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns the number of members of the enum with type_info @c type if it has been registered; @c std::string::npos otherwise.
|
||||
*/
|
||||
size_t size(const std::type_info &type) {
|
||||
static size_t size(const std::type_info &type) {
|
||||
const auto entry = members_by_type_.find(&type);
|
||||
if(entry == members_by_type_.end()) return std::string::npos;
|
||||
return entry->second.size();
|
||||
@@ -109,32 +110,48 @@ class Enum {
|
||||
/*!
|
||||
@returns A @c std::string name for the enum value @c e.
|
||||
*/
|
||||
template <typename Type> static const std::string &toString(Type e) {
|
||||
return toString(typeid(Type), size_t(e));
|
||||
template <typename Type> static const std::string &to_string(Type e) {
|
||||
return to_string(typeid(Type), size_t(e));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns A @c std::string name for the enum value @c e from the enum with type_info @c type.
|
||||
*/
|
||||
static const std::string &toString(const std::type_info &type, size_t e) {
|
||||
static const std::string &to_string(const std::type_info &type, size_t e) {
|
||||
const auto entry = members_by_type_.find(&type);
|
||||
if(entry == members_by_type_.end()) return empty_string_;
|
||||
return entry->second[e];
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns a vector naming the members of the enum with type_info @c type if it has been registered; an empty vector otherwise.
|
||||
*/
|
||||
static const std::vector<std::string> &all_values(const std::type_info &type) {
|
||||
const auto entry = members_by_type_.find(&type);
|
||||
if(entry == members_by_type_.end()) return empty_vector_;
|
||||
return entry->second;
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns a vector naming the members of the enum @c Type type if it has been registered; an empty vector otherwise.
|
||||
*/
|
||||
template <typename Type> static const std::vector<std::string> &all_values() {
|
||||
return all_values(typeid(Type));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns A value of @c Type for the name @c str, or @c EnumType(std::string::npos) if
|
||||
the name is not found.
|
||||
*/
|
||||
template <typename Type> Type fromString(const std::string &str) {
|
||||
return Type(fromString(typeid(Type), str));
|
||||
template <typename Type> static Type from_string(const std::string &str) {
|
||||
return Type(from_string(typeid(Type), str));
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns A value for the name @c str in the enum with type_info @c type , or @c std::string::npos if
|
||||
the name is not found.
|
||||
*/
|
||||
size_t fromString(const std::type_info &type, const std::string &str) {
|
||||
static size_t from_string(const std::type_info &type, const std::string &str) {
|
||||
const auto entry = members_by_type_.find(&type);
|
||||
if(entry == members_by_type_.end()) return std::string::npos;
|
||||
const auto iterator = std::find(entry->second.begin(), entry->second.end(), str);
|
||||
@@ -146,6 +163,7 @@ class Enum {
|
||||
static inline std::unordered_map<const std::type_info *, std::vector<std::string>> members_by_type_;
|
||||
static inline std::unordered_map<const std::type_info *, std::string> names_by_type_;
|
||||
static inline const std::string empty_string_;
|
||||
static inline const std::vector<std::string> empty_vector_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+19
-11
@@ -19,16 +19,24 @@ namespace Reflection {
|
||||
|
||||
#define DeclareField(Name) declare(&Name, #Name)
|
||||
|
||||
template <typename Owner> class Struct {
|
||||
struct Struct {
|
||||
virtual std::vector<std::string> all_keys() = 0;
|
||||
virtual const std::type_info *type_of(const std::string &name) = 0;
|
||||
virtual void set(const std::string &name, const void *value) = 0;
|
||||
virtual const void *get(const std::string &name) = 0;
|
||||
virtual ~Struct() {}
|
||||
};
|
||||
|
||||
template <typename Owner> class StructImpl: public Struct {
|
||||
public:
|
||||
/*!
|
||||
@returns the value of type @c Type that is loaded from the offset registered for the field @c name.
|
||||
It is the caller's responsibility to provide an appropriate type of data.
|
||||
*/
|
||||
template <typename Type> const Type *get(const std::string &name) {
|
||||
const void *get(const std::string &name) final {
|
||||
const auto iterator = contents_.find(name);
|
||||
if(iterator == contents_.end()) return nullptr;
|
||||
return reinterpret_cast<Type *>(reinterpret_cast<uint8_t *>(this) + iterator->second.offset);
|
||||
return reinterpret_cast<uint8_t *>(this) + iterator->second.offset;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -36,16 +44,16 @@ template <typename Owner> class Struct {
|
||||
|
||||
It is the caller's responsibility to provide an appropriate type of data.
|
||||
*/
|
||||
template <typename Type> void set(const std::string &name, const Type &value) {
|
||||
void set(const std::string &name, const void *value) final {
|
||||
const auto iterator = contents_.find(name);
|
||||
if(iterator == contents_.end()) return;
|
||||
*reinterpret_cast<Type *>(reinterpret_cast<uint8_t *>(this) + iterator->second.offset) = value;
|
||||
memcpy(reinterpret_cast<uint8_t *>(this) + iterator->second.offset, value, iterator->second.size);
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns @c type_info for the field @c name.
|
||||
*/
|
||||
const std::type_info *type_of(const std::string &name) {
|
||||
const std::type_info *type_of(const std::string &name) final {
|
||||
const auto iterator = contents_.find(name);
|
||||
if(iterator == contents_.end()) return nullptr;
|
||||
return iterator->second.type;
|
||||
@@ -54,7 +62,7 @@ template <typename Owner> class Struct {
|
||||
/*!
|
||||
@returns A vector of all declared fields for this struct.
|
||||
*/
|
||||
std::vector<std::string> all_keys() {
|
||||
std::vector<std::string> all_keys() final {
|
||||
std::vector<std::string> keys;
|
||||
for(const auto &pair: contents_) {
|
||||
keys.push_back(pair.first);
|
||||
@@ -82,7 +90,7 @@ template <typename Owner> class Struct {
|
||||
contents_.emplace(
|
||||
std::make_pair(
|
||||
name,
|
||||
Field(typeid(Type), reinterpret_cast<uint8_t *>(t) - reinterpret_cast<uint8_t *>(this))
|
||||
Field(typeid(Type), reinterpret_cast<uint8_t *>(t) - reinterpret_cast<uint8_t *>(this), sizeof(Type))
|
||||
));
|
||||
}
|
||||
|
||||
@@ -96,9 +104,9 @@ template <typename Owner> class Struct {
|
||||
private:
|
||||
struct Field {
|
||||
const std::type_info *type;
|
||||
ssize_t offset;
|
||||
Field(const std::type_info &type, ssize_t offset) :
|
||||
type(&type), offset(offset) {}
|
||||
ssize_t offset, size;
|
||||
Field(const std::type_info &type, ssize_t offset, size_t size) :
|
||||
type(&type), offset(offset), size(size) {}
|
||||
};
|
||||
static inline std::unordered_map<std::string, Field> contents_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user