44 #include <immintrin.h> 54 bool contains_ci( std::vector<std::string>
const& haystack, std::string
const& needle )
56 auto const l_needle =
to_lower( needle );
57 for(
auto const& val : haystack ) {
65 bool equals_ci( std::string
const& lhs, std::string
const& rhs)
67 const size_t sz = lhs.size();
68 if( rhs.size() != sz ) {
71 for(
size_t i = 0; i < sz; ++i ) {
72 if( tolower( lhs[i] ) != tolower( rhs[i] ) ) {
79 bool starts_with( std::string
const & text, std::string
const & start )
81 if (start.size() > text.size()) {
84 return std::equal( start.begin(), start.end(), text.begin() );
87 bool ends_with( std::string
const & text, std::string
const & ending )
89 if (ending.size() > text.size()) {
92 return std::equal( ending.rbegin(), ending.rend(), text.rbegin() );
99 std::string
head( std::string
const& text,
size_t lines )
102 auto vec =
split( text,
"\n",
false );
103 size_t remove = vec.size() > lines ? vec.size() - lines : 0;
104 vec.erase( vec.end() -
remove, vec.end() );
105 return join( vec,
"\n" );
108 std::string
tail( std::string
const& text,
size_t lines )
111 auto vec =
split( text,
"\n",
false );
112 size_t remove = vec.size() > lines ? vec.size() - lines : 0;
113 vec.erase( vec.begin(), vec.begin() + remove );
114 return join( vec,
"\n" );
123 if (sub.length() == 0) {
129 size_t offset = str.find(sub);
130 offset != std::string::npos;
143 std::string
const&
string,
144 std::function<
size_t ( std::string
const&,
size_t )> find_pos,
146 const bool trim_empty
148 std::vector<std::string> result;
153 size_t pos = find_pos(
string, last_pos );
156 if( pos == std::string::npos ) {
157 pos =
string.length();
159 if( pos != last_pos || !trim_empty ) {
160 result.push_back( std::string(
string.data() + last_pos, pos - last_pos ));
167 if( pos != last_pos || !trim_empty ) {
168 result.push_back( std::string(
string.data() + last_pos, pos - last_pos ));
172 last_pos = pos + advance_by;
179 std::string
const& str,
180 std::string
const& delimiters,
181 const bool trim_empty
185 [&]( std::string
const& str,
size_t last_pos ){
186 return str.find_first_of( delimiters, last_pos );
194 std::string
const& str,
195 std::function<
bool(
char)> delimiter_predicate,
196 const bool trim_empty
200 [&]( std::string
const& str,
size_t last_pos ){
202 size_t pos = std::string::npos;
203 for(
size_t i = last_pos; i < str.size(); ++i ) {
204 if( delimiter_predicate( str[i] ) ) {
217 std::string
const& str,
218 std::string
const& delimiter,
219 const bool trim_empty
223 [&]( std::string
const& str,
size_t last_pos ){
224 return str.find( delimiter, last_pos );
233 std::vector<size_t> result;
235 auto is_digits = []( std::string
const& s ){
236 return trim( s ).find_first_not_of(
"0123456789" ) == std::string::npos;
239 auto get_number = []( std::string
const& s ){
241 sscanf(
trim( s ).c_str(),
"%zu", &n );
245 if(
trim( str ).empty() ) {
249 auto const lst =
split( str,
"," );
250 for(
auto const& le : lst ) {
252 if( is_digits( le ) ) {
253 result.push_back( get_number( le ));
255 auto const rng =
split( le,
"-" );
256 if( rng.size() != 2 || ! is_digits( rng[0] ) || ! is_digits( rng[1] ) ) {
257 throw std::runtime_error(
"Invalid range list string." );
259 auto const b = get_number( rng[0] );
260 auto const e = get_number( rng[1] );
261 for(
size_t i = b; i <= e; ++i ) {
262 result.push_back( i );
267 std::sort( result.begin(), result.end() );
276 std::string
const& text,
289 std::ostringstream output;
290 auto const lines =
split( text,
"\n",
false );
291 for(
auto const& line : lines ) {
292 std::istringstream text_stream( line );
295 if( text_stream >> word ) {
297 long space_left =
static_cast<long>( line_length ) - static_cast<long>( word.length() );
298 while( text_stream >> word ) {
299 if( space_left < static_cast<long>( word.length() + 1 )) {
300 output <<
"\n" << word;
301 space_left = line_length - word.length();
303 output <<
" " << word;
304 space_left -= word.length() + 1;
315 std::string
const& text,
316 std::string
const& indentation
318 auto ret = indentation +
replace_all( text,
"\n",
"\n" + indentation );
323 std::string
const& text, std::string
const& search, std::string
const& replace
325 std::string tmp = text;
326 for (
size_t pos = 0; ; pos += replace.length()) {
327 pos = tmp.find(search, pos);
329 if (pos == std::string::npos){
333 tmp.erase(pos, search.length());
334 tmp.insert(pos, replace);
357 std::string
const& text,
358 std::string
const& search_chars,
362 for(
auto& c : result ) {
363 if( search_chars.find( c ) != std::string::npos ) {
371 std::string
const& s,
372 std::string
const& delimiters
374 auto const pos = s.find_last_not_of(delimiters);
375 if( std::string::npos == pos ) {
378 return s.substr( 0, pos + 1 );
383 std::string
const& s,
384 std::string
const& delimiters
386 auto const pos = s.find_first_not_of(delimiters);
387 if( std::string::npos == pos ) {
390 return s.substr(pos);
395 std::string
const& s,
396 std::string
const& delimiters
407 inline void toggle_case_ascii_inplace_avx_( std::string& str,
char char_a,
char char_z )
414 auto static const val_32 = _mm256_set1_epi8( 0x20 );
417 auto const mask_a = _mm256_set1_epi8( char_a );
418 auto const mask_z = _mm256_set1_epi8( char_z );
421 for(
size_t i = 0; i < str.size() / 32 * 32; i += 32 ) {
422 auto reg = _mm256_loadu_si256( reinterpret_cast<__m256i*>( &str[i] ) );
425 auto mask_az = _mm256_or_si256( _mm256_cmpgt_epi8( mask_a, reg ), _mm256_cmpgt_epi8( reg, mask_z ) );
428 reg = _mm256_xor_si256( _mm256_andnot_si256( mask_az, val_32 ), reg );
430 _mm256_storeu_si256( reinterpret_cast<__m256i*>( &str[i] ), reg );
434 for(
size_t i = str.size() / 32 * 32; i < str.size(); ++i ) {
435 if( char_a <= str[i] && str[i] <= char_z ){
441 #endif // GENESIS_AVX 448 toggle_case_ascii_inplace_avx_( str,
'A',
'Z' );
453 for(
auto& c : str ){
457 #endif // GENESIS_AVX 472 toggle_case_ascii_inplace_avx_( str,
'a',
'z' );
477 for(
auto& c : str ){
481 #endif // GENESIS_AVX 495 std::string
escape( std::string
const& text )
511 tmp.reserve( text.size() );
514 for(
size_t i = 0; i < text.size(); ++i ) {
515 if( text[ i ] ==
'\\' ) {
516 if( i + 1 >= text.size() ){
550 std::string
repeat( std::string
const& word,
size_t times )
554 result.reserve( times * word.length() );
557 for(
size_t i = 0; i < times; ++i ) {
565 std::stringstream ss;
566 ss << std::setw( length ) << std::setfill(
'0' ) << value;
573 std::ostringstream s;
574 s << std::fixed << std::setprecision( precision ) << value;
581 std::ostringstream s;
582 s << std::fixed << std::setprecision( precision ) << value;
588 size_t const last_nonzero = str.find_last_not_of(
'0');
589 if( str[ last_nonzero ] ==
'.' ) {
592 str.erase( last_nonzero + offset, std::string::npos );
void offset(Histogram &h, double value)
std::string escape(std::string const &text)
Return a string where special chars are replaces by their escape sequence.
std::string deescape(std::string const &text)
Return a string where backslash-escaped characters are transformed into their respective string form...
std::string to_string_rounded(double const value, int const precision)
Return a string representation of the input value, using the provided precision value (determining it...
bool starts_with(std::string const &text, std::string const &start)
Return whether a string starts with another string.
std::string repeat(std::string const &word, size_t times)
Take a string and repeat it a given number of times.
void to_upper_ascii_inplace(std::string &str)
Turn the given string to all-uppercase, ASCII-only, inline.
std::vector< size_t > split_range_list(std::string const &str)
Split a string containing positive interger numbers into its parts and resolve ranges.
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
std::string to_upper_ascii(std::string const &str)
Return an all-uppercase copy of the given string, ASCII-only.
std::string join(T const &v, std::string const &delimiter=", ")
Return a string where the elements of a container v are joined using the string delimiter in between ...
std::string indent(std::string const &text, std::string const &indentation)
Indent each line of text with indentation and return the result.
std::string trim_left(std::string const &s, std::string const &delimiters)
Return a copy of the input string, with right trimmed white spaces.
std::string replace_all(std::string const &text, std::string const &search, std::string const &replace)
Return a copy of a string, where all occurrences of a search string are replaced by a replace string...
std::string trim_right(std::string const &s, std::string const &delimiters)
Return a copy of the input string, with left trimmed white spaces.
std::string trim(std::string const &s, std::string const &delimiters)
Return a copy of the input string, with trimmed white spaces.
void to_lower_ascii_inplace(std::string &str)
Turn the given string to all-lowercase, ASCII-only.
std::string replace_all_chars(std::string const &text, std::string const &search_chars, char replace)
Replace all occurrences of the search_chars in text by the replace char.
std::string to_string_precise(double const value, int const precision)
Return a precise string representation of the input value, using the provided precision value (determ...
std::string to_string_leading_zeros(size_t value, size_t length)
Return a string representation of a size_t value with a fixed length, that is, by adding leading zero...
std::string wrap(std::string const &text, size_t line_length)
Wrap a text at a given line_length.
static std::vector< std::string > split_(std::string const &string, std::function< size_t(std::string const &, size_t)> find_pos, size_t advance_by, const bool trim_empty)
Local function that does the work for the split cuntions.
std::vector< std::string > split(std::string const &str, std::string const &delimiters, const bool trim_empty)
Spilt a string into parts, given a delimiters set of chars.
std::string head(std::string const &text, size_t lines)
Return the first lines of the text.
Provides some commonly used string utility functions.
bool equals_ci(std::string const &lhs, std::string const &rhs)
Compare two strings case insensitive.
bool ends_with(std::string const &text, std::string const &ending)
Return whether a string ends with another string.
std::string tail(std::string const &text, size_t lines)
Return the last lines of the text.
size_t count_substring_occurrences(std::string const &str, std::string const &sub)
Return the number of (possibly overlapping) occurrences of a substring in a string.
constexpr char to_upper(char c) noexcept
Return the upper case version of a letter, ASCII-only.
std::vector< std::string > split_at(std::string const &str, std::string const &delimiter, const bool trim_empty)
Spilt a string into parts, given a delimiter string.
double length(Tree const &tree)
Get the length of the tree, i.e., the sum of all branch lengths.
constexpr char to_lower(char c) noexcept
Return the lower case version of a letter, ASCII-only.
bool equal(Tree const &lhs, Tree const &rhs, std::function< bool(TreeNode const &, TreeNode const &) > node_comparator, std::function< bool(TreeEdge const &, TreeEdge const &) > edge_comparator)
Compare two trees for equality given binary comparator functionals for their nodes and edges...
std::string to_lower_ascii(std::string const &str)
Return an all-lowercase copy of the given string, ASCII-only.
bool contains_ci(std::vector< std::string > const &haystack, std::string const &needle)
Return whether a vector of strings contains a given string, case insensitive.