Geogram Version 1.10.0-rc
A programming library of geometric algorithms
Loading...
Searching...
No Matches
string.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_BASIC_STRING
41#define GEOGRAM_BASIC_STRING
42
45
46#include <string>
47#include <sstream>
48#include <stdexcept>
49#include <iomanip>
50
51#include <vector>
52#include <stdlib.h>
53#include <string.h>
54#include <errno.h>
55#include <stdio.h>
56#include <limits.h>
57
63namespace GEO {
64
65 /*
66 * \brief String manipulation utilities.
67 */
68 namespace String {
69
81 void GEOGRAM_API split_string(
82 const std::string& in,
83 char separator,
84 std::vector<std::string>& out,
85 bool skip_empty_fields = true
86 );
87
99 void GEOGRAM_API split_string(
100 const std::string& in,
101 const std::string& separator,
102 std::vector<std::string>& out,
103 bool skip_empty_fields = true
104 );
105
119 bool GEOGRAM_API split_string(
120 const std::string& in,
121 char separator,
122 std::string& left,
123 std::string& right
124 );
125
126
140 bool GEOGRAM_API split_string(
141 const std::string& in,
142 const std::string& separator,
143 std::string& left,
144 std::string& right
145 );
146
156 std::string GEOGRAM_API join_strings(
157 const std::vector<std::string>& in,
158 char separator
159 );
160
170 std::string GEOGRAM_API join_strings(
171 const std::vector<std::string>& in,
172 const std::string& separator
173 );
174
181 std::string GEOGRAM_API to_lowercase(const std::string& s);
182
189 std::string GEOGRAM_API to_uppercase(const std::string& s);
190
196 inline std::string char_to_string(char c) {
197 char s[2];
198 s[0] = c;
199 s[1] = '\0';
200 return std::string(s);
201 }
202
211 std::string GEOGRAM_API quote(
212 const std::string& s, char quotes = '\"'
213 );
214
222 bool GEOGRAM_API string_starts_with(
223 const std::string& haystack, const std::string& needle
224 );
225
233 bool GEOGRAM_API string_ends_with(
234 const std::string& haystack, const std::string& needle
235 );
236
244 GEO_NODISCARD inline std::string remove_prefix(
245 const std::string& s, const std::string& prefix
246 ) {
247 if(string_starts_with(s, prefix)) {
248 return s.substr(prefix.length());
249 }
250 return s;
251 }
252
260 GEO_NODISCARD inline std::string remove_suffix(
261 const std::string& s, const std::string& suffix
262 ) {
263 if(string_ends_with(s, suffix)) {
264 return s.substr(0, s.length() - suffix.length());
265 }
266 return s;
267 }
268
275 GEO_NODISCARD inline std::string trim_spaces(const std::string& s) {
276 size_t first = s.find_first_not_of(' ');
277 if (first == std::string::npos) {
278 return s;
279 }
280 size_t last = s.find_last_not_of(' ');
281 return s.substr(first, (last - first + 1));
282 }
283
289 std::string GEOGRAM_API format(const char* format, ...)
290#ifndef GOMGEN
291#ifdef GEO_COMPILER_GCC_FAMILY
292 // Tells the compiler that format is a printf-like format
293 // string, so that it can check that the arguments match
294 // the format string and bark at you if it is not the case.
295 __attribute__ ((__format__(printf, 1, 2)))
296#endif
297#endif
298 ;
299
306 std::string GEOGRAM_API format_time(double seconds, bool HMS_only=false);
307
313 template <class T>
314 inline std::string to_string(const T& value) {
315 std::ostringstream out;
316 // Makes sure that double-precision number are displayed
317 // with a sufficient number of digits. This is important
318 // to avoid losing precision when using ASCII files.
319 out << std::setprecision(17);
320 out << value;
321 return out.str();
322 }
323
324
331 template <>
332 inline std::string to_string(const unsigned char& value) {
333 std::ostringstream out;
334 out << int(value);
335 return out.str();
336 }
337
338 template <>
339 inline std::string to_string(const signed char& value) {
340 std::ostringstream out;
341 out << int(value);
342 return out.str();
343 }
344
345
353 template <class T>
354 inline std::string to_display_string(const T& value) {
355 return to_string(value);
356 }
357
358
366 template <>
367 inline std::string to_display_string(const double& value) {
368 std::ostringstream out;
369 out << value;
370 return out.str();
371 }
372
380 template <>
381 inline std::string to_display_string(const float& value) {
382 std::ostringstream out;
383 out << value;
384 return out.str();
385 }
386
393 template <>
394 inline std::string to_string(const bool& value) {
395 return value ? "true" : "false";
396 }
397
404 class GEOGRAM_API ConversionError : public std::logic_error {
405 public:
411 ConversionError(const std::string& s, const std::string& type);
412
416 const char* what() const GEO_NOEXCEPT override;
417 };
418
429 template <class T>
430 inline bool from_string(const char* s, T& value) {
431 std::istringstream in(s);
432 return (in >> value) && (in.eof() || ((in >> std::ws) && in.eof()));
433 }
434
445 template <class T>
446 inline bool from_string(const std::string& s, T& value) {
447 return from_string(s.c_str(), value);
448 }
449
457 template <>
458 inline bool from_string(const char* s, double& value) {
459 errno = 0;
460 char* end;
461 value = strtod(s, &end);
462 return end != s && *end == '\0' && errno == 0;
463 }
464
472 template <typename T>
473 inline bool string_to_signed_integer(const char* s, T& value) {
474 errno = 0;
475 char* end;
476#ifdef GEO_OS_WINDOWS
477 Numeric::int64 v = _strtoi64(s, &end, 10);
478#else
479 Numeric::int64 v = strtoll(s, &end, 10);
480#endif
481 if(
482 end != s && *end == '\0' && errno == 0 &&
483 v >= std::numeric_limits<T>::min() &&
484 v <= std::numeric_limits<T>::max()
485 ) {
486 value = static_cast<T>(v);
487 return true;
488 }
489
490 return false;
491 }
492
497 template <>
498 inline bool from_string(const char* s, Numeric::int8& value) {
499 return string_to_signed_integer(s, value);
500 }
501
506 template <>
507 inline bool from_string(const char* s, Numeric::int16& value) {
508 return string_to_signed_integer(s, value);
509 }
510
515 template <>
516 inline bool from_string(const char* s, Numeric::int32& value) {
517 return string_to_signed_integer(s, value);
518 }
519
523 template <>
524 inline bool from_string(const char* s, Numeric::int64& value) {
525 errno = 0;
526 char* end;
527#ifdef GEO_OS_WINDOWS
528 value = _strtoi64(s, &end, 10);
529#else
530 value = strtoll(s, &end, 10);
531#endif
532 return end != s && *end == '\0' && errno == 0;
533 }
534
542 template <typename T>
543 inline bool string_to_unsigned_integer(const char* s, T& value) {
544 errno = 0;
545 char* end;
546#ifdef GEO_OS_WINDOWS
547 Numeric::uint64 v = _strtoui64(s, &end, 10);
548#else
549 Numeric::uint64 v = strtoull(s, &end, 10);
550#endif
551 if(
552 end != s && *end == '\0' && errno == 0 &&
553 v <= std::numeric_limits<T>::max()
554 ) {
555 value = static_cast<T>(v);
556 return true;
557 }
558
559 return false;
560 }
561
566 template <>
567 inline bool from_string(const char* s, Numeric::uint8& value) {
568 return string_to_unsigned_integer(s, value);
569 }
570
575 template <>
576 inline bool from_string(const char* s, Numeric::uint16& value) {
577 return string_to_unsigned_integer(s, value);
578 }
579
584 template <>
585 inline bool from_string(const char* s, Numeric::uint32& value) {
586 return string_to_unsigned_integer(s, value);
587 }
588
592 template <>
593 inline bool from_string(const char* s, Numeric::uint64& value) {
594 errno = 0;
595 char* end;
596#ifdef GEO_OS_WINDOWS
597 value = _strtoui64(s, &end, 10);
598#else
599 value = strtoull(s, &end, 10);
600#endif
601 return end != s && *end == '\0' && errno == 0;
602 }
603
614 template <>
615 inline bool from_string(const char* s, bool& value) {
616 if(strcmp(s, "true") == 0 ||
617 strcmp(s, "True") == 0 ||
618 strcmp(s, "1") == 0
619 ) {
620 value = true;
621 return true;
622 }
623 if(strcmp(s, "false") == 0 ||
624 strcmp(s, "False") == 0 ||
625 strcmp(s, "0") == 0
626 ) {
627 value = false;
628 return true;
629 }
630 return false;
631 }
632
642 inline int to_int(const std::string& s) {
643 int value;
644 if(!from_string(s, value)) {
645 throw ConversionError(s, "integer");
646 }
647 return value;
648 }
649
659 inline unsigned int to_uint(const std::string& s) {
660 unsigned int value;
661 if(!from_string(s, value)) {
662 throw ConversionError(s, "integer");
663 }
664 return value;
665 }
666
676 inline double to_double(const std::string& s) {
677 double value;
678 if(!from_string(s, value)) {
679 throw ConversionError(s, "double");
680 }
681 return value;
682 }
683
693 inline bool to_bool(const std::string& s) {
694 bool value;
695 if(!from_string(s, value)) {
696 throw ConversionError(s, "boolean");
697 }
698 return value;
699 }
700
706 std::string GEOGRAM_API wchar_to_UTF8(const wchar_t* in);
707 }
708}
709
710#endif
Conversion exception.
Definition string.h:404
ConversionError(const std::string &s, const std::string &type)
Constructs a conversion exception.
const char * what() const GEO_NOEXCEPT override
Gets the string identifying the exception.
Common include file, providing basic definitions. Should be included before anything else by all head...
uint8_t uint8
Definition numeric.h:136
uint64_t uint64
Definition numeric.h:145
int8_t int8
Definition numeric.h:124
int32_t int32
Definition numeric.h:130
uint16_t uint16
Definition numeric.h:139
uint32_t uint32
Definition numeric.h:142
int16_t int16
Definition numeric.h:127
int64_t int64
Definition numeric.h:133
Global Vorpaline namespace.
Definition basic.h:55
Types and functions for numbers manipulation.
Functions for string manipulation.
std::string to_string(const T &value)
Converts a typed value to a string.
Definition string.h:314
bool string_to_unsigned_integer(const char *s, T &value)
Converts a string to a unsigned integer value.
Definition string.h:543
std::string wchar_to_UTF8(const wchar_t *in)
Converts a wide char string into an UTF8 string.
std::string to_uppercase(const std::string &s)
Converts a string to uppercase.
std::string char_to_string(char c)
Creates a one char string.
Definition string.h:196
bool from_string(const char *s, T &value)
Converts a C string to a typed value.
Definition string.h:430
void split_string(const std::string &in, char separator, std::vector< std::string > &out, bool skip_empty_fields=true)
Splits a string into parts.
int to_int(const std::string &s)
Converts a string to an int.
Definition string.h:642
bool string_starts_with(const std::string &haystack, const std::string &needle)
Checks if a string starts with a substring.
bool string_ends_with(const std::string &haystack, const std::string &needle)
Checks if a string ends with a substring.
std::string format(const char *format,...)
Creates a string from a format string and additional arguments. Works like sprintf()
std::string format_time(double seconds, bool HMS_only=false)
Converts a time in seconds into a human-readable string.
std::string join_strings(const std::vector< std::string > &in, char separator)
Join multiple strings.
std::string quote(const std::string &s, char quotes='\"' )
Adds quotes to a string.
unsigned int to_uint(const std::string &s)
Converts a string to an unsigned int.
Definition string.h:659
GEO_NODISCARD std::string remove_suffix(const std::string &s, const std::string &suffix)
Removes a suffix from a string.
Definition string.h:260
std::string to_lowercase(const std::string &s)
Converts a string to lowercase.
std::string to_display_string(const T &value)
Converts a typed value to a string for display.
Definition string.h:354
GEO_NODISCARD std::string trim_spaces(const std::string &s)
Removes the leading and trailing spaces from a string.
Definition string.h:275
bool to_bool(const std::string &s)
Converts a string to a boolean.
Definition string.h:693
bool string_to_signed_integer(const char *s, T &value)
Converts a string to a signed integer value.
Definition string.h:473
double to_double(const std::string &s)
Converts a string to a double.
Definition string.h:676
GEO_NODISCARD std::string remove_prefix(const std::string &s, const std::string &prefix)
Removes a prefix from a string.
Definition string.h:244