Skip to content

Commit

Permalink
Added string utility functions to trim, filter and convert.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulhoux committed Dec 29, 2023
1 parent e10faeb commit 1ba8a56
Show file tree
Hide file tree
Showing 2 changed files with 281 additions and 5 deletions.
80 changes: 79 additions & 1 deletion include/cinder/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,86 @@ CI_API bool asciiCaseEqual( const char *a, const char *b );
//! returns equivalent of strcmp() using ASCII case-insensitive comparison
CI_API int asciiCaseCmp( const char *a, const char *b );

//! removes all whitespace (as defined by std::isspace()) from the beginning of \a str. Unicode aware.
CI_API void trimLeftInPlace( std::string &str );
//! removes all whitespace (as defined by std::isspace()) from the beginning of \a str and returns a copy. Unicode aware.
CI_API std::string trimLeft( std::string str );

//! removes all whitespace (as defined by std::isspace()) from the end of \a str. Unicode aware.
CI_API void trimRightInPlace( std::string &str );
//! removes all whitespace (as defined by std::isspace()) from the end of \a str and returns a copy. Unicode aware.
CI_API std::string trimRight( std::string str );

//! removes all whitespace (as defined by std::isspace()) removed from beginning and end of \a str. Unicode aware.
CI_API void trimInPlace( std::string &str );
//! returns a copy of \a str with all whitespace (as defined by std::isspace()) removed from beginning and end. Unicode aware.
CI_API std::string trim( const std::string &str );
CI_API std::string trim( std::string str );

//! removes all specified \a characters from the beginning of \a str. Not Unicode-aware.
CI_API void trimLeftInPlace( std::string &str, const std::string &characters );
//! removes all specified \a characters from the beginning of \a str. Not Unicode-aware.
CI_API std::string trimLeft( std::string str, const std::string &characters );

//! removes all specified \a characters from the end of \a str. Not Unicode-aware.
CI_API void trimRightInPlace( std::string &str, const std::string &characters );
//! removes all specified \a characters from the end of \a str. Not Unicode-aware.
CI_API std::string trimRight( std::string str, const std::string &characters );

//! filters all occurrences of any of \a chars in \a str.
CI_API void filterInPlace( std::string &str, const std::string &chars );
//! returns a copy of \a str with all occurrences of any of \a chars filtered out.
CI_API std::string filter( std::string str, const std::string &chars );

//! Converts the character \a c to lowercase. Not Unicode-aware.
CI_API char charToLower( const char c );
//! Converts the character \a c to uppercase. Not Unicode-aware.
CI_API char charToUpper( const char c );

//! returns a copy of \a str with all characters converted to lowercase (using std::tolower()). Not Unicode-aware.
CI_API std::string toLower( std::string str );
//! returns a copy of \a str with all characters converted to lowercase (using std::tolower()). Not Unicode-aware.
CI_API std::string toLower( std::string str, const std::locale &loc );
//! returns a copy of \a str with all characters converted to uppercase (using std::toupper()). Not Unicode-aware.
CI_API std::string toUpper( std::string str );
//! returns a copy of \a str with all characters converted to uppercase (using std::toupper()). Not Unicode-aware.
CI_API std::string toUpper( std::string str, const std::locale &loc );

//! replaces all instances of \a find with \a replace in \a str.
CI_API void findReplaceInPlace( const std::string &find, const std::string &replace, std::string &str );
//! replaces all instances of \a find with \a replace in \a str and returns a copy.
CI_API std::string findReplace( const std::string &find, const std::string &replace, std::string str );

//! returns whether character \a c is considered white space.
CI_API bool isWhiteSpace( char c );
//! returns whether character \a c is a digit (0-9).
CI_API bool isDigit( char c );
//! returns whether character \a c is a hexadecimal digit (0-9)+(a-f).
CI_API bool isHexDigit( char c );
//! returns whether character \a c is alphabetic (a-z).
CI_API bool isAlpha( char c );
//! returns whether character \a c is numeric (0-9)+(.+-eE).
CI_API bool isNumeric( char c );

//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( int value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( unsigned value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( long value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( unsigned long value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( long long value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( unsigned long long value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( float value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( float value, int precision );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( double value );
//! converts the value to a string without leading and trailing zeroes.
CI_API std::string valueToString( double value, int precision );

//! Returns a stack trace (aka backtrace) where \c stackTrace()[0] == caller, \c stackTrace()[1] == caller's parent, etc
CI_API std::vector<std::string> stackTrace();
Expand Down
206 changes: 202 additions & 4 deletions src/cinder/Utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,209 @@ int asciiCaseCmp( const char *a, const char *b )
return ((int)std::toupper(*a)) - ((int)std::toupper(*b));
}

std::string trim( const std::string &str )
void trimLeftInPlace( std::string &str )
{
size_t wsFront = str.find_first_not_of( " \f\n\r\t\v" );
size_t wsBack = str.find_last_not_of( " \f\n\r\t\v" );
return wsBack <= wsFront ? std::string() : str.substr( wsFront, wsBack - wsFront + 1 );
str.erase( str.begin(), std::find_if( str.begin(), str.end(), []( std::string::value_type ch ) { return !std::isspace( ch ); } ) );
}

std::string trimLeft( std::string str )
{
trimLeftInPlace( str );
return str;
}

void trimRightInPlace( std::string &str )
{
str.erase( std::find_if( str.rbegin(), str.rend(), []( std::string::value_type ch ) { return !std::isspace( ch ); } ).base(), str.end() );
}

std::string trimRight( std::string str )
{
trimRightInPlace( str );
return str;
}

void trimInPlace( std::string &str )
{
trimLeftInPlace( str );
trimRightInPlace( str );
}

std::string trim( std::string str )
{
trimInPlace( str );
return str;
}

void trimLeftInPlace( std::string &str, const std::string &characters )
{
str.erase( str.begin(), std::find_if( str.begin(), str.end(), [characters]( std::string::value_type ch ) { return characters.find( ch ) == std::string::npos; } ) );
}

std::string trimLeft( std::string str, const std::string &characters )
{
trimLeftInPlace( str, characters );
return str;
}

void trimRightInPlace( std::string &str, const std::string &characters )
{
str.erase( std::find_if( str.rbegin(), str.rend(), [characters]( std::string::value_type ch ) { return characters.find( ch ) == std::string::npos; } ).base(), str.end() );
}

std::string trimRight( std::string str, const std::string &characters )
{
trimRightInPlace( str, characters );
return str;
}

void filterInPlace( std::string &str, const std::string &chars )
{
str.erase( std::remove_if( str.begin(), str.end(), [chars]( char c ) { return chars.find( c ) != std::string::npos; } ), str.end() );
}

std::string filter( std::string str, const std::string &chars )
{
filterInPlace( str, chars );
return str;
}

char charToLower( const char c )
{
if( c >= 'A' && c <= 'Z' )
return char( c + 32 );
return c;
}

char charToUpper( const char c )
{
if( c >= 'a' && c <= 'z' )
return char( c - 32 );
return c;
}

std::string toLower( std::string str )
{
thread_local static std::locale loc( "" );
return toLower( std::move( str ), loc );
}

std::string toLower( std::string str, const std::locale &loc )
{
std::transform( str.begin(), str.end(), str.begin(), [loc]( unsigned char c ) { return std::tolower( c, loc ); } );
return str;
}

std::string toUpper( std::string str )
{
thread_local static std::locale loc( "" );
return toUpper( std::move( str ), loc );
}

std::string toUpper( std::string str, const std::locale &loc )
{
std::transform( str.begin(), str.end(), str.begin(), [loc]( unsigned char c ) { return std::toupper( c, loc ); } );
return str;
}

void findReplaceInPlace( const std::string &find, const std::string &replace, std::string &str )
{
auto pos = str.find( find );
while( pos != std::string::npos ) {
str.replace( pos, find.length(), replace );
pos = str.find( find, pos + replace.length() );
}
}

std::string findReplace( const std::string &find, const std::string &replace, std::string str )
{
findReplaceInPlace( find, replace, str );
return str;
}

bool isWhiteSpace( char c )
{
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f';
}

bool isDigit( char c )
{
return !( c < '0' || c > '9' );
}

bool isHexDigit( char c )
{
c = charToLower( c );
return isDigit( c ) || c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f';
}

bool isAlpha( char c )
{
c = charToLower( c );
return !( c < 'a' || c > 'z' );
}

bool isNumeric( char c )
{
return isDigit( c ) || c == '.' || c == '-' || c == 'e' || c == 'E' || c == '+';
}

std::string valueToString( int value )
{
return std::to_string( value );
}

std::string valueToString( unsigned value )
{
return std::to_string( value );
}

std::string valueToString( long value )
{
return std::to_string( value );
}

std::string valueToString( unsigned long value )
{
return std::to_string( value );
}

std::string valueToString( long long value )
{
return std::to_string( value );
}

std::string valueToString( unsigned long long value )
{
return std::to_string( value );
}

std::string valueToString( float value )
{
std::string str = std::to_string( value );
trimRightInPlace( str, "0.," );
return str;
}

std::string valueToString( float value, int precision )
{
std::ostringstream str;
str << std::fixed << std::setprecision( precision ) << value;
return str.str();
}

std::string valueToString( double value )
{
std::string str = std::to_string( value );
trimRightInPlace( str, "0.," );
return str;
}

std::string valueToString( double value, int precision )
{
std::ostringstream str;
str << std::fixed << std::setprecision( precision ) << value;
return str.str();
}

void sleep( float milliseconds )
Expand Down

0 comments on commit 1ba8a56

Please sign in to comment.