1#pragma once
2
3#include <sstream>
4#include <stdexcept>
5#include <string>
6
7namespace c10 {
8
9// to_string, stoi and stod implementation for Android related stuff.
10// Note(jiayq): Do not use the CAFFE2_TESTONLY_FORCE_STD_STRING_TEST macro
11// outside testing code that lives under common_test.cc
12#if defined(__ANDROID__) || defined(CAFFE2_TESTONLY_FORCE_STD_STRING_TEST)
13#define CAFFE2_TESTONLY_WE_ARE_USING_CUSTOM_STRING_FUNCTIONS 1
14template <typename T>
15std::string to_string(T value) {
16 std::ostringstream os;
17 os << value;
18 return os.str();
19}
20
21inline int stoi(const std::string& str, std::size_t* pos = 0) {
22 std::stringstream ss;
23 int n = 0;
24 ss << str;
25 ss >> n;
26 if (ss.fail()) {
27 // To mimic `std::stoi` and to avoid including `Exception.h`, throw
28 // `std::invalid_argument`.
29 // We can't easily detect out-of-range, so we don't use `std::out_of_range`.
30 throw std::invalid_argument("Not an integer");
31 }
32 if (pos) {
33 if (ss.tellg() == std::streampos(-1)) {
34 *pos = str.size();
35 } else {
36 *pos = ss.tellg();
37 }
38 }
39 return n;
40}
41
42inline uint64_t stoull(const std::string& str) {
43 std::stringstream ss;
44 uint64_t n = 0;
45 ss << str;
46 ss >> n;
47 if (ss.fail()) {
48 // To mimic `std::stoull` and to avoid including `Exception.h`, throw
49 // `std::invalid_argument`.
50 // We can't easily detect out-of-range, so we don't use `std::out_of_range`.
51 throw std::invalid_argument("Not an unsigned 64-bit integer");
52 }
53 return n;
54}
55
56inline double stod(const std::string& str, std::size_t* pos = 0) {
57 std::stringstream ss;
58 ss << str;
59 double val = 0;
60 ss >> val;
61 if (ss.fail()) {
62 // To mimic `std::stod` and to avoid including `Exception.h`, throw
63 // `std::invalid_argument`.
64 // We can't easily detect out-of-range, so we don't use `std::out_of_range`.
65 throw std::invalid_argument("Not a double-precision floating point number");
66 }
67 if (pos) {
68 if (ss.tellg() == std::streampos(-1)) {
69 *pos = str.size();
70 } else {
71 *pos = ss.tellg();
72 }
73 }
74 return val;
75}
76
77inline long long stoll(const std::string& str, std::size_t* pos = 0) {
78 // std::stoll doesn't exist in our Android environment, we need to implement
79 // it ourselves.
80 std::stringstream ss;
81 ss << str;
82 long long result = 0;
83 ss >> result;
84 if (ss.fail()) {
85 // To mimic `std::stoll` and to avoid including `Exception.h`, throw
86 // `std::invalid_argument`.
87 // We can't easily detect out-of-range, so we don't use `std::out_of_range`.
88 throw std::invalid_argument("Not a long long integer");
89 }
90 if (pos) {
91 if (ss.tellg() == std::streampos(-1)) {
92 *pos = str.size();
93 } else {
94 *pos = ss.tellg();
95 }
96 }
97 return result;
98}
99
100inline long long stoll(const std::string& str, size_t pos, int base) {
101 // std::stoll doesn't exist in our Android environment, we need to implement
102 // it ourselves.
103 std::stringstream ss;
104 if (str.size() > 0 && str.at(0) == '0') {
105 if (str.size() > 1 && (str.at(1) == 'x' || str.at(1) == 'X')) {
106 ss << std::hex << str;
107 } else {
108 ss << std::oct << str;
109 }
110 } else {
111 ss << str;
112 }
113 long long result = 0;
114 ss >> result;
115 if (ss.fail()) {
116 // To mimic `std::stoll` and to avoid including `Exception.h`, throw
117 // `std::invalid_argument`.
118 // We can't easily detect out-of-range, so we don't use `std::out_of_range`.
119 throw std::invalid_argument("Not a long long integer");
120 }
121 return result;
122}
123
124#else
125#define CAFFE2_TESTONLY_WE_ARE_USING_CUSTOM_STRING_FUNCTIONS 0
126using std::stod;
127using std::stoi;
128using std::stoll;
129using std::stoull;
130using std::to_string;
131#endif // defined(__ANDROID__) || defined(CAFFE2_FORCE_STD_STRING_FALLBACK_TEST)
132
133} // namespace c10
134
135#if defined(__ANDROID__) && __ANDROID_API__ < 21 && defined(__GLIBCXX__)
136#include <cstdlib>
137// std::strtoll isn't available on Android NDK platform < 21 when building
138// with libstdc++, so bring the global version into std.
139namespace std {
140using ::strtoll;
141}
142#endif
143