libfly  6.2.2
C++20 utility library for Linux, macOS, and Windows
converter.hpp
1 #pragma once
2 
3 #include "fly/fly.hpp"
4 
5 #include <charconv>
6 #include <cstdint>
7 #include <optional>
8 #include <string>
9 
10 namespace fly::detail {
11 
24 template <typename T>
25 struct Converter
26 {
27  static std::optional<T> convert(const std::string &value)
28  {
29  const char *begin = value.data();
30  const char *end = begin + value.size();
31 
32  T converted {};
33  auto result = std::from_chars(begin, end, converted);
34 
35  if ((result.ptr != end) || (result.ec != std::errc {}))
36  {
37  return std::nullopt;
38  }
39 
40  return converted;
41  }
42 };
43 
44 #if !defined(FLY_COMPILER_SUPPORTS_FP_CHARCONV)
45 
46 //==================================================================================================
47 template <>
48 struct Converter<float>
49 {
50  static std::optional<float> convert(const std::string &value)
51  {
52  std::size_t index = 0;
53  float result {};
54 
55  try
56  {
57  result = std::stof(value, &index);
58  }
59  catch (...)
60  {
61  return std::nullopt;
62  }
63 
64  if (index != value.length())
65  {
66  return std::nullopt;
67  }
68 
69  return result;
70  }
71 };
72 
73 //==================================================================================================
74 template <>
75 struct Converter<double>
76 {
77  static std::optional<double> convert(const std::string &value)
78  {
79  std::size_t index = 0;
80  double result {};
81 
82  try
83  {
84  result = std::stod(value, &index);
85  }
86  catch (...)
87  {
88  return std::nullopt;
89  }
90 
91  if (index != value.length())
92  {
93  return std::nullopt;
94  }
95 
96  return result;
97  }
98 };
99 
100 //==================================================================================================
101 template <>
102 struct Converter<long double>
103 {
104  static std::optional<long double> convert(const std::string &value)
105  {
106  std::size_t index = 0;
107  long double result {};
108 
109  try
110  {
111  result = std::stold(value, &index);
112  }
113  catch (...)
114  {
115  return std::nullopt;
116  }
117 
118  if (index != value.length())
119  {
120  return std::nullopt;
121  }
122 
123  return result;
124  }
125 };
126 
127 #endif
128 
129 } // namespace fly::detail
Definition: converter.hpp:26