Skip to content

Commit

Permalink
string_view version of utf8_display_split to optimize mapgen with way…
Browse files Browse the repository at this point in the history
… fewer allocs
  • Loading branch information
akrieger committed Dec 24, 2023
1 parent d0c725e commit f40d35d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
26 changes: 18 additions & 8 deletions src/catacharset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,21 +415,31 @@ std::u32string utf8_to_utf32( const std::string_view str )
std::vector<std::string> utf8_display_split( const std::string &s )
{
std::vector<std::string> result;
std::string current_glyph;
std::vector<std::string_view> parts;
utf8_display_split_into( s, parts );
result.reserve( parts.size() );
for( std::string_view part : parts ) {
result.emplace_back( part );
}
return result;
}

void utf8_display_split_into( const std::string &s, std::vector<std::string_view> &result )
{
const char *pos = s.c_str();
const char *glyph_begin = pos;
const char *glyph_end = pos;
int len = s.length();
while( len > 0 ) {
const char *old_pos = pos;
const uint32_t ch = UTF8_getch( &pos, &len );
const int width = mk_wcwidth( ch );
if( width > 0 && !current_glyph.empty() ) {
result.push_back( current_glyph );
current_glyph.clear();
if( width > 0 && glyph_begin != glyph_end ) {
result.push_back( std::string_view( glyph_begin, std::distance( glyph_begin, glyph_end ) ) );
glyph_begin = glyph_end;
}
current_glyph += std::string( old_pos, pos );
glyph_end = pos;
}
result.push_back( current_glyph );
return result;
result.push_back( std::string_view( glyph_begin, std::distance( glyph_begin, glyph_end ) ) );
}

int center_text_pos( const char *text, int start_pos, int end_pos )
Expand Down
1 change: 1 addition & 0 deletions src/catacharset.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ std::u32string utf8_to_utf32( std::string_view str );
// Split the given string into displayed characters. Each element of the returned vector
// contains one 'regular' codepoint and all subsequent combining characters.
std::vector<std::string> utf8_display_split( const std::string & );
void utf8_display_split_into( const std::string &, std::vector<std::string_view> & );

/**
* UTF8-Wrapper over std::string.
Expand Down
10 changes: 5 additions & 5 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4491,10 +4491,10 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo )
}
for( int c = m_offset.y; c < expected_dim.y; c++ ) {
const std::string row = parray.get_string( c );
std::vector<map_key> row_keys;
for( const std::string &key : utf8_display_split( row ) ) {
row_keys.emplace_back( key );
}
static std::vector<std::string_view> row_keys;
row_keys.clear();
row_keys.reserve( total_size.x );
utf8_display_split_into( row, row_keys );
if( row_keys.size() < static_cast<size_t>( expected_dim.x ) ) {
parray.throw_error(
string_format( " format: row %d must have at least %d columns, not %d",
Expand All @@ -4507,7 +4507,7 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo )
}
for( int i = m_offset.x; i < expected_dim.x; i++ ) {
const point p = point( i, c ) - m_offset;
const map_key key = row_keys[i];
const map_key key{ std::string( row_keys[i] ) };
const auto iter_ter = keys_with_terrain.find( key );
const auto fpi = format_placings.find( key );

Expand Down

0 comments on commit f40d35d

Please sign in to comment.