|
@@ -13,6 +13,7 @@
|
|
|
#include <utility>
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "reflection/forward.h"
|
|
#include "reflection/forward.h"
|
|
|
|
|
+#include "reflection/scope.h"
|
|
|
|
|
|
|
|
namespace reflection {
|
|
namespace reflection {
|
|
|
class Object {
|
|
class Object {
|
|
@@ -31,6 +32,9 @@ public:
|
|
|
}
|
|
}
|
|
|
std::string_view path() const { return name_; }
|
|
std::string_view path() const { return name_; }
|
|
|
std::type_index type() const { return type_; }
|
|
std::type_index type() const { return type_; }
|
|
|
|
|
+ std::string_view type_name() const {
|
|
|
|
|
+ return type_name_.empty() ? type_.name() : type_name_;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
template <typename T> bool is_a() const { return type_ == typeid(T); }
|
|
template <typename T> bool is_a() const { return type_ == typeid(T); }
|
|
|
|
|
|
|
@@ -47,10 +51,13 @@ public:
|
|
|
Object get(std::string_view id) & { return (this->*get_)(id); }
|
|
Object get(std::string_view id) & { return (this->*get_)(id); }
|
|
|
Object get(std::string_view id) const & { return (this->*get_)(id); }
|
|
Object get(std::string_view id) const & { return (this->*get_)(id); }
|
|
|
Object get(std::string_view id) && { return (this->*get_)(id).own(); }
|
|
Object get(std::string_view id) && { return (this->*get_)(id).own(); }
|
|
|
|
|
+
|
|
|
|
|
+ Object get(Scope const & scope) const {
|
|
|
|
|
+ if (type_name() != scope.type_name()) { throw std::bad_cast(); }
|
|
|
|
|
+ return get(*this, scope.begin(), scope.end());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- template <typename C,
|
|
|
|
|
- typename = std::enable_if_t<std::is_constructible_v<
|
|
|
|
|
- std::string_view, decltype(*std::begin(std::declval<C>()))>>>
|
|
|
|
|
|
|
+ template <typename C, typename = std::enable_if_t<IS_SCOPE_CONTAINER(C)>>
|
|
|
Object get(C const & container) const {
|
|
Object get(C const & container) const {
|
|
|
return get(*this, std::begin(container), std::end(container));
|
|
return get(*this, std::begin(container), std::end(container));
|
|
|
}
|
|
}
|
|
@@ -72,7 +79,8 @@ private:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- std::type_index type_; //
|
|
|
|
|
|
|
+ std::type_index type_;
|
|
|
|
|
+ std::string_view type_name_; // A more human-readable version of type_
|
|
|
std::string name_; // The property name as a dot-separated path
|
|
std::string name_; // The property name as a dot-separated path
|
|
|
// Are we using a proxy class to store non-trivial setter behavior
|
|
// Are we using a proxy class to store non-trivial setter behavior
|
|
|
bool proxy_{false};
|
|
bool proxy_{false};
|
|
@@ -99,23 +107,23 @@ template <typename T> Object Object::accessor(std::string_view id) const {
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
Object::Object(T const & data, std::string name)
|
|
Object::Object(T const & data, std::string name)
|
|
|
- : type_(typeid(T)), name_(std::move(name)), const_(true),
|
|
|
|
|
|
|
+ : type_(typeid(T)), type_name_(Name<T>), name_(std::move(name)), const_(true),
|
|
|
data_(const_cast<T *>(&data), [](auto *) {}), get_(&Object::getter<T>) {}
|
|
data_(const_cast<T *>(&data), [](auto *) {}), get_(&Object::getter<T>) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
Object::Object(T & data, std::string name)
|
|
Object::Object(T & data, std::string name)
|
|
|
- : type_(typeid(T)), name_(std::move(name)), const_(false),
|
|
|
|
|
|
|
+ : type_(typeid(T)), type_name_(Name<T>), name_(std::move(name)), const_(false),
|
|
|
data_(&data, [](auto *) {}), get_(&Object::accessor<T>) {}
|
|
data_(&data, [](auto *) {}), get_(&Object::accessor<T>) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
Object::Object(T && data, std::string name)
|
|
Object::Object(T && data, std::string name)
|
|
|
- : type_(typeid(T)), name_(std::move(name)), const_(true),
|
|
|
|
|
|
|
+ : type_(typeid(T)), type_name_(Name<T>), name_(std::move(name)), const_(true),
|
|
|
data_(std::make_shared<T>(std::move(data))), get_(&Object::getter<T>),
|
|
data_(std::make_shared<T>(std::move(data))), get_(&Object::getter<T>),
|
|
|
clone_(&Object::deep<T>) {}
|
|
clone_(&Object::deep<T>) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
Object::Object(Proxy<T> data, std::string name)
|
|
Object::Object(Proxy<T> data, std::string name)
|
|
|
- : type_(typeid(T)), name_(std::move(name)), proxy_(true), const_(false),
|
|
|
|
|
|
|
+ : type_(typeid(T)), type_name_(Name<T>), name_(std::move(name)), proxy_(true), const_(false),
|
|
|
data_(std::make_shared<Proxy<T>>(std::move(data))),
|
|
data_(std::make_shared<Proxy<T>>(std::move(data))),
|
|
|
get_(&Object::getter<T>) {}
|
|
get_(&Object::getter<T>) {}
|
|
|
|
|
|