feat update
This commit is contained in:
parent
19cdaa8e9b
commit
cf664d8143
@ -37,7 +37,7 @@ BreakBeforeTernaryOperators: true
|
|||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: BeforeColon
|
||||||
ColumnLimit: 100
|
ColumnLimit: 120
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
@ -40,6 +40,10 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_executable(test test/main.cc)
|
||||||
|
target_include_directories(test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_link_libraries(test PRIVATE sled)
|
||||||
|
|
||||||
target_include_directories(meta PRIVATE
|
target_include_directories(meta PRIVATE
|
||||||
${CLANG_INCLUDE_DIR}
|
${CLANG_INCLUDE_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
12
runtime/meta_object.h
Normal file
12
runtime/meta_object.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef META_RUNTIME_META_OBJECT_H
|
||||||
|
#define META_RUNTIME_META_OBJECT_H
|
||||||
|
|
||||||
|
namespace meta {
|
||||||
|
|
||||||
|
class MetaObject {
|
||||||
|
public:
|
||||||
|
virtual ~MetaObject() = default;
|
||||||
|
};
|
||||||
|
}// namespace meta
|
||||||
|
#endif// META_RUNTIME_META_OBJECT_H
|
38
runtime/meta_object_register.h
Normal file
38
runtime/meta_object_register.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef META_RUNTIME_META_OBJECT_REGISTER_H
|
||||||
|
#define META_RUNTIME_META_OBJECT_REGISTER_H
|
||||||
|
#include "meta_registry.h"
|
||||||
|
#include "meta_utils.h"
|
||||||
|
|
||||||
|
namespace meta {
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
class MetaObjectRegister {
|
||||||
|
public:
|
||||||
|
MetaObjectRegister() { register_.DoNothing(); }
|
||||||
|
|
||||||
|
virtual ~MetaObjectRegister() = default;
|
||||||
|
|
||||||
|
static T *CreateMetaObject(Args &&...args)
|
||||||
|
{
|
||||||
|
T *ptr = nullptr;
|
||||||
|
try {
|
||||||
|
ptr = new T(std::forward<Args>(args)...);
|
||||||
|
} catch (const std::bad_alloc &) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Register {
|
||||||
|
Register() { MetaRegistry<Args...>::Register(GetMetaName<T>(), CreateMetaObject); }
|
||||||
|
|
||||||
|
~Register() { MetaRegistry<Args...>::Unregister(GetMetaName<T>()); }
|
||||||
|
|
||||||
|
void DoNothing();
|
||||||
|
};
|
||||||
|
|
||||||
|
static Register register_;
|
||||||
|
};
|
||||||
|
}// namespace meta
|
||||||
|
#endif// META_RUNTIME_META_OBJECT_REGISTER_H
|
70
runtime/meta_registry.h
Normal file
70
runtime/meta_registry.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef META_RUNTIME_META_REGISTRY_H
|
||||||
|
#define META_RUNTIME_META_REGISTRY_H
|
||||||
|
|
||||||
|
#include "meta_object.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace meta {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry
|
||||||
|
**/
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
class MetaRegistry {
|
||||||
|
public:
|
||||||
|
static MetaRegistry *Instance();
|
||||||
|
static bool Register(const std::string &obj_name,
|
||||||
|
std::function<MetaObject *(Args &&...)> creator);
|
||||||
|
static bool Unregister(const std::string &obj_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool RegisterImpl(const std::string &obj_name, std::function<MetaObject *(Args &&...)> creator);
|
||||||
|
bool UnregisterImpl(const std::string &obj_name);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::function<MetaObject *(Args &&...)>> creators_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
MetaRegistry<Args...> *
|
||||||
|
MetaRegistry<Args...>::Instance()
|
||||||
|
{
|
||||||
|
static MetaRegistry<Args...> instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool
|
||||||
|
MetaRegistry<Args...>::Register(const std::string &obj_name,
|
||||||
|
std::function<MetaObject *(Args &&...)> creator)
|
||||||
|
{
|
||||||
|
return Instance()->RegisterImpl(obj_name, creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool
|
||||||
|
MetaRegistry<Args...>::Unregister(const std::string &obj_name)
|
||||||
|
{
|
||||||
|
return Instance()->UnregisterImpl(obj_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool
|
||||||
|
MetaRegistry<Args...>::RegisterImpl(const std::string &obj_name,
|
||||||
|
std::function<MetaObject *(Args &&...)> creator)
|
||||||
|
{
|
||||||
|
return creators_.insert({obj_name, creator}).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
bool
|
||||||
|
MetaRegistry<Args...>::UnregisterImpl(const std::string &obj_name)
|
||||||
|
{
|
||||||
|
return creators_.erase(obj_name) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace meta
|
||||||
|
|
||||||
|
#endif// META_RUNTIME_META_REGISTRY_H
|
68
runtime/meta_utils.h
Normal file
68
runtime/meta_utils.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef META_RUNTIME_META_UTILS_H
|
||||||
|
#define META_RUNTIME_META_UTILS_H
|
||||||
|
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace meta {
|
||||||
|
namespace {
|
||||||
|
template<typename T>
|
||||||
|
inline std::string
|
||||||
|
GetDemangleName()
|
||||||
|
{
|
||||||
|
const std::string name = typeid(T).name();
|
||||||
|
std::string pretty_name = name;
|
||||||
|
int status = -4;
|
||||||
|
char *res = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
|
||||||
|
if (status == 0) { pretty_name = std::string(res); }
|
||||||
|
free(res);
|
||||||
|
return pretty_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string
|
||||||
|
RemoveWhiteSpace(const std::string &name, const std::string &chars = "[]<>,&* ")
|
||||||
|
{
|
||||||
|
// trim left and right
|
||||||
|
std::string compact_name = name.substr(name.find_first_not_of(' '));
|
||||||
|
compact_name = compact_name.substr(0, compact_name.find_last_not_of(' ') + 1);
|
||||||
|
|
||||||
|
// remove white space
|
||||||
|
for (int i = 0; i < compact_name.size(); ++i) {
|
||||||
|
if (compact_name[i] == ' ') {
|
||||||
|
if (i > 0 && chars.find(compact_name[i - 1]) != std::string::npos) {
|
||||||
|
compact_name.erase(i, 1);
|
||||||
|
} else if (i + 1 < compact_name.size()
|
||||||
|
&& chars.find(compact_name[i + 1]) != std::string::npos) {
|
||||||
|
compact_name.erase(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compact_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string
|
||||||
|
RemoveInnerNamespace(const std::string &name)
|
||||||
|
{
|
||||||
|
std::string new_name = name;
|
||||||
|
auto iter = name.find("::__1");
|
||||||
|
while (iter != std::string::npos) {
|
||||||
|
new_name.replace(iter, 5, "");
|
||||||
|
iter = new_name.find("::__1");
|
||||||
|
}
|
||||||
|
return new_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::string
|
||||||
|
GetMetaName()
|
||||||
|
{
|
||||||
|
static std::string name = RemoveInnerNamespace(RemoveWhiteSpace(GetDemangleName<T>()));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace meta
|
||||||
|
|
||||||
|
#endif// META_RUNTIME_META_UTILS_H
|
21
test/main.cc
Normal file
21
test/main.cc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "runtime/meta_object_register.h"
|
||||||
|
#include "runtime/meta_utils.h"
|
||||||
|
#include <sled/log/log.h>
|
||||||
|
|
||||||
|
class Object : public meta::MetaObject {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjectRegister : public meta::MetaObjectRegister<Object> {};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ObjectRegister register;
|
||||||
|
LOGV("", "{}", meta::GetMetaName<Object>());
|
||||||
|
LOGV("", "{}", meta::GetMetaName<meta::MetaObject>());
|
||||||
|
LOGV("", "{}", meta::GetMetaName<std::vector<int>>());
|
||||||
|
LOGV("", "{}", meta::GetMetaName<std::unordered_map<void **, const long &>>());
|
||||||
|
LOGV("", "{}", meta::GetMetaName<std::unordered_map<void **, const std::string &>>());
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user