CBMC
string2int.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk
6 
7 \*******************************************************************/
8 
9 
10 #ifndef CPROVER_UTIL_STRING2INT_H
11 #define CPROVER_UTIL_STRING2INT_H
12 
13 #include "narrow.h"
14 #include "optional.h"
15 #include <string>
16 #include <type_traits>
17 
18 // These check that the string is indeed a valid number,
19 // and fail an assertion otherwise.
20 // We use those for data types that C++11's std::stoi etc. do not
21 // cover.
22 unsigned safe_string2unsigned(const std::string &str, int base=10);
23 std::size_t safe_string2size_t(const std::string &str, int base=10);
24 
25 // The below mimic C's atoi/atol: any errors are silently ignored.
26 // They are meant to replace atoi/atol.
27 int unsafe_string2int(const std::string &str, int base=10);
28 unsigned unsafe_string2unsigned(const std::string &str, int base=10);
29 std::size_t unsafe_string2size_t(const std::string &str, int base=10);
30 
31 // Same for atoll
32 long long int unsafe_string2signedlonglong(const std::string &str, int base=10);
33 long long unsigned int unsafe_string2unsignedlonglong(
34  const std::string &str, int base=10);
35 
36 // if we had a `resultt` รก la Boost.Outcome (https://ned14.github.io/outcome/)
37 // we could also return the reason why the conversion failed
38 
41 optionalt<int> string2optional_int(const std::string &, int base = 10);
42 
47 string2optional_unsigned(const std::string &, int base = 10);
48 
53 string2optional_size_t(const std::string &, int base = 10);
54 
56 template <typename T>
57 auto string2optional_base(const std::string &str, int base) ->
58  typename std::enable_if<std::is_signed<T>::value, long long>::type
59 {
60  static_assert(
61  sizeof(T) <= sizeof(long long),
62  "this works under the assumption that long long is the largest type we try "
63  "to convert");
64  return std::stoll(str, nullptr, base);
65 }
66 
68 template <typename T>
69 auto string2optional_base(const std::string &str, int base) ->
70  typename std::enable_if<std::is_unsigned<T>::value, unsigned long long>::type
71 {
72  static_assert(
73  sizeof(T) <= sizeof(unsigned long long),
74  "this works under the assumption that long long is the largest type we try "
75  "to convert");
76  if(str.find('-') != std::string::npos)
77  {
78  throw std::out_of_range{
79  "unsigned conversion behaves a bit strangely with negative values, "
80  "therefore we disable it"};
81  }
82  return std::stoull(str, nullptr, base);
83 }
84 
87 template <typename do_conversiont>
88 auto wrap_string_conversion(do_conversiont do_conversion)
89  -> optionalt<decltype(do_conversion())>
90 {
91  try
92  {
93  return do_conversion();
94  }
95  catch(const std::invalid_argument &)
96  {
97  return nullopt;
98  }
99  catch(const std::out_of_range &)
100  {
101  return nullopt;
102  }
103 }
104 
109 template <typename T>
110 optionalt<T> string2optional(const std::string &str, int base = 10)
111 {
112  return wrap_string_conversion([&]() {
113  return narrow_or_throw_out_of_range<T>(string2optional_base<T>(str, base));
114  });
115 }
116 
117 #endif // CPROVER_UTIL_STRING2INT_H
unsafe_string2unsigned
unsigned unsafe_string2unsigned(const std::string &str, int base=10)
Definition: string2int.cpp:35
optional.h
string2optional_unsigned
optionalt< unsigned > string2optional_unsigned(const std::string &, int base=10)
Convert string to unsigned similar to the stoul or stoull functions, return nullopt when the conversi...
Definition: string2int.cpp:64
invalid_argument
invalid_command_line_argument_exceptiont invalid_argument(const std::string &option_name, const std::string &bad_argument, const mappingt &mapping)
Definition: variable_sensitivity_configuration.cpp:121
unsafe_string2size_t
std::size_t unsafe_string2size_t(const std::string &str, int base=10)
Definition: string2int.cpp:40
string2optional_int
optionalt< int > string2optional_int(const std::string &, int base=10)
Convert string to integer as per stoi, but return nullopt when stoi would throw.
Definition: string2int.cpp:59
narrow.h
safe_string2unsigned
unsigned safe_string2unsigned(const std::string &str, int base=10)
Definition: string2int.cpp:16
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
unsafe_string2unsignedlonglong
long long unsigned int unsafe_string2unsignedlonglong(const std::string &str, int base=10)
Definition: string2int.cpp:52
wrap_string_conversion
auto wrap_string_conversion(do_conversiont do_conversion) -> optionalt< decltype(do_conversion())>
attempt a given conversion, return nullopt if the conversion fails with out_of_range or invalid_argum...
Definition: string2int.h:88
unsafe_string2int
int unsafe_string2int(const std::string &str, int base=10)
Definition: string2int.cpp:30
string2optional_base
auto string2optional_base(const std::string &str, int base) -> typename std::enable_if< std::is_signed< T >::value, long long >::type
convert string to signed long long if T is signed
Definition: string2int.h:57
safe_string2size_t
std::size_t safe_string2size_t(const std::string &str, int base=10)
Definition: string2int.cpp:23
string2optional_size_t
optionalt< std::size_t > string2optional_size_t(const std::string &, int base=10)
Convert string to size_t similar to the stoul or stoull functions, return nullopt when the conversion...
Definition: string2int.cpp:69
unsafe_string2signedlonglong
long long int unsafe_string2signedlonglong(const std::string &str, int base=10)
Definition: string2int.cpp:45
string2optional
optionalt< T > string2optional(const std::string &str, int base=10)
convert a string to an integer, given the base of the representation works with signed and unsigned i...
Definition: string2int.h:110