Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
strings.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_BASE_STRINGS_H
7#define ELEMENTA_BASE_STRINGS_H
8
9#include <string>
10#include <vector>
11#include <utility>
12#include <algorithm>
13#include <type_traits>
14#include <sstream>
15#include <bitset>
16#include <iomanip>
17#include <functional>
18#include <cctype>
19#include <limits>
21
22namespace elementa
23{
24
25namespace base
26{
27
47/* ==========================================================================
48
49 TESTING STRINGS
50
51============================================================================*/
52
53
54/* *************************************************************************
55
56 Template class: is_charlike
57
58**************************************************************************/
59
61
62template <typename T>
63struct is_charlike { static constexpr bool value = false; };
64
66template <>
67struct is_charlike<char> { static constexpr bool value = true; };
68
70template <>
71struct is_charlike<wchar_t> { static constexpr bool value = true; };
72
74template <>
75struct is_charlike<char16_t> { static constexpr bool value = true; };
76
78template <>
79struct is_charlike<char32_t> { static constexpr bool value = true; };
80
81
82/* *************************************************************************
83
84 Template class: is_string
85
86******************************************************************************/
87
89
91template <typename... T>
92struct IsStringHelperPriv { typedef void type; };
93
95
100template <typename T, class Enable = void>
101struct is_string: std::false_type {}; // the resulting struct has a ::value
102 // member that is FALSE
103
104template <typename T>
105struct is_string<T,
106 typename IsStringHelperPriv<
107 // this parameter yield error if the
108 // compiler finds in T a type that
109 // has no value_type, traits_type or
110 // allocator_type, but in that case,
111 // due to the SFINAE rule, it will
112 // look for another specialization of
113 // IsStringHelperPriv instead of giving
114 // the error, and that will be the false
115 // one. Otherwise, ::type is void
116 // and this specialization goes on.
117 typename T::value_type,
118 typename T::traits_type,
119 typename T::allocator_type
120 >::type
121 >
122 : std::is_base_of<
123 std::basic_string<
124 typename T::value_type,
125 typename T::traits_type,
126 typename T::allocator_type
127 >,
128 T
129 > {}; // the resulting struct will contain a ::value
130 // member that is TRUE
131
132
133/* *************************************************************************
134
135 Functions: is_all_upper, is_all_lower,
136 is_hex_digit, is_identifier, is_number,
137 is_linechanger, is_blank, is_separator, bytes_for_eol
138
139******************************************************************************/
140
142
144bool is_all_upper(const std::string & s) noexcept;
145
147
149bool is_all_lower(const std::string & s) noexcept;
150
152constexpr bool is_hex_digit(char c) noexcept
153 { return(((c >= 'a') && (c <= 'f')) ||
154 ((c >= 'A') && (c <= 'F')) ||
155 std::isdigit(c)); }
156
158
160bool is_identifier(const std::string & s);
161
163
170bool is_number(const std::string & s, uint8_t base = 10,
171 bool onlyint = false);
172
174constexpr bool is_linechanger(char c)
175 { return((c == '\r') || (c == '\n')); }
176
178constexpr bool is_blank(char c)
179 { return((c == '\t') || (c == ' ')); }
180
182constexpr bool is_separator(char c)
183 { return(is_linechanger(c) || is_blank(c)); }
184
186const std::vector<uint8_t> & bytes_for_eol(void);
187
188
189
190/* ==========================================================================
191
192 CONVERTIG TO/FROM STRING
193
194============================================================================*/
195
196
197/* *************************************************************************
198
199 Template functions: to_string_dec, to_string_hex, to_string_bin,
200 to_string_oct, from_string_hex, from_string_bin
201 Functions: real_to_string, char_to_string, hexdump
202
203******************************************************************************/
204
206
208template <typename NumType>
209std::string to_string_dec(NumType n, bool padding = true)
210{
211 static_assert(std::is_integral<NumType>::value,
212 "to_string_dec only works with integral types");
213
214 std::stringstream stream;
215 if (padding)
216 {
217 stream << std::setw(std::numeric_limits<NumType>::digits10 + 1);
218 stream << std::setfill('0');
219 }
220 stream << n;
221 return(stream.str());
222}
223
225
227template <>
228std::string to_string_dec<>(uint8_t n, bool padding);
229
231
233template <typename NumType>
234std::string to_string_hex(NumType n, bool padding = true)
235{
236 static_assert(std::is_integral<NumType>::value,
237 "to_string_hex only works with integral types");
238
239 std::stringstream stream;
240 if (padding)
241 stream << std::hex <<
242 std::setw(sizeof(NumType)*2) << std::setfill('0') <<
243 std::uppercase <<
244 static_cast<LongestUnsigned>(n); // cast needed for uint8_t...
245 else stream << std::hex << static_cast<LongestUnsigned>(n);// not being char
246 return(stream.str());
247}
248
250
252template <typename NumType>
253std::string to_string_bin(NumType n, bool padding = true)
254{
255 static_assert(std::is_integral<NumType>::value,
256 "to_string_bin only works with integral types");
257
258 const std::string result = std::bitset<sizeof(NumType)*8>(n).to_string();
259 if (padding) return(result);
260 return(result.substr(result.find("1", 0)));
261}
262
264
266template <typename NumType>
267std::string to_string_oct(NumType n, bool padding = true)
268{
269 static_assert(std::is_integral<NumType>::value,
270 "to_string_oct only works with integral types");
271
272 std::stringstream stream;
273 if (padding)
274 stream << std::oct <<
275 std::setw(sizeof(NumType)*2) << std::setfill('0') <<
276 static_cast<LongestUnsigned>(n);
277 else stream << std::oct << static_cast<LongestUnsigned>(n);
278 return(stream.str());
279}
280
282
285template <typename NumType>
286NumType from_string_hex(const std::string & txt)
287{
288 static_assert(std::is_unsigned<NumType>::value,
289 "from_string_hex only works with integral unsigned types");
290
291 NumType v{0};
292 NumType mult{0};
293 NumType c;
294 for (int f = static_cast<int>(txt.size() - 1); f >= 0; --f)
295 {
296 if (std::isdigit(txt[f])) c = txt[f] - '0';
297 else if (std::isalpha(txt[f]))
298 {
299 if (std::isupper(txt[f])) c = txt[f] - 'A' + 10;
300 else c = txt[f] - 'a' + 10;
301 if (c > 15) break;
302 }
303 else break;
304 v += c << mult;
305 mult += 4;
306 }
307 return(v);
308}
309
311
314template <typename NumType>
315NumType from_string_bin(const std::string & txt)
316{
317 static_assert(std::is_unsigned<NumType>::value,
318 "from_string_bin only works with integral unsigned types");
319
320 NumType v{0};
321 NumType mult{0};
322 NumType c;
323 for (int f = static_cast<int>(txt.size() - 1); f >= 0; --f)
324 {
325 if ((txt[f] == '0') || (txt[f] == '1')) c = txt[f] - '0';
326 else break;
327 v += c << mult;
328 ++mult;
329 }
330 return(v);
331}
332
334
336
338std::string real_to_string_fixdec(LongestReal n, unsigned ds);
339
341
343std::string char_to_string(char c);
344
346
348template <typename PointedType>
349std::string hexdump(const PointedType * data, size_t howmany, bool toupp = true,
350 bool sepelems = true)
351{
352 std::string res;
353 if ((data != nullptr) && (howmany > 0))
354 {
355 const auto * bytes = reinterpret_cast<const uint8_t *>(data);
356 for (size_t f = 0; f < howmany; ++f)
357 {
358 res += to_string_hex(*bytes);
359 if (sepelems && (f < howmany - 1)) res.push_back(' ');
360 ++bytes;
361 }
362 if (toupp)
363 std::transform(res.begin(),res.end(),res.begin(),
364 [](char c)->char
365 { return(std::toupper(c)); });
366 }
367 return(res);
368}
369
370
371/* ==========================================================================
372
373 PROCESSING / MODIFYING STRINGS
374
375============================================================================*/
376
377
378/* *************************************************************************
379
380 Function: toCase
381
382*****************************************************************************/
383
385std::string toCase(const std::string & s, char to);
386
387
388/* *************************************************************************
389
390 Functions: ltrim, rtrim, trim / ltrim_mut, rtrim_mut, trim_mut,
391 pad
392
393******************************************************************************/
394
396
400inline std::string & ltrim_mut(std::string & s)
401{
402 auto f = [](int c) { return(!std::isspace(c)); };
403 s.erase(s.begin(), std::find_if(s.begin(),s.end(),f) );
404 // erase() removes characters from the iterator of its first argument to the
405 // iterator of the second one minus 1. find_if() returns iter. to the first
406 // element that satisfies its predicate within two iterators. not1() returns
407 // the complement of its predicate (std::isspace in this case). ptr_fun()
408 // creates a function wrapper for its argument.
409 return(s);
410}
411
413inline std::string ltrim(const std::string & s)
414{
415 std::string res{s};
416 ltrim_mut(res);
417 return(res);
418}
419
421
425inline std::string & rtrim_mut(std::string & s)
426{
427 auto f = [](int c) { return(!std::isspace(c)); };
428 s.erase(std::find_if(s.rbegin(),s.rend(),f).base() , s.end() );
429 return(s);
430}
431
433inline std::string rtrim(const std::string & s)
434{
435 std::string res{s};
436 rtrim_mut(res);
437 return(res);
438}
439
441inline std::string & trim_mut(std::string & s)
442{
443 return(ltrim_mut(rtrim_mut(s)));
444}
445
447inline std::string trim(const std::string & s)
448{
449 std::string res{s};
450 return(trim_mut(res));
451}
452
454
456void pad(std::string & s, size_t len,
457 bool leftorright = false, char padding = ' ');
458
460
462void chop(std::string & s, size_t len, char excess = 0x00,
463 bool leftorright = false, char padding = ' ');
464
465
466
467/* *************************************************************************
468
469 Function: split
470
471*****************************************************************************/
472
474
478std::vector<std::string> split(const std::string & s, char delim);
479
480
481/* *************************************************************************
482
483 Function: concatWithMiddle
484
485*****************************************************************************/
486
488std::string concatWithMiddle(const std::string & s1,
489 const std::string & s2,
490 const std::string & m = ". ");
491
492
493/* ***************************************************************************
494
495 Function: indentlinedtext
496
497*****************************************************************************/
498
500
541std::string indentlinedtext(const std::string & txt,
542 bool atstarttoo = false,
543 std::string::size_type maxlinelength = 80,
544 const std::string & newlinepreffix =" ",
545 const std::string & newlinetext = "\n");
546
547
548
549/* ==========================================================================
550
551 TYPES BASED ON STRINGS
552
553============================================================================*/
554
555
556/* **********************************************************************
557
558 Class: Strings
559
560*************************************************************************/
561
563class Strings: public std::vector<std::string>
564{
565 public:
566
567 using Base = std::vector<std::string>;
568
569 using Base::Base;
570
572
575 std::string to_string(const std::string & preffix = "",
576 const std::string & beg = "{",
577 const std::string & end = "}") const;
578};
579
580
581
582 // Strings
584
585
586} // end namespace base
587
588} // end namespace elementa
589
590#endif
unsigned long long LongestUnsigned
Longest unsigned integral type in the target machine.
long double LongestReal
Longest real type.
std::string to_string(const std::string &preffix="", const std::string &beg="{", const std::string &end="}") const
Return a string formed by all the strings as a set.
A number of strings.
Definition: strings.h:564
std::string & trim_mut(std::string &s)
Remove both right and left space-like characters, directly on input string.
Definition: strings.h:441
const std::vector< uint8_t > & bytes_for_eol(void)
Return a vector containing the bytes that form std::endl in this machine.
std::string rtrim(const std::string &s)
Remove right space-like characters, creating a new string with the result.
Definition: strings.h:433
std::string char_to_string(char c)
Convert a char to a string of 1 char.
std::string to_string_bin(NumType n, bool padding=true)
Convert an integral number to string in binary format.
Definition: strings.h:253
bool is_all_lower(const std::string &s) noexcept
Return TRUE if all characters in S are lowercase.
std::string hexdump(const PointedType *data, size_t howmany, bool toupp=true, bool sepelems=true)
Return a string that represents all hex codes of the pointed bytes.
Definition: strings.h:349
std::string concatWithMiddle(const std::string &s1, const std::string &s2, const std::string &m=". ")
Concatenate two strings putting a middle one only if the second is not empty.
constexpr bool is_blank(char c)
Return TRUE if C is a tab or space character.
Definition: strings.h:178
bool is_identifier(const std::string &s)
Return TRUE if S is a standard identifier.
constexpr bool is_hex_digit(char c) noexcept
Return TRUE if C is an hexadecimal digit, either in lower or uppercase.
Definition: strings.h:152
std::string & ltrim_mut(std::string &s)
Remove left space-like characters, modifying the input string directly.
Definition: strings.h:400
void chop(std::string &s, size_t len, char excess=0x00, bool leftorright=false, char padding=' ')
Chop S to a string of length LEN, padding it if necessary.
std::string real_to_string(LongestReal n)
Convert a N to string with high precision.
std::vector< std::string > split(const std::string &s, char delim)
Split a string through a given delimiter.
std::string indentlinedtext(const std::string &txt, bool atstarttoo=false, std::string::size_type maxlinelength=80, const std::string &newlinepreffix=" ", const std::string &newlinetext="\n")
Return a string after splitting it into a number of indented lines.
std::string ltrim(const std::string &s)
Remove left space-like characters, creating a new string with the result.
Definition: strings.h:413
constexpr bool is_linechanger(char c)
Return TRUE if C is a character involved in changing to new lines of text.
Definition: strings.h:174
bool is_all_upper(const std::string &s) noexcept
Return TRUE if all characters in S are uppercase.
std::string real_to_string_fixdec(LongestReal n, unsigned ds)
Convert N to string with a fixed number of decimal digits. *‍/.
std::string to_string_dec(NumType n, bool padding=true)
Convert an integral number to string in decimal format.
Definition: strings.h:209
bool is_number(const std::string &s, uint8_t base=10, bool onlyint=false)
Return TRUE if S contains a number (possibly with sign) in some base.
std::string to_string_hex(NumType n, bool padding=true)
Convert an integral number to string in hexadecimal format, without preffix.
Definition: strings.h:234
std::string to_string_oct(NumType n, bool padding=true)
Convert an integral number to string in octal format.
Definition: strings.h:267
std::string toCase(const std::string &s, char to)
Convert a string into upper ('U') or lower ('L') case.
void pad(std::string &s, size_t len, bool leftorright=false, char padding=' ')
Pad S with character PADDING if shorter than LEN.
NumType from_string_bin(const std::string &txt)
Return the unsigned int. value of a number expressed in binary form.
Definition: strings.h:315
std::string & rtrim_mut(std::string &s)
Remove right space-like characters, modifying the input string directly.
Definition: strings.h:425
constexpr bool is_separator(char c)
Return TRUE if C is a separator character.
Definition: strings.h:182
std::string trim(const std::string &s)
Remove both right and left space-like characters, creating new string.
Definition: strings.h:447
NumType from_string_hex(const std::string &txt)
Return the unsigned int. value of a number expressed in hexadecimal form.
Definition: strings.h:286
A struct with a void member.
Definition: strings.h:92
Return TRUE if type T is char, wchar_t, char16_t or char32_t.
Definition: strings.h:63
Template class to check whether T is derived from std::basic_string.
Definition: strings.h:101