Commit bcad2b28 authored by Dominik Charousset's avatar Dominik Charousset

fixed uniform name for user-defined templates using std::string

parent 82e6624a
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
namespace { namespace {
using namespace std;
using namespace cppa;
using namespace detail;
constexpr const char* mapped_int_names[][2] = { constexpr const char* mapped_int_names[][2] = {
{ nullptr, nullptr }, // sizeof 0-> invalid { nullptr, nullptr }, // sizeof 0-> invalid
{ "@i8", "@u8" }, // sizeof 1 -> signed / unsigned int8 { "@i8", "@u8" }, // sizeof 1 -> signed / unsigned int8
...@@ -65,13 +69,13 @@ constexpr const char* mapped_int_names[][2] = { ...@@ -65,13 +69,13 @@ constexpr const char* mapped_int_names[][2] = {
template<typename T> template<typename T>
constexpr size_t sign_index() { constexpr size_t sign_index() {
static_assert(std::numeric_limits<T>::is_integer, "T is not an integer"); static_assert(numeric_limits<T>::is_integer, "T is not an integer");
return std::numeric_limits<T>::is_signed ? 0 : 1; return numeric_limits<T>::is_signed ? 0 : 1;
} }
template<typename T> template<typename T>
inline std::string demangled() { inline string demangled() {
return cppa::detail::demangle(typeid(T).name()); return demangle(typeid(T));
} }
template<typename T> template<typename T>
...@@ -80,10 +84,10 @@ constexpr const char* mapped_int_name() { ...@@ -80,10 +84,10 @@ constexpr const char* mapped_int_name() {
} }
template<typename Iterator> template<typename Iterator>
std::string to_uniform_name_impl(Iterator begin, Iterator end, string to_uniform_name_impl(Iterator begin, Iterator end,
bool first_run = false) { bool first_run = false) {
// all integer type names as uniform representation // all integer type names as uniform representation
static std::map<std::string, std::string> mapped_demangled_names = { static map<string, string> mapped_demangled_names = {
// integer types // integer types
{ demangled<char>(), mapped_int_name<char>() }, { demangled<char>(), mapped_int_name<char>() },
{ demangled<signed char>(), mapped_int_name<signed char>() }, { demangled<signed char>(), mapped_int_name<signed char>() },
...@@ -109,23 +113,23 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -109,23 +113,23 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
{ demangled<char16_t>(), mapped_int_name<char16_t>() }, { demangled<char16_t>(), mapped_int_name<char16_t>() },
{ demangled<char32_t>(), mapped_int_name<char32_t>() }, { demangled<char32_t>(), mapped_int_name<char32_t>() },
// string types // string types
{ demangled<std::string>(), "@str" }, { demangled<string>(), "@str" },
{ demangled<std::u16string>(), "@u16str" }, { demangled<u16string>(), "@u16str" },
{ demangled<std::u32string>(), "@u32str" }, { demangled<u32string>(), "@u32str" },
// cppa types // cppa types
{ demangled<cppa::atom_value>(), "@atom" }, { demangled<atom_value>(), "@atom" },
{ demangled<cppa::util::void_type>(), "@0" }, { demangled<util::void_type>(), "@0" },
{ demangled<cppa::any_tuple>(), "@<>" }, { demangled<any_tuple>(), "@<>" },
{ demangled<cppa::actor_ptr>(), "@actor" }, { demangled<actor_ptr>(), "@actor" },
{ demangled<cppa::group_ptr>(), "@group" }, { demangled<group_ptr>(), "@group" },
{ demangled<cppa::channel_ptr>(), "@channel" }, { demangled<channel_ptr>(), "@channel" },
{ demangled<cppa::detail::addressed_message>(), "@msg" }, { demangled<addressed_message>(), "@msg" },
{ demangled< cppa::intrusive_ptr<cppa::process_information> >(), "@process_info" } { demangled< intrusive_ptr<process_information> >(), "@process_info" }
}; };
// check if we could find the whole string in our lookup map // check if we could find the whole string in our lookup map
if (first_run) { if (first_run) {
std::string tmp(begin, end); string tmp(begin, end);
auto i = mapped_demangled_names.find(tmp); auto i = mapped_demangled_names.find(tmp);
if (i != mapped_demangled_names.end()) { if (i != mapped_demangled_names.end()) {
return i->second; return i->second;
...@@ -135,10 +139,10 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -135,10 +139,10 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
// does [begin, end) represents an empty string? // does [begin, end) represents an empty string?
if (begin == end) return ""; if (begin == end) return "";
// derived reverse_iterator type // derived reverse_iterator type
typedef std::reverse_iterator<Iterator> reverse_iterator; typedef reverse_iterator<Iterator> reverse_iterator;
// a subsequence [begin', end') within [begin, end) // a subsequence [begin', end') within [begin, end)
typedef std::pair<Iterator, Iterator> subseq; typedef pair<Iterator, Iterator> subseq;
std::vector<subseq> substrings; vector<subseq> substrings;
// explode string if we got a list of types // explode string if we got a list of types
int open_brackets = 0; // counts "open" '<' int open_brackets = 0; // counts "open" '<'
// denotes the begin of a possible subsequence // denotes the begin of a possible subsequence
...@@ -153,14 +157,14 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -153,14 +157,14 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
case '>': case '>':
if (--open_brackets < 0) { if (--open_brackets < 0) {
throw std::runtime_error("malformed string"); throw runtime_error("malformed string");
} }
++i; ++i;
break; break;
case ',': case ',':
if (open_brackets == 0) { if (open_brackets == 0) {
substrings.push_back(std::make_pair(anchor, i)); substrings.push_back(make_pair(anchor, i));
++i; ++i;
anchor = i; anchor = i;
} }
...@@ -177,8 +181,8 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -177,8 +181,8 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
} }
// call recursively for each list argument // call recursively for each list argument
if (!substrings.empty()) { if (!substrings.empty()) {
std::string result; string result;
substrings.push_back(std::make_pair(anchor, end)); substrings.push_back(make_pair(anchor, end));
for (const subseq& sstr : substrings) { for (const subseq& sstr : substrings) {
if (!result.empty()) result += ","; if (!result.empty()) result += ",";
result += to_uniform_name_impl(sstr.first, sstr.second); result += to_uniform_name_impl(sstr.first, sstr.second);
...@@ -188,17 +192,17 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -188,17 +192,17 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
// we didn't got a list, compute unify name // we didn't got a list, compute unify name
else { else {
// is [begin, end) a template? // is [begin, end) a template?
Iterator substr_begin = std::find(begin, end, '<'); Iterator substr_begin = find(begin, end, '<');
if (substr_begin == end) { if (substr_begin == end) {
// not a template, return mapping // not a template, return mapping
std::string arg(begin, end); string arg(begin, end);
auto mapped = mapped_demangled_names.find(arg); auto mapped = mapped_demangled_names.find(arg);
return (mapped == mapped_demangled_names.end()) ? arg : mapped->second; return (mapped == mapped_demangled_names.end()) ? arg : mapped->second;
} }
// skip leading '<' // skip leading '<'
++substr_begin; ++substr_begin;
// find trailing '>' // find trailing '>'
Iterator substr_end = std::find(reverse_iterator(end), Iterator substr_end = find(reverse_iterator(end),
reverse_iterator(substr_begin), reverse_iterator(substr_begin),
'>') '>')
// get as an Iterator // get as an Iterator
...@@ -206,9 +210,9 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -206,9 +210,9 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
// skip trailing '>' // skip trailing '>'
--substr_end; --substr_end;
if (substr_end == substr_begin) { if (substr_end == substr_begin) {
throw std::runtime_error("substr_end == substr_begin"); throw runtime_error("substr_end == substr_begin");
} }
std::string result; string result;
// template name (part before leading '<') // template name (part before leading '<')
result.append(begin, substr_begin); result.append(begin, substr_begin);
// get mappings of all template parameter(s) // get mappings of all template parameter(s)
...@@ -218,24 +222,32 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -218,24 +222,32 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
} }
} }
template<size_t RawSize>
void replace_all(string& str, const char (&before)[RawSize], const char* after) {
// always skip the last element in `before`, because the last element
// is the null-terminator
auto i = search(begin(str), end(str), begin(before), end(before) - 1);
while (i != end(str)) {
str.replace(i, i + RawSize - 1, after);
i = search(begin(str), end(str), begin(before), end(before) - 1);
}
}
const char s_rawstr[] =
"std::basic_string<@i8,std::char_traits<@i8>,std::allocator<@i8>";
const char s_str[] = "@str";
const char s_rawan[] = "(anonymous namespace)";
const char s_an[] = "@_";
} // namespace <anonymous> } // namespace <anonymous>
namespace cppa { namespace detail { namespace cppa { namespace detail {
std::string to_uniform_name(const std::string& dname) { std::string to_uniform_name(const std::string& dname) {
static std::string an = "(anonymous namespace)";
static std::string an_replacement = "@_";
auto r = to_uniform_name_impl(dname.begin(), dname.end(), true); auto r = to_uniform_name_impl(dname.begin(), dname.end(), true);
// replace all occurrences of an with "@_" replace_all(r, s_rawstr, s_str);
if (r.size() > an.size()) { replace_all(r, s_rawan, s_an);
auto i = std::search(r.begin(), r.end(), an.begin(), an.end());
while (i != r.end()) {
auto substr_end = i + an.size();
r.replace(i, substr_end, an_replacement);
// next iteration
i = std::search(r.begin(), r.end(), an.begin(), an.end());
}
}
return r; return r;
} }
...@@ -243,4 +255,4 @@ std::string to_uniform_name(const std::type_info& tinfo) { ...@@ -243,4 +255,4 @@ std::string to_uniform_name(const std::type_info& tinfo) {
return to_uniform_name(demangle(tinfo.name())); return to_uniform_name(demangle(tinfo.name()));
} }
} } // namespace cppa::detail } } // namespace detail
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment