feat update

This commit is contained in:
tqcq 2024-03-06 08:55:49 +08:00
parent 19cdaa8e9b
commit cf664d8143
7 changed files with 214 additions and 1 deletions

View File

@ -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

View File

@ -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
View 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

View 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
View 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
View 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
View 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;
}