24#include "AstUtil/RTTIAPI.hpp"
25#include "AstUtil/ValueView.hpp"
26#include "AstUtil/Span.hpp"
27#include "AstUtil/ParseFormat.hpp"
29#include <unordered_map>
49constexpr int find_closing(
const char* s,
int p) {
50 return s[p] ==
'>' ? p : find_closing(s, p + 1);
55constexpr bool is_type(
const char* s,
int p,
const char* type) {
57 while (type[i] !=
'\0') {
58 if (s[p + i] != type[i])
return false;
62 return s[p + i] ==
'>' ||
s[p + i] ==
':';
66constexpr bool is_type_impl(
const char* s,
int p,
const char* type,
int i) {
67 return type[i] ==
'\0'
68 ? (
s[p + i] ==
'>' ||
s[p + i] ==
':')
69 : (
s[p + i] == type[i] && is_type_impl(
s, p, type, i + 1));
73constexpr bool is_type(
const char* s,
int p,
const char* type) {
74 return is_type_impl(s, p, type, 0);
79constexpr int count_args(
const char* s,
int p = 0) {
80 return s[p] ==
'\0' ? 0 :
81 s[p] ==
'<' ? 1 + count_args(s, p + 1) :
96constexpr uint64_t get_parameter_tag(
const char* s,
int p = 0) {
97 return s[p] ==
'\0' ? 0 :
99 is_type(s, p+1,
"bool") ? get_parameter_tag(s, find_closing(s, p)+1) * num_types + type_bool :
100 is_type(s, p+1,
"int") ? get_parameter_tag(s, find_closing(s, p)+1) * num_types + type_int :
101 is_type(s, p+1,
"double") ? get_parameter_tag(s, find_closing(s, p)+1) * num_types + type_double :
102 is_type(s, p+1,
"string") ? get_parameter_tag(s, find_closing(s, p)+1) * num_types + type_string :
103 is_type(s, p+1,
"object") ? get_parameter_tag(s, find_closing(s, p)+1) * num_types + type_object :
104 throw "invalid parameter type"
106 get_parameter_tag(
s, p + 1);
109template <
int Pos,
typename T>
111 static constexpr int pos = Pos;
117template <
int TypeCode>
128template <u
int64_t Tag,
int Pos>
134template <u
int64_t Tag,
int Pos,
int Count>
136 using type =
decltype(
139 typename decode_impl<Tag / num_types, Pos + 1, Count - 1>::type()
144template <u
int64_t Tag,
int Pos>
146 using type = std::tuple<>;
152template <u
int64_t Tag,
int N>
153using decode_tag =
typename decode_impl<Tag, 0, N>::type;
156inline std::vector<StringView> split(
StringView str)
158 std::vector<StringView> result;
159 const char* p = str.data();
160 const char* end = p + str.size();
164 while (p < end && std::isspace(
static_cast<unsigned char>(*p))) {
171 const char* start = p;
172 while (p < end && *p !=
'"') {
176 result.emplace_back(start,
static_cast<std::size_t
>(p - start));
179 const char* start = p;
180 while (p < end && !std::isspace(
static_cast<unsigned char>(*p)) && *p !=
'"') {
183 result.emplace_back(start,
static_cast<std::size_t
>(p - start));
189inline std::string extract_command_name(
const char* tmpl) {
191 while (*tmpl && *tmpl !=
' ' && *tmpl !=
'<') {
201T convert_token(StringView s);
204inline bool convert_token<bool>(StringView s) {
207 throw std::runtime_error(std::string(
"invalid bool value: ") + std::string(s));
212inline int convert_token<int>(StringView s) {
215 throw std::runtime_error(std::string(
"invalid int value: ") + std::string(s));
221inline double convert_token<double>(StringView s) {
224 throw std::runtime_error(std::string(
"invalid double value: ") + std::string(s));
229inline Object* convert_token<Object*>(StringView s) {
235inline StringView convert_token<StringView>(StringView s) {
241inline errc_t fill_result(CommandResult& ) {
247typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, errc_t>::type
248fill_result(CommandResult& , T ret) {
249 return static_cast<errc_t
>(ret);
253inline errc_t fill_result(CommandResult& result, std::vector<std::string> vec) {
254 result = std::move(vec);
259inline errc_t fill_result(CommandResult& result,
const std::string& str) {
260 result.push_back(str);
263inline errc_t fill_result(CommandResult& result, std::string&& str) {
264 result.push_back(std::move(str));
268inline errc_t fill_result(CommandResult& result,
const char* str) {
269 result.push_back(str);
273typename std::enable_if<!std::is_integral<T>::value &&
274 !std::is_same<T, std::vector<std::string>>::value &&
275 !std::is_same<T, std::string>::value &&
276 !std::is_same<T, const char*>::value, errc_t>::type
277fill_result(CommandResult& , T ret) {
278 return static_cast<errc_t
>(ret);
对象基类,继承自该类的对象可以使用运行时类型信息相关功能,实现强弱引用计数、运行时元信息(属性访问、序列化等)等基础功能
定义 Object.hpp:86
Object * aResolveObject(StringView value, Class *cls)
解析对象
定义 RTTIAPI.cpp:94