USRP Hardware Driver and Device Manual  Version: 4.11.0.0-0-g0d7ed3b1
UHD and USRP Manual
cast.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2014-2015 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 // Copyright 2019 Ettus Research, a National Instruments Brand
5 //
6 // SPDX-License-Identifier: GPL-3.0-or-later
7 //
8 
9 #pragma once
10 
11 #include <uhd/config.hpp>
12 #include <uhd/exception.hpp>
13 #include <type_traits>
14 #include <complex>
15 #include <cstdint>
16 #include <iomanip>
17 #include <ios>
18 #include <limits>
19 #include <locale>
20 #include <sstream>
21 #include <string>
22 
23 namespace uhd { namespace cast {
30 template <typename T>
31 inline T hexstr_cast(const std::string& in)
32 {
33  T x;
34  std::stringstream ss;
35  ss << std::hex << in;
36  ss >> x;
37  return x;
38 }
39 
48 template <typename T>
49 inline T fromstr_cast(const std::string& in)
50 {
51  T x;
52  std::istringstream is(in);
53  is >> std::setbase(0) >> x;
54  return x;
55 }
56 
69 template <typename data_t>
70 data_t from_str(const std::string& val)
71 {
72  if constexpr (
73  (std::is_same_v<data_t,
74  size_t> || std::is_same_v<data_t, unsigned long> || std::is_same_v<data_t, unsigned long long>)&&!std::
75  is_same_v<data_t, uint32_t> && !std::is_same_v<data_t, uint64_t>) {
76  try {
77  if (!val.empty() && val[0] == '-') {
78  throw std::out_of_range("negative value for unsigned type");
79  }
80  size_t pos;
81  unsigned long long tmp = std::stoull(val, &pos);
82  if (pos != val.length()) {
83  throw std::invalid_argument("trailing characters");
84  }
85  if (tmp > std::numeric_limits<data_t>::max()) {
86  throw std::out_of_range("value out of range");
87  }
88  return static_cast<data_t>(tmp);
89  } catch (std::invalid_argument&) {
90  throw uhd::runtime_error(
91  std::string("Cannot convert `") + val + "' to numeric type!");
92  } catch (std::out_of_range&) {
93  throw uhd::runtime_error(
94  std::string("Cannot convert `") + val + "' to numeric type!");
95  }
96  } else {
97  throw uhd::runtime_error("Cannot convert from string!");
98  }
99 }
100 
101 // Specializations of `uhd::cast::from_str()` for supported data types
102 
109 template <>
110 UHD_API bool from_str(const std::string& val);
111 
113 template <>
114 UHD_API double from_str(const std::string& val);
115 
117 template <>
118 UHD_API int from_str(const std::string& val);
119 
121 template <>
122 UHD_API uint8_t from_str(const std::string& val);
123 
125 template <>
126 UHD_API uint16_t from_str(const std::string& val);
127 
129 template <>
130 UHD_API uint32_t from_str(const std::string& val);
131 
133 template <>
134 UHD_API uint64_t from_str(const std::string& val);
135 
137 template <>
138 inline UHD_API std::string from_str(const std::string& val)
139 {
140  return val;
141 }
142 
144 UHD_API std::string to_ordinal_string(int val);
145 
153 // Type trait to detect if a type has a to_string() method
154 namespace detail {
155 template <typename T>
157  -> decltype(std::declval<T>().to_string(), std::true_type{});
158 template <typename T>
159 auto has_to_string_method_impl(...) -> std::false_type;
160 template <typename T>
161 using has_to_string_method = decltype(has_to_string_method_impl<T>(0));
162 } // namespace detail
163 
172 template <typename T>
173 auto to_str(const T& val) -> std::enable_if_t<
174  std::is_arithmetic_v<
175  T> && !std::is_floating_point_v<T> && !std::is_same_v<T, int8_t> && !std::is_same_v<T, uint8_t> && !std::is_enum_v<T> && !detail::has_to_string_method<T>::value,
176  decltype(std::to_string(val))>
177 {
178  return std::to_string(val);
179 }
180 
185 template <typename T>
186 auto to_str(const T& val) -> std::enable_if_t<std::is_enum_v<T>, std::string>
187 {
188  return std::to_string(static_cast<std::underlying_type_t<T>>(val));
189 }
190 
196 template <typename T>
197 auto to_str(const T& val) -> std::enable_if_t<
198  std::is_floating_point_v<T> && !detail::has_to_string_method<T>::value,
199  std::string>
200 {
201  std::ostringstream oss;
202  oss.imbue(std::locale::classic());
203  oss.precision(std::numeric_limits<T>::max_digits10);
204  oss << val;
205  return oss.str();
206 }
207 
208 // Special handling for int8_t and uint8_t since std::to_string treats them as chars
209 
211 template <typename T>
212 auto to_str(const T& val)
213  -> std::enable_if_t<std::is_same_v<T, int8_t> || std::is_same_v<T, signed char>,
214  std::string>
215 {
216  return std::to_string(static_cast<int>(val));
217 }
218 
220 template <typename T>
221 auto to_str(const T& val)
222  -> std::enable_if_t<std::is_same_v<T, uint8_t> || std::is_same_v<T, unsigned char>,
223  std::string>
224 {
225  return std::to_string(static_cast<unsigned int>(val));
226 }
227 
233 template <typename T>
234 std::string to_str(const std::complex<T>& val)
235 {
236  std::string real_str = to_str(val.real());
237  T imag_val = val.imag();
238 
239  if (imag_val >= 0) {
240  return real_str + "+j" + to_str(imag_val);
241  } else {
242  return real_str + "-j" + to_str(-imag_val);
243  }
244 }
245 
251 template <typename T>
252 auto to_str(const T& val)
253  -> std::enable_if_t<std::is_convertible_v<decltype(val.to_string()), std::string>,
254  std::string>
255 {
256  return val.to_string();
257 }
258 
260 inline std::string to_str(const std::string& val)
261 {
262  return val;
263 }
264 
265 inline std::string to_str(const char* val)
266 {
267  return std::string(val);
268 }
269 
270 }} // namespace uhd::cast
#define UHD_API
Definition: config.h:87
decltype(has_to_string_method_impl< T >(0)) has_to_string_method
Definition: cast.hpp:161
auto has_to_string_method_impl(int) -> decltype(std::declval< T >().to_string(), std::true_type{})
T fromstr_cast(const std::string &in)
Convert hexadecimal, decimal, octal or other strings that support the >> operator into a value depend...
Definition: cast.hpp:49
T hexstr_cast(const std::string &in)
Convert a hexadecimal string into a value.
Definition: cast.hpp:31
auto to_str(const T &val) -> std::enable_if_t< std::is_arithmetic_v< T > &&!std::is_floating_point_v< T > &&!std::is_same_v< T, int8_t > &&!std::is_same_v< T, uint8_t > &&!std::is_enum_v< T > &&!detail::has_to_string_method< T >::value, decltype(std::to_string(val))>
SFINAE-based template for integer types that std::to_string can handle.
Definition: cast.hpp:173
data_t from_str(const std::string &val)
Generic cast-from-string function.
Definition: cast.hpp:70
UHD_API std::string to_ordinal_string(int val)
Create an ordinal string from a number.
Definition: build_info.hpp:12
Definition: exception.hpp:132