feat update
This commit is contained in:
parent
19cdaa8e9b
commit
cf664d8143
@ -37,7 +37,7 @@ BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 100
|
||||
ColumnLimit: 120
|
||||
CompactNamespaces: false
|
||||
ContinuationIndentWidth: 4
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
|
@ -40,6 +40,10 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
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
|
||||
${CLANG_INCLUDE_DIR}
|
||||
${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