PLSSVM - Parallel Least Squares Support Vector Machine  2.0.0
A Least Squares Support Vector Machine implementation using different backends.
string_conversion.hpp
Go to the documentation of this file.
1 
12 #ifndef PLSSVM_DETAIL_STRING_CONVERSION_HPP_
13 #define PLSSVM_DETAIL_STRING_CONVERSION_HPP_
14 #pragma once
15 
16 #include "plssvm/detail/arithmetic_type_name.hpp" // plssvm::detail::arithmetic_type_name
17 #include "plssvm/detail/string_utility.hpp" // plssvm::detail::{trim, trim_left, as_lower_case}
18 #include "plssvm/detail/type_traits.hpp" // PLSSVM_REQUIRES, plssvm::detail::remove_cvref_t
19 
20 #include "fast_float/fast_float.h" // fast_float::from_chars_result, fast_float::from_chars (floating point types)
21 #include "fmt/core.h" // fmt::format
22 
23 #include <charconv> // std::from_chars_result, std::from_chars (integral types)
24 #include <stdexcept> // std::runtime_error
25 #include <string> // std::string, std::stold
26 #include <string_view> // std::string_view
27 #include <system_error> // std:errc
28 #include <type_traits> // std::is_arithmetic_v, std::is_same_v, std::is_floating_point_v, std::is_integral_v
29 #include <vector> // std::vector
30 
31 namespace plssvm::detail {
32 
46 template <typename T, typename Exception = std::runtime_error, PLSSVM_REQUIRES((std::is_arithmetic_v<T> || std::is_same_v<remove_cvref_t<T>, std::string>) )>
47 [[nodiscard]] inline T convert_to(const std::string_view str) {
48  if constexpr (std::is_same_v<remove_cvref_t<T>, std::string>) {
49  // convert string_view to string
50  return std::string{ trim(str) };
51  } else if constexpr (std::is_same_v<remove_cvref_t<T>, bool>) {
52  const std::string lower_case_str = as_lower_case(trim(str));
53  // the string true
54  if (lower_case_str == "true") {
55  return true;
56  }
57  // the string false
58  if (lower_case_str == "false") {
59  return false;
60  }
61  // convert a number to its "long long" value and convert it to a bool: 0 -> false, otherwise true
62  return static_cast<bool>(convert_to<long long, Exception>(str));
63  } else if constexpr (std::is_same_v<remove_cvref_t<T>, char>) {
64  const std::string_view trimmed = trim(str);
65  if (trimmed.size() != 1) {
66  throw Exception{ fmt::format("Can't convert '{}' to a value of type char!", str) };
67  }
68  return trimmed.front();
69  } else if constexpr (std::is_same_v<remove_cvref_t<T>, long double>) {
70  return std::stold(std::string{ str });
71  } else {
72  // select conversion function depending on the provided type
73  const auto convert_from_chars = [](const std::string_view sv, auto &val) {
74  if constexpr (std::is_floating_point_v<T>) {
75  // convert the string to a floating point value
76  return fast_float::from_chars(sv.data(), sv.data() + sv.size(), val);
77  } else {
78  // convert the string to an integral value
79  return std::from_chars(sv.data(), sv.data() + sv.size(), val);
80  }
81  // unreachable, needed to silence a nvcc warning
82  // see also: https://stackoverflow.com/questions/64523302/cuda-missing-return-statement-at-end-of-non-void-function-in-constexpr-if-fun
83  return std::conditional_t<std::is_floating_point_v<T>, fast_float::from_chars_result, std::from_chars_result>{};
84  };
85 
86  // remove leading whitespaces
87  const std::string_view trimmed_str = trim_left(str);
88 
89  // convert string to value fo type T
90  T val;
91  auto res = convert_from_chars(trimmed_str, val);
92  if (res.ec != std::errc{}) {
93  throw Exception{ fmt::format("Can't convert '{}' to a value of type {}!", str, arithmetic_type_name<T>()) };
94  }
95  return val;
96  }
97  // unreachable, needed to silence a nvcc warning
98  // see also: https://stackoverflow.com/questions/64523302/cuda-missing-return-statement-at-end-of-non-void-function-in-constexpr-if-fun
99  return T{};
100 }
101 
109 template <typename T>
110 [[nodiscard]] inline T extract_first_integer_from_string(std::string_view str) {
111  const std::string_view::size_type n = str.find_first_of("0123456789");
112  if (n != std::string_view::npos) {
113  const std::string_view::size_type m = str.find_first_not_of("0123456789", n);
114  return convert_to<T>(str.substr(n, m != std::string_view::npos ? m - n : m));
115  }
116  throw std::runtime_error{ fmt::format("String \"{}\" doesn't contain any integer!", str) };
117 }
118 
126 template <typename T>
127 [[nodiscard]] inline std::vector<T> split_as(const std::string_view str, const char delim = ' ') {
128  std::vector<T> split_str;
129 
130  // if the input str is empty, return an empty vector
131  if (str.empty()) {
132  return split_str;
133  }
134 
135  std::string_view::size_type pos = 0;
136  std::string_view::size_type next = 0;
137  while (next != std::string_view::npos) {
138  next = str.find_first_of(delim, pos);
139  split_str.emplace_back(convert_to<T>(next == std::string_view::npos ? str.substr(pos) : str.substr(pos, next - pos)));
140  pos = next + 1;
141  }
142  return split_str;
143 }
144 
145 } // namespace plssvm::detail
146 
147 #endif // PLSSVM_DETAIL_STRING_CONVERSION_HPP_
Implements conversion functions from arithmetic types to their name as string representation.
Namespace containing implementation details. Should not directly be used by users.
Definition: csvm.hpp:27
std::vector< T > split_as(const std::string_view str, const char delim=' ')
Split the string str at the positions with delimiter delim and return the sub-strings converted to th...
Definition: string_conversion.hpp:127
T extract_first_integer_from_string(std::string_view str)
Extract the first integer from the given string str and converts it to T ignoring a potential sign.
Definition: string_conversion.hpp:110
T convert_to(const std::string_view str)
Converts the string str to a value of type T.
Definition: string_conversion.hpp:47
std::string_view trim(std::string_view str) noexcept
Returns a new std::string_view equal to str where all leading and trailing whitespaces are removed.
std::string_view trim_left(std::string_view str) noexcept
Returns a new std::string_view equal to str where all leading whitespaces are removed.
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Remove the topmost reference- and cv-qualifiers.
Definition: type_traits.hpp:46
std::string as_lower_case(std::string_view str)
Return a new string with the same content as str but all lower case.
Implements utility functions for string manipulation and querying.
Defines some generic type traits used in the PLSSVM library.