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 
15 #include <optional>
16 #include <string>
17 #include <type_traits>
18 
19 // These check that the string is indeed a valid number,
20 // and fail an assertion otherwise.
21 // We use those for data types that C++11's std::stoi etc. do not
22 // cover.
23 unsigned safe_string2unsigned(const std::string &str, int base=10);
24 std::size_t safe_string2size_t(const std::string &str, int base=10);
25 
26 // The below mimic C's atoi/atol: any errors are silently ignored.
27 // They are meant to replace atoi/atol.
28 int unsafe_string2int(const std::string &str, int base=10);
29 unsigned unsafe_string2unsigned(const std::string &str, int base=10);
30 std::size_t unsafe_string2size_t(const std::string &str, int base=10);
31 
32 // Same for atoll
33 long long int unsafe_string2signedlonglong(const std::string &str, int base=10);
34 long long unsigned int unsafe_string2unsignedlonglong(
35  const std::string &str, int base=10);
36 
37 // if we had a `resultt` รก la Boost.Outcome (https://ned14.github.io/outcome/)
38 // we could also return the reason why the conversion failed
39 
42 std::optional<int> string2optional_int(const std::string &, int base = 10);
43 
47 std::optional<unsigned>
48 string2optional_unsigned(const std::string &, int base = 10);
49 
53 std::optional<std::size_t>
54 string2optional_size_t(const std::string &, int base = 10);
55 
57 template <typename T>
58 auto string2optional_base(const std::string &str, int base) ->
59  typename std::enable_if<std::is_signed<T>::value, long long>::type
60 {
61  static_assert(
62  sizeof(T) <= sizeof(long long),
63  "this works under the assumption that long long is the largest type we try "
64  "to convert");
65  return std::stoll(str, nullptr, base);
66 }
67 
69 template <typename T>
70 auto string2optional_base(const std::string &str, int base) ->
71  typename std::enable_if<std::is_unsigned<T>::value, unsigned long long>::type
72 {
73  static_assert(
74  sizeof(T) <= sizeof(unsigned long long),
75  "this works under the assumption that long long is the largest type we try "
76  "to convert");
77  if(str.find('-') != std::string::npos)
78  {
79  throw std::out_of_range{
80  "unsigned conversion behaves a bit strangely with negative values, "
81  "therefore we disable it"};
82  }
83  return std::stoull(str, nullptr, base);
84 }
85 
88 template <typename do_conversiont>
89 auto wrap_string_conversion(do_conversiont do_conversion)
90  -> std::optional<decltype(do_conversion())>
91 {
92  try
93  {
94  return do_conversion();
95  }
96  catch(const std::invalid_argument &)
97  {
98  return std::nullopt;
99  }
100  catch(const std::out_of_range &)
101  {
102  return std::nullopt;
103  }
104 }
105 
110 template <typename T>
111 std::optional<T> string2optional(const std::string &str, int base = 10)
112 {
113  return wrap_string_conversion([&]() {
114  return narrow_or_throw_out_of_range<T>(string2optional_base<T>(str, base));
115  });
116 }
117 
118 #endif // CPROVER_UTIL_STRING2INT_H
std::optional< 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:65
long long int unsafe_string2signedlonglong(const std::string &str, int base=10)
Definition: string2int.cpp:45
unsigned unsafe_string2unsigned(const std::string &str, int base=10)
Definition: string2int.cpp:35
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:58
long long unsigned int unsafe_string2unsignedlonglong(const std::string &str, int base=10)
Definition: string2int.cpp:52
std::optional< 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
std::size_t safe_string2size_t(const std::string &str, int base=10)
Definition: string2int.cpp:23
unsigned safe_string2unsigned(const std::string &str, int base=10)
Definition: string2int.cpp:16
std::optional< 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:71
std::optional< 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:111
int unsafe_string2int(const std::string &str, int base=10)
Definition: string2int.cpp:30
std::size_t unsafe_string2size_t(const std::string &str, int base=10)
Definition: string2int.cpp:40
auto wrap_string_conversion(do_conversiont do_conversion) -> std::optional< decltype(do_conversion())>
attempt a given conversion, return nullopt if the conversion fails with out_of_range or invalid_argum...
Definition: string2int.h:89
invalid_command_line_argument_exceptiont invalid_argument(const std::string &option_name, const std::string &bad_argument, const mappingt &mapping)