Skip to content

Commit

Permalink
Instead of replacing :: with nothing, keep them and use Unicode uA789…
Browse files Browse the repository at this point in the history
… (Modified Letter raised colon)
  • Loading branch information
cfis committed Jan 29, 2025
1 parent f48035c commit b7525f3
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
6 changes: 5 additions & 1 deletion doc/stl/stl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,15 @@ Rice can also automatically generate Ruby classes. These Ruby classes are added

Sometimes Ruby also needs to create new instances of these classes. With manually defined class names, this is easy to do. With generated class names you need to understand how Rice creates class names.

Starting in version 4.5, Rice makes use of three unicode characters to create class names that "look" like their C++ counterparts. For example, the type ``std::pair<std::string, double>`` becomes ``Rice::Std::Pair≺string≺char≻‚ double≻``. The characters are:
Starting in version 4.5, Rice makes use of three unicode characters to create class names that "look" like their C++ counterparts. For example, the type ``std::pair<std::string, double>`` becomes ``Rice::Std::Pair≺string≺char≻‚ double≻``. Or assume there is a vector containing a custom class``MyNamespace::MyClass``. Then generated name would be ``Rice::Std::Vector≺MyNamesapce꞉꞉MyClass≻``.

The unicode characters are:

+---------------------------++----------------------------+
| Character | Code Point | Name |
+=============+=============+=============================+
| : | U+A789 | Modified Letter Colon |
+-------------+-------------+-----------------------------+
|| U+227A | Precedes |
+-------------+-------------+-----------------------------+
|| U+227B | Succeeds |
Expand Down
10 changes: 7 additions & 3 deletions rice/detail/Type.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,16 @@ namespace Rice::detail
// Capitalize first letter
base[0] = std::toupper(base[0]);

// Replace :: or _ and capitalize the next letter
std::regex namespaceRegex(R"((_|::)(\w))");
// Replace :: with unicode U+u02F8 (Modified Letter raised colon)
auto colonRegex = std::regex(R"(:)");
replaceAll(base, colonRegex, "\uA789");

// Replace _ and capitalize the next letter
std::regex namespaceRegex(R"(_(\w))");
std::smatch namespaceMatch;
while (std::regex_search(base, namespaceMatch, namespaceRegex))
{
std::string replacement = namespaceMatch[2];
std::string replacement = namespaceMatch[1];
std::transform(replacement.begin(), replacement.end(), replacement.begin(), ::toupper);
base.replace(namespaceMatch.position(), namespaceMatch.length(), replacement);
}
Expand Down
10 changes: 10 additions & 0 deletions test/test_Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ namespace Outer
using Vec2 = std::vector<unsigned char*>;
using Map1 = std::map<std::string, std::vector<std::complex<float>>>;
using UnorderedMap1 = std::unordered_map<std::string, std::complex<float>>;

class SomeClass
{
};

using Vec3 = std::vector<SomeClass>;
}
}

Expand Down Expand Up @@ -60,6 +66,10 @@ TESTCASE(MakeClassName)
className = detail::makeClassName(typeName);
ASSERT_EQUAL(u8"Vector≺unsigned char*≻", className.c_str());

typeName = detail::typeName(typeid(Outer::Inner::Vec3));
className = detail::makeClassName(typeName);
ASSERT_EQUAL(u8"Vector≺Outer꞉꞉Inner꞉꞉SomeClass≻", className.c_str());

typeName = detail::typeName(typeid(Outer::Inner::Map1));
className = detail::makeClassName(typeName);
ASSERT_EQUAL(u8"Map≺string≺char≻‚ vector≺complex≺float≻≻≻", className.c_str());
Expand Down

0 comments on commit b7525f3

Please sign in to comment.