QMCPACK
ModernStringUtils.hpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2023 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 //
9 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_MODERNSTRINGUTILS_HPP
13 #define QMCPLUSPLUS_MODERNSTRINGUTILS_HPP
14 
15 #include <charconv>
16 #include <stdexcept>
17 #include <string>
18 #include <string_view>
19 #include <sstream>
20 #include <type_traits>
21 #include <vector>
22 
23 namespace qmcplusplus
24 {
25 
26 /** @ingroup C++17 string utility functions
27  * @{
28  */
29 /** take string_view (or something that can be implicitly converted to one) and return lcase string.
30  * Don't call on anything but ASCII strings.
31  *
32  * According to en.cppreference.com std::tolower is only defined for usigned char and EOF. the std::tolower conversion
33  * is based on the _c_ locale which to makes it unclear on what might happen to char > 127.
34  * * For tags, and keywords where we define explicitly define they are ASCII encoded and this is fine.
35  * * For other XML derived text this should never be used since we should assume that to be UTF-8 encoded.
36  */
37 std::string lowerCase(const std::string_view s);
38 
39 /** prevent clash with string_utils.h */
40 namespace modernstrutil
41 {
42 /** return string_view tokens */
43 std::vector<std::string_view> split(const std::string_view s, const std::string_view delimiters);
44 /** remove white space from each beginning and end of string_view */
45 std::string_view strip(const std::string_view s);
46 } // namespace modernstrutil
47 
48 /** alternate to string2real
49  * calls c++ string to real conversion based on T's precision template<typename T>
50  */
51 template<typename T>
52 inline T string2Real(const std::string_view svalue)
53 {
54  static_assert(std::is_floating_point_v<T>);
55  T result;
56 // full support for floating point from char not present until stdlibc++ aligned with gcc11
57 // there is still not from_char for floats as of libc++ 15
58 #if _GLIBCXX_RELEASE > 10
59  auto [prt, ec] = std::from_chars(svalue.data(), svalue.data() + svalue.size(), result, std::chars_format::general);
60  if (ec != std::errc())
61  throw std::runtime_error("Could not convert from string to real value");
62 #else
63  // atof must be given a null terminated string, string_view is not guaranteed to have a null terminator.
64  std::string str_value(svalue);
65  result = static_cast<T>(atof(str_value.c_str()));
66 #endif
67  return result;
68 }
69 
70 /** alternate to string2real
71  * calls c++ string to real conversion based on T's precision template<typename T>
72  */
73 template<typename T>
74 inline T string2Int(const std::string_view svalue)
75 {
76  static_assert(std::is_integral_v<T>);
77  // full support for floating point from char not present until stdlibc++ aligned with gcc11
78  // there is still not from_char for floats as of libc++ 15
79  T result{};
80 #if _GLIBCXX_RELEASE > 10
81  auto [prt, ec] = std::from_chars(svalue.data(), svalue.data() + svalue.size(), result);
82  // std::errc() represents success or a value of 0 with respect to errc's error enumeration.
83  if (ec != std::errc())
84  {
85  if (ec == std::errc::result_out_of_range)
86  throw std::range_error("Value out of range for integral type parameter of string2Int");
87  else
88  {
89  std::ostringstream msg;
90  msg << "Could not convert from string " << std::string(svalue) << " to int!";
91  throw std::runtime_error(msg.str());
92  }
93  }
94 #else
95  // atof must be given a null terminated string, string_view is not guaranteed to have a null terminator.
96  std::string str_value(svalue);
97  if constexpr (std::is_same_v<T, int>)
98  result = atoi(str_value.c_str());
99  else if constexpr (std::is_same_v<T, long>)
100  result = atol(str_value.c_str());
101  else if constexpr (std::is_same_v<T, long long>)
102  result = atol(str_value.c_str());
103  else
104  throw std::runtime_error("unsupported type for string to integral type conversion with pre v.10 stdlibc++!");
105 #endif
106  return result;
107 }
108 /** @} */
109 
110 } // namespace qmcplusplus
111 
112 #endif
T string2Int(const std::string_view svalue)
alternate to string2real calls c++ string to real conversion based on T&#39;s precision template<typename...
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
std::string_view strip(const string_view s)
T string2Real(const std::string_view svalue)
alternate to string2real calls c++ string to real conversion based on T&#39;s precision template<typename...
std::string lowerCase(const std::string_view s)
++17
std::vector< std::string_view > split(const string_view s, const string_view delimiters)