Skip to content

Commit 2a8994f

Browse files
committed
Merge string_util.h into cpp2util.h
Minus a couple of functions that aren't used And minor touchups, mainly int_to_string using more if-constexpr
1 parent 85b8458 commit 2a8994f

File tree

5 files changed

+168
-166
lines changed

5 files changed

+168
-166
lines changed

include/cpp2regex.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,7 +3009,7 @@ size_t i{0};
30093009
char number_as_char {unsafe_narrow<char>(cpp2::move(number))};
30103010

30113011
auto token {CPP2_UFCS_TEMPLATE(cpp2_new<char_token>)(cpp2::shared, number_as_char, ctx.get_modifiers().has(expression_flags::case_insensitive))};
3012-
(*cpp2::impl::assert_not_null(token)).set_string("\\" + cpp2::to_string(string_util::int_to_string(cpp2::impl::as_<int>(cpp2::move(number_as_char)), 8)) + "");
3012+
(*cpp2::impl::assert_not_null(token)).set_string("\\" + cpp2::to_string(string_util::int_to_string<8>(cpp2::impl::as_<int>(cpp2::move(number_as_char)))) + "");
30133013

30143014
return token;
30153015
}
@@ -3335,7 +3335,7 @@ template<typename CharT, int group, bool case_insensitive> [[nodiscard]] auto gr
33353335
// TODO: Change for unicode.
33363336
char number_as_char {unsafe_narrow<char>(cpp2::move(number))};
33373337

3338-
std::string syntax {string_util::int_to_string(cpp2::impl::as_<int>(number_as_char), 16)};
3338+
std::string syntax {string_util::int_to_string<16>(cpp2::impl::as_<int>(number_as_char))};
33393339
if (cpp2::move(has_brackets)) {
33403340
syntax = "{" + cpp2::to_string(syntax) + "}";
33413341
}
@@ -3471,7 +3471,7 @@ template<typename CharT, bool positive> [[nodiscard]] auto lookahead_token_match
34713471
// TODO: Change for unicode.
34723472
char number_as_char {unsafe_narrow<char>(cpp2::move(number))};
34733473

3474-
std::string syntax {"\\o{" + cpp2::to_string(string_util::int_to_string(cpp2::impl::as_<int>(number_as_char), 8)) + "}"};
3474+
std::string syntax {"\\o{" + cpp2::to_string(string_util::int_to_string<8>(cpp2::impl::as_<int>(number_as_char))) + "}"};
34753475
auto r {CPP2_UFCS_TEMPLATE(cpp2_new<char_token>)(cpp2::shared, cpp2::move(number_as_char), ctx.get_modifiers().has(expression_flags::case_insensitive))};
34763476
(*cpp2::impl::assert_not_null(r)).set_string(cpp2::move(syntax));
34773477
return r;

include/cpp2regex.h2

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ group_ref_token: @polymorphic_base type = {
15681568
number_as_char : char = unsafe_narrow<char>(number);
15691569

15701570
token := shared.new<char_token>(number_as_char, ctx..get_modifiers()..has(expression_flags::case_insensitive));
1571-
token*..set_string("\\(string_util::int_to_string(number_as_char as int, 8))$");
1571+
token*..set_string("\\(string_util::int_to_string<8>(number_as_char as int))$");
15721572

15731573
return token;
15741574
}
@@ -1902,7 +1902,7 @@ hexadecimal_token_parse: (inout ctx: parse_context) -> token_ptr = {
19021902
// TODO: Change for unicode.
19031903
number_as_char : char = unsafe_narrow<char>(number);
19041904

1905-
syntax: std::string = string_util::int_to_string(number_as_char as int, 16);
1905+
syntax: std::string = string_util::int_to_string<16>(number_as_char as int);
19061906
if has_brackets {
19071907
syntax = "{(syntax)$}";
19081908
}
@@ -2057,7 +2057,7 @@ octal_token_parse: (inout ctx: parse_context) -> token_ptr = {
20572057
// TODO: Change for unicode.
20582058
number_as_char : char = unsafe_narrow<char>(number);
20592059

2060-
syntax: std::string = "\\o{(string_util::int_to_string(number_as_char as int, 8))$}";
2060+
syntax: std::string = "\\o{(string_util::int_to_string<8>(number_as_char as int))$}";
20612061
r := shared.new<char_token>(number_as_char, ctx..get_modifiers()..has(expression_flags::case_insensitive));
20622062
r*..set_string(syntax);
20632063
return r;

include/cpp2util.h

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
// because it can't happen; using the name impl::deferred_init directly
3737
// from program code is not supported.
3838
//
39+
// 3) Entities in other subnamespaces, such as cpp2::string_util
40+
//
41+
// These are typically metafunction "runtime-library" functions,
42+
// implementation details called by metafunction-generated code.
43+
// For example, @regex generates code that uses string_util:: functions.
44+
//
3945
//===========================================================================
4046

4147
#ifndef CPP2_UTIL_H
@@ -323,8 +329,6 @@
323329
#define CPP2_CONSTEXPR constexpr
324330
#endif
325331

326-
#include "string_util.h"
327-
328332
namespace cpp2 {
329333

330334

@@ -364,6 +368,152 @@ using _schar = signed char; // normally use i8 instead
364368
using _uchar = unsigned char; // normally use u8 instead
365369

366370

371+
//-----------------------------------------------------------------------
372+
//
373+
// String utilities
374+
//
375+
376+
namespace string_util {
377+
378+
// From https://stackoverflow.com/questions/216823/how-to-trim-a-stdstring
379+
380+
// Trim from start (in place)
381+
inline void ltrim(std::string &s) {
382+
s.erase(
383+
s.begin(),
384+
std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })
385+
);
386+
}
387+
388+
// Trim from end (in place)
389+
inline void rtrim(std::string &s) {
390+
s.erase(
391+
std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(),
392+
s.end()
393+
);
394+
}
395+
396+
// Trim from both ends (in place)
397+
inline void trim(std::string &s) {
398+
rtrim(s);
399+
ltrim(s);
400+
}
401+
402+
// Trim from both ends (copying)
403+
inline std::string trim_copy(std::string_view s) {
404+
std::string t(s);
405+
trim(t);
406+
return t;
407+
}
408+
409+
// From https://oleksandrkvl.github.io/2021/04/02/cpp-20-overview.html#nttp
410+
411+
template<typename CharT, std::size_t N>
412+
struct fixed_string {
413+
constexpr fixed_string(const CharT (&s)[N+1]) {
414+
std::copy_n(s, N + 1, c_str);
415+
}
416+
constexpr const CharT* data() const {
417+
return c_str;
418+
}
419+
constexpr std::size_t size() const {
420+
return N;
421+
}
422+
423+
constexpr auto str() const {
424+
return std::basic_string<CharT>(c_str);
425+
}
426+
427+
CharT c_str[N+1];
428+
};
429+
430+
template<typename CharT, std::size_t N>
431+
fixed_string(const CharT (&)[N])->fixed_string<CharT, N-1>;
432+
433+
// Other string utility functions.
434+
435+
inline bool is_escaped(std::string_view s) {
436+
return
437+
s.starts_with("\"")
438+
&& s.ends_with("\"")
439+
;
440+
}
441+
442+
inline bool string_to_int(std::string const& s, int& v, int base = 10) {
443+
try {
444+
v = stoi(s, nullptr, base);
445+
return true;
446+
}
447+
catch (std::invalid_argument const&)
448+
{
449+
return false;
450+
}
451+
catch (std::out_of_range const&)
452+
{
453+
return false;
454+
}
455+
}
456+
457+
template<int Base = 10>
458+
inline std::string int_to_string(int i) {
459+
if constexpr (8 == Base) {
460+
std::ostringstream oss;
461+
oss << std::oct << i;
462+
return oss.str();
463+
}
464+
else if constexpr (10 == Base) {
465+
return std::to_string(i);
466+
}
467+
else if constexpr (16 == Base) {
468+
std::ostringstream oss;
469+
oss << std::hex << i;
470+
return oss.str();
471+
}
472+
else {
473+
[] <bool flag = false>() {
474+
static_assert(flag, "Unsupported int_to_string Base");
475+
}();
476+
}
477+
}
478+
479+
inline char safe_toupper(char ch) {
480+
return static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
481+
}
482+
483+
inline char safe_tolower(char ch) {
484+
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
485+
}
486+
487+
inline std::string replace_all(
488+
std::string str,
489+
const std::string& from,
490+
const std::string& to
491+
)
492+
{
493+
size_t start_pos = 0;
494+
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
495+
str.replace(start_pos, from.length(), to);
496+
start_pos += to.length(); // safe also when 'to' is a substring of 'from'
497+
}
498+
return str;
499+
}
500+
501+
template<typename List>
502+
inline std::string join(List const& list) {
503+
std::string r = "";
504+
std::string sep = "";
505+
506+
for (auto const& cur : list) {
507+
r += sep + cur;
508+
sep = ", ";
509+
}
510+
511+
return r;
512+
}
513+
514+
} // namespace string_util
515+
516+
367517
//-----------------------------------------------------------------------
368518
//
369519
// Conveniences for expressing Cpp1 references (rarely useful)

include/string_util.h

Lines changed: 0 additions & 148 deletions
This file was deleted.

0 commit comments

Comments
 (0)