mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 19:41:29 +07:00
212 lines
8.7 KiB
C++
212 lines
8.7 KiB
C++
/*******************************************************************************
|
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
|
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
|
******************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include "meta_fwd.hpp"
|
|
#include "meta_infos.hpp"
|
|
|
|
#include "meta_registry/base_.hpp"
|
|
#include "meta_registry/class_.hpp"
|
|
#include "meta_registry/ctor_.hpp"
|
|
#include "meta_registry/data_.hpp"
|
|
#include "meta_registry/enum_.hpp"
|
|
#include "meta_registry/evalue_.hpp"
|
|
#include "meta_registry/function_.hpp"
|
|
#include "meta_registry/member_.hpp"
|
|
#include "meta_registry/method_.hpp"
|
|
#include "meta_registry/namespace_.hpp"
|
|
|
|
namespace meta_hpp
|
|
{
|
|
class registry final {
|
|
public:
|
|
registry() = default;
|
|
|
|
class_info get_class_by_path(std::string_view path) const noexcept;
|
|
data_info get_data_by_path(std::string_view path) const noexcept;
|
|
enum_info get_enum_by_path(std::string_view path) const noexcept;
|
|
evalue_info get_evalue_by_path(std::string_view path) const noexcept;
|
|
function_info get_function_by_path(std::string_view path) const noexcept;
|
|
member_info get_member_by_path(std::string_view path) const noexcept;
|
|
method_info get_method_by_path(std::string_view path) const noexcept;
|
|
namespace_info get_namespace_by_path(std::string_view path) const noexcept;
|
|
public:
|
|
template < typename... Internals >
|
|
registry& operator()(Internals&&... internals);
|
|
private:
|
|
template < typename Class >
|
|
void add_(const std::string& prefix, const class_<Class>& internal);
|
|
void add_(const std::string& prefix, const data_& internal);
|
|
template < typename Enum >
|
|
void add_(const std::string& prefix, const enum_<Enum>& internal);
|
|
template < typename Function >
|
|
void add_(const std::string& prefix, const function_<Function>& internal);
|
|
void add_(const std::string& prefix, const namespace_& internal);
|
|
void add_(const std::string& prefix, ...) = delete;
|
|
private:
|
|
struct add_info_f;
|
|
void add_info_(const std::string& prefix, const base_info& info);
|
|
void add_info_(const std::string& prefix, const class_info& info);
|
|
void add_info_(const std::string& prefix, const ctor_info& info);
|
|
void add_info_(const std::string& prefix, const data_info& info);
|
|
void add_info_(const std::string& prefix, const enum_info& info);
|
|
void add_info_(const std::string& prefix, const evalue_info& info);
|
|
void add_info_(const std::string& prefix, const function_info& info);
|
|
void add_info_(const std::string& prefix, const member_info& info);
|
|
void add_info_(const std::string& prefix, const method_info& info);
|
|
void add_info_(const std::string& prefix, const namespace_info& info);
|
|
void add_info_(const std::string& prefix, ...) = delete;
|
|
private:
|
|
class_info_map classes_;
|
|
data_info_map datas_;
|
|
enum_info_map enums_;
|
|
evalue_info_map evalues_;
|
|
function_info_map functions_;
|
|
member_info_map members_;
|
|
method_info_map methods_;
|
|
namespace_info_map namespaces_;
|
|
};
|
|
}
|
|
|
|
namespace meta_hpp
|
|
{
|
|
inline class_info registry::get_class_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(classes_, path);
|
|
}
|
|
|
|
inline data_info registry::get_data_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(datas_, path);
|
|
}
|
|
|
|
inline enum_info registry::get_enum_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(enums_, path);
|
|
}
|
|
|
|
inline evalue_info registry::get_evalue_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(evalues_, path);
|
|
}
|
|
|
|
inline function_info registry::get_function_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(functions_, path);
|
|
}
|
|
|
|
inline member_info registry::get_member_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(members_, path);
|
|
}
|
|
|
|
inline method_info registry::get_method_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(methods_, path);
|
|
}
|
|
|
|
inline namespace_info registry::get_namespace_by_path(std::string_view path) const noexcept {
|
|
return detail::find_or_default(namespaces_, path);
|
|
}
|
|
}
|
|
|
|
namespace meta_hpp
|
|
{
|
|
template < typename... Internals >
|
|
inline registry& registry::operator()(Internals&&... internals) {
|
|
(add_(std::string{}, std::forward<Internals>(internals)), ...);
|
|
return *this;
|
|
}
|
|
}
|
|
|
|
namespace meta_hpp
|
|
{
|
|
template < typename Class >
|
|
inline void registry::add_(const std::string& prefix, const class_<Class>& internal) {
|
|
add_info_(prefix, internal.make_info());
|
|
}
|
|
|
|
inline void registry::add_(const std::string& prefix, const data_& internal) {
|
|
add_info_(prefix, internal.make_info());
|
|
}
|
|
|
|
template < typename Enum >
|
|
inline void registry::add_(const std::string& prefix, const enum_<Enum>& internal) {
|
|
add_info_(prefix, internal.make_info());
|
|
}
|
|
|
|
template < typename Function >
|
|
inline void registry::add_(const std::string& prefix, const function_<Function>& internal) {
|
|
add_info_(prefix, internal.make_info());
|
|
}
|
|
|
|
inline void registry::add_(const std::string& prefix, const namespace_& internal) {
|
|
add_info_(prefix, internal.make_info());
|
|
}
|
|
}
|
|
|
|
namespace meta_hpp
|
|
{
|
|
struct registry::add_info_f final {
|
|
template < typename Info >
|
|
void operator()(registry& self, const std::string& prefix, Info&& info) const {
|
|
self.add_info_(prefix, std::forward<Info>(info));
|
|
}
|
|
};
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const base_info& info) {
|
|
(void)prefix;
|
|
(void)info;
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const class_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(classes_, name, info, &class_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const ctor_info& info) {
|
|
(void)prefix;
|
|
(void)info;
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const data_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(datas_, name, info, &data_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const enum_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(enums_, name, info, &enum_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const evalue_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(evalues_, name, info, &evalue_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const function_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(functions_, name, info, &function_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const member_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(members_, name, info, &member_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const method_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(methods_, name, info, &method_info::merge);
|
|
}
|
|
|
|
inline void registry::add_info_(const std::string& prefix, const namespace_info& info) {
|
|
std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name();
|
|
info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name));
|
|
detail::merge_with(namespaces_, name, info, &namespace_info::merge);
|
|
}
|
|
}
|