Geogram  Version 1.9.0
A programming library of geometric algorithms
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 
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/numeric.h>
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 
63 namespace 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 
135  std::string GEOGRAM_API join_strings(
136  const std::vector<std::string>& in,
137  char separator
138  );
139 
149  std::string GEOGRAM_API join_strings(
150  const std::vector<std::string>& in,
151  const std::string& separator
152  );
153 
160  std::string GEOGRAM_API to_lowercase(const std::string& s);
161 
168  std::string GEOGRAM_API to_uppercase(const std::string& s);
169 
175  inline std::string char_to_string(char c) {
176  char s[2];
177  s[0] = c;
178  s[1] = '\0';
179  return std::string(s);
180  }
181 
190  std::string GEOGRAM_API quote(
191  const std::string& s, char quotes = '\"'
192  );
193 
201  bool GEOGRAM_API string_starts_with(
202  const std::string& haystack, const std::string& needle
203  );
204 
212  bool GEOGRAM_API string_ends_with(
213  const std::string& haystack, const std::string& needle
214  );
215 
221  std::string GEOGRAM_API format(const char* format, ...)
222 #ifndef GOMGEN
223 #ifdef GEO_COMPILER_GCC_FAMILY
224  // Tells the compiler that format is a printf-like format
225  // string, so that it can check that the arguments match
226  // the format string and bark at you if it is not the case.
227  __attribute__ ((__format__(printf, 1, 2)))
228 #endif
229 #endif
230  ;
231 
237  template <class T>
238  inline std::string to_string(const T& value) {
239  std::ostringstream out;
240  // Makes sure that double-precision number are displayed
241  // with a sufficient number of digits. This is important
242  // to avoid losing precision when using ASCII files.
243  out << std::setprecision(17);
244  out << value;
245  return out.str();
246  }
247 
255  template <class T>
256  inline std::string to_display_string(const T& value) {
257  return to_string(value);
258  }
259 
260 
268  template <>
269  inline std::string to_display_string(const double& value) {
270  std::ostringstream out;
271  out << value;
272  return out.str();
273  }
274 
282  template <>
283  inline std::string to_display_string(const float& value) {
284  std::ostringstream out;
285  out << value;
286  return out.str();
287  }
288 
295  template <>
296  inline std::string to_string(const bool& value) {
297  return value ? "true" : "false";
298  }
299 
306  class GEOGRAM_API ConversionError : public std::logic_error {
307  public:
313  ConversionError(const std::string& s, const std::string& type);
314 
318  const char* what() const GEO_NOEXCEPT override;
319  };
320 
331  template <class T>
332  inline bool from_string(const char* s, T& value) {
333  std::istringstream in(s);
334  return (in >> value) && (in.eof() || ((in >> std::ws) && in.eof()));
335  }
336 
347  template <class T>
348  inline bool from_string(const std::string& s, T& value) {
349  return from_string(s.c_str(), value);
350  }
351 
359  template <>
360  inline bool from_string(const char* s, double& value) {
361  errno = 0;
362  char* end;
363  value = strtod(s, &end);
364  return end != s && *end == '\0' && errno == 0;
365  }
366 
374  template <typename T>
375  inline bool string_to_signed_integer(const char* s, T& value) {
376  errno = 0;
377  char* end;
378 #ifdef GEO_OS_WINDOWS
379  Numeric::int64 v = _strtoi64(s, &end, 10);
380 #else
381  Numeric::int64 v = strtoll(s, &end, 10);
382 #endif
383  if(
384  end != s && *end == '\0' && errno == 0 &&
385  v >= std::numeric_limits<T>::min() &&
386  v <= std::numeric_limits<T>::max()
387  ) {
388  value = static_cast<T>(v);
389  return true;
390  }
391 
392  return false;
393  }
394 
399  template <>
400  inline bool from_string(const char* s, Numeric::int8& value) {
401  return string_to_signed_integer(s, value);
402  }
403 
408  template <>
409  inline bool from_string(const char* s, Numeric::int16& value) {
410  return string_to_signed_integer(s, value);
411  }
412 
417  template <>
418  inline bool from_string(const char* s, Numeric::int32& value) {
419  return string_to_signed_integer(s, value);
420  }
421 
425  template <>
426  inline bool from_string(const char* s, Numeric::int64& value) {
427  errno = 0;
428  char* end;
429 #ifdef GEO_OS_WINDOWS
430  value = _strtoi64(s, &end, 10);
431 #else
432  value = strtoll(s, &end, 10);
433 #endif
434  return end != s && *end == '\0' && errno == 0;
435  }
436 
444  template <typename T>
445  inline bool string_to_unsigned_integer(const char* s, T& value) {
446  errno = 0;
447  char* end;
448 #ifdef GEO_OS_WINDOWS
449  Numeric::uint64 v = _strtoui64(s, &end, 10);
450 #else
451  Numeric::uint64 v = strtoull(s, &end, 10);
452 #endif
453  if(
454  end != s && *end == '\0' && errno == 0 &&
455  v <= std::numeric_limits<T>::max()
456  ) {
457  value = static_cast<T>(v);
458  return true;
459  }
460 
461  return false;
462  }
463 
468  template <>
469  inline bool from_string(const char* s, Numeric::uint8& value) {
470  return string_to_unsigned_integer(s, value);
471  }
472 
477  template <>
478  inline bool from_string(const char* s, Numeric::uint16& value) {
479  return string_to_unsigned_integer(s, value);
480  }
481 
486  template <>
487  inline bool from_string(const char* s, Numeric::uint32& value) {
488  return string_to_unsigned_integer(s, value);
489  }
490 
494  template <>
495  inline bool from_string(const char* s, Numeric::uint64& value) {
496  errno = 0;
497  char* end;
498 #ifdef GEO_OS_WINDOWS
499  value = _strtoui64(s, &end, 10);
500 #else
501  value = strtoull(s, &end, 10);
502 #endif
503  return end != s && *end == '\0' && errno == 0;
504  }
505 
516  template <>
517  inline bool from_string(const char* s, bool& value) {
518  if(strcmp(s, "true") == 0 ||
519  strcmp(s, "True") == 0 ||
520  strcmp(s, "1") == 0
521  ) {
522  value = true;
523  return true;
524  }
525  if(strcmp(s, "false") == 0 ||
526  strcmp(s, "False") == 0 ||
527  strcmp(s, "0") == 0
528  ) {
529  value = false;
530  return true;
531  }
532  return false;
533  }
534 
544  inline int to_int(const std::string& s) {
545  int value;
546  if(!from_string(s, value)) {
547  throw ConversionError(s, "integer");
548  }
549  return value;
550  }
551 
561  inline unsigned int to_uint(const std::string& s) {
562  unsigned int value;
563  if(!from_string(s, value)) {
564  throw ConversionError(s, "integer");
565  }
566  return value;
567  }
568 
578  inline double to_double(const std::string& s) {
579  double value;
580  if(!from_string(s, value)) {
581  throw ConversionError(s, "double");
582  }
583  return value;
584  }
585 
595  inline bool to_bool(const std::string& s) {
596  bool value;
597  if(!from_string(s, value)) {
598  throw ConversionError(s, "boolean");
599  }
600  return value;
601  }
602 
608  std::string GEOGRAM_API wchar_to_UTF8(const wchar_t* in);
609  }
610 }
611 
612 #endif
613 
Conversion exception.
Definition: string.h:306
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:135
uint64_t uint64
Definition: numeric.h:144
int8_t int8
Definition: numeric.h:123
int32_t int32
Definition: numeric.h:129
uint16_t uint16
Definition: numeric.h:138
uint32_t uint32
Definition: numeric.h:141
int16_t int16
Definition: numeric.h:126
int64_t int64
Definition: numeric.h:132
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:238
bool string_to_unsigned_integer(const char *s, T &value)
Converts a string to a unsigned integer value.
Definition: string.h:445
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:175
bool from_string(const char *s, T &value)
Converts a C string to a typed value.
Definition: string.h:332
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:544
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 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:561
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:256
bool to_bool(const std::string &s)
Converts a string to a boolean.
Definition: string.h:595
bool string_to_signed_integer(const char *s, T &value)
Converts a string to a signed integer value.
Definition: string.h:375
double to_double(const std::string &s)
Converts a string to a double.
Definition: string.h:578