catch_string_manip.cpp
1 2 // Copyright Catch2 Authors 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE.txt or copy at 5 // https://www.boost.org/LICENSE_1_0.txt) 6 7 // SPDX-License-Identifier: BSL-1.0 8 #include <catch2/internal/catch_string_manip.hpp> 9 #include <catch2/internal/catch_stringref.hpp> 10 11 #include <ostream> 12 #include <cstring> 13 #include <cctype> 14 #include <vector> 15 16 namespace Catch { 17 18 bool startsWith( std::string const& s, std::string const& prefix ) { 19 return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); 20 } 21 bool startsWith( StringRef s, char prefix ) { 22 return !s.empty() && s[0] == prefix; 23 } 24 bool endsWith( std::string const& s, std::string const& suffix ) { 25 return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); 26 } 27 bool endsWith( std::string const& s, char suffix ) { 28 return !s.empty() && s[s.size()-1] == suffix; 29 } 30 bool contains( std::string const& s, std::string const& infix ) { 31 return s.find( infix ) != std::string::npos; 32 } 33 void toLowerInPlace( std::string& s ) { 34 for ( char& c : s ) { 35 c = toLower( c ); 36 } 37 } 38 std::string toLower( std::string const& s ) { 39 std::string lc = s; 40 toLowerInPlace( lc ); 41 return lc; 42 } 43 char toLower(char c) { 44 return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); 45 } 46 47 std::string trim( std::string const& str ) { 48 static char const* whitespaceChars = "\n\r\t "; 49 std::string::size_type start = str.find_first_not_of( whitespaceChars ); 50 std::string::size_type end = str.find_last_not_of( whitespaceChars ); 51 52 return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); 53 } 54 55 StringRef trim(StringRef ref) { 56 const auto is_ws = [](char c) { 57 return c == ' ' || c == '\t' || c == '\n' || c == '\r'; 58 }; 59 size_t real_begin = 0; 60 while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; } 61 size_t real_end = ref.size(); 62 while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; } 63 64 return ref.substr(real_begin, real_end - real_begin); 65 } 66 67 bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { 68 bool replaced = false; 69 std::size_t i = str.find( replaceThis ); 70 while( i != std::string::npos ) { 71 replaced = true; 72 str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); 73 if( i < str.size()-withThis.size() ) 74 i = str.find( replaceThis, i+withThis.size() ); 75 else 76 i = std::string::npos; 77 } 78 return replaced; 79 } 80 81 std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) { 82 std::vector<StringRef> subStrings; 83 std::size_t start = 0; 84 for(std::size_t pos = 0; pos < str.size(); ++pos ) { 85 if( str[pos] == delimiter ) { 86 if( pos - start > 1 ) 87 subStrings.push_back( str.substr( start, pos-start ) ); 88 start = pos+1; 89 } 90 } 91 if( start < str.size() ) 92 subStrings.push_back( str.substr( start, str.size()-start ) ); 93 return subStrings; 94 } 95 96 std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { 97 os << pluraliser.m_count << ' ' << pluraliser.m_label; 98 if( pluraliser.m_count != 1 ) 99 os << 's'; 100 return os; 101 } 102 103 }