#ifndef OBJECT_PROXY_HPP #define OBJECT_PROXY_HPP #include "matador/object/primary_key_resolver.hpp" #include namespace matador::object { class basic_object_proxy { public: virtual ~basic_object_proxy() = default; [[nodiscard]] virtual void *get() const = 0; }; template < typename Type > class object_proxy; template < typename Type > class object_resolver { public: virtual ~object_resolver() = default; virtual Type* resolve(const object_proxy &proxy) const = 0; }; template < typename Type > class static_object_resolver final : public object_resolver { public: static_object_resolver() = default; explicit static_object_resolver(Type* obj) : obj_(obj) {} explicit static_object_resolver(std::unique_ptr obj) : obj_(std::move(obj)) {} Type* resolve(const object_proxy &/*proxy*/) const override { return obj_.get(); } private: std::unique_ptr obj_{}; }; template class object_proxy final : public basic_object_proxy { public: object_proxy() = default; explicit object_proxy(Type* obj) : resolver_(std::make_unique>(obj)) , pk_(primary_key_resolver::resolve_object(*obj).pk) {} [[nodiscard]] void *get() const override { return static_cast(pointer()); } Type* operator->() const { return pointer(); } Type& operator*() { return *pointer(); } const Type& operator*() const { return *pointer(); } Type* pointer() const { return resolve(); } Type& ref() { return *pointer(); } const Type& ref() const { return *pointer(); } void reset(Type* obj) { pk_ = primary_key_resolver::resolve_object(*obj).pk; resolver_ = std::make_unique>(obj); } void reset(std::unique_ptr obj) { pk_ = primary_key_resolver::resolve_object(*obj).pk; resolver_ = std::make_unique>(std::move(obj)); } void reset(std::unique_ptr> &&resolver) { resolver_ = std::move(resolver); } [[nodiscard]] bool empty() const { return resolver_ == nullptr; } [[nodiscard]] bool valid() const { return !empty(); } [[nodiscard]] bool has_primary_key() const { return !pk_.is_null(); } [[nodiscard]] const utils::identifier& primary_key() const { return pk_; } void primary_key(const utils::identifier &pk) { pk_ = pk; } private: Type* resolve() const { return resolver_->resolve(*this); } private: std::unique_ptr> resolver_{std::make_unique>()}; utils::identifier pk_{}; }; } #endif //OBJECT_PROXY_HPP