1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #ifndef TENSORFLOW_LITE_TESTING_SPLIT_H_
16 #define TENSORFLOW_LITE_TESTING_SPLIT_H_
17
18 #include <algorithm>
19 #include <complex>
20 #include <cstdlib>
21 #include <iostream>
22 #include <string>
23 #include <utility>
24 #include <vector>
25
26 #include "tensorflow/lite/string_type.h"
27
28 namespace tflite {
29 namespace testing {
30
31 // Splits a string based on the given delimiter string. Each pair in the
32 // returned vector has the start and past-the-end positions for each of the
33 // parts of the original string. Empty fields are not represented in the
34 // output.
35 std::vector<std::pair<size_t, size_t>> SplitToPos(const string& s,
36 const string& delimiter);
37
38 // Splits the given string and converts each part to the given T.
39 template <typename T>
40 std::vector<T> Split(const string& s, const string& delimiter);
41
42 template <>
Split(const string & s,const string & delimiter)43 inline std::vector<string> Split(const string& s, const string& delimiter) {
44 std::vector<string> fields;
45 for (const auto& p : SplitToPos(s, delimiter)) {
46 fields.push_back(s.substr(p.first, p.second - p.first));
47 }
48 return fields;
49 }
50
51 template <>
Split(const string & s,const string & delimiter)52 inline std::vector<int> Split(const string& s, const string& delimiter) {
53 std::vector<int> fields;
54 for (const auto& p : SplitToPos(s, delimiter)) {
55 // NOLINTNEXTLINE(runtime/deprecated_fn)
56 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
57 }
58 return fields;
59 }
60
61 template <>
Split(const string & s,const string & delimiter)62 inline std::vector<uint32_t> Split(const string& s, const string& delimiter) {
63 std::vector<uint32_t> fields;
64 for (const auto& p : SplitToPos(s, delimiter)) {
65 // NOLINTNEXTLINE(runtime/deprecated_fn)
66 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
67 }
68 return fields;
69 }
70
71 template <>
Split(const string & s,const string & delimiter)72 inline std::vector<int64_t> Split(const string& s, const string& delimiter) {
73 std::vector<int64_t> fields;
74 for (const auto& p : SplitToPos(s, delimiter)) {
75 // NOLINTNEXTLINE(runtime/deprecated_fn)
76 fields.push_back(strtoll(s.data() + p.first, nullptr, 10));
77 }
78 return fields;
79 }
80
81 template <>
Split(const string & s,const string & delimiter)82 inline std::vector<uint64_t> Split(const string& s, const string& delimiter) {
83 std::vector<uint64_t> fields;
84 for (const auto& p : SplitToPos(s, delimiter)) {
85 // NOLINTNEXTLINE(runtime/deprecated_fn)
86 fields.push_back(strtoull(s.data() + p.first, nullptr, 10));
87 }
88 return fields;
89 }
90
91 template <>
Split(const string & s,const string & delimiter)92 inline std::vector<float> Split(const string& s, const string& delimiter) {
93 std::vector<float> fields;
94 for (const auto& p : SplitToPos(s, delimiter)) {
95 fields.push_back(strtod(s.data() + p.first, nullptr));
96 }
97 return fields;
98 }
99
100 template <>
Split(const string & s,const string & delimiter)101 inline std::vector<double> Split(const string& s, const string& delimiter) {
102 std::vector<double> fields;
103 for (const auto& p : SplitToPos(s, delimiter)) {
104 fields.push_back(strtod(s.data() + p.first, nullptr));
105 }
106 return fields;
107 }
108
109 template <>
Split(const string & s,const string & delimiter)110 inline std::vector<uint8_t> Split(const string& s, const string& delimiter) {
111 std::vector<uint8_t> fields;
112 for (const auto& p : SplitToPos(s, delimiter)) {
113 // NOLINTNEXTLINE(runtime/deprecated_fn)
114 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
115 }
116 return fields;
117 }
118
119 template <>
Split(const string & s,const string & delimiter)120 inline std::vector<int8_t> Split(const string& s, const string& delimiter) {
121 std::vector<int8_t> fields;
122 for (const auto& p : SplitToPos(s, delimiter)) {
123 // NOLINTNEXTLINE(runtime/deprecated_fn)
124 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
125 }
126 return fields;
127 }
128
129 template <>
Split(const string & s,const string & delimiter)130 inline std::vector<int16_t> Split(const string& s, const string& delimiter) {
131 std::vector<int16_t> fields;
132 for (const auto& p : SplitToPos(s, delimiter)) {
133 // NOLINTNEXTLINE(runtime/deprecated_fn)
134 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
135 }
136 return fields;
137 }
138
139 template <>
Split(const string & s,const string & delimiter)140 inline std::vector<uint16_t> Split(const string& s, const string& delimiter) {
141 std::vector<uint16_t> fields;
142 for (const auto& p : SplitToPos(s, delimiter)) {
143 // NOLINTNEXTLINE(runtime/deprecated_fn)
144 fields.push_back(strtol(s.data() + p.first, nullptr, 10));
145 }
146 return fields;
147 }
148
149 template <>
Split(const string & s,const string & delimiter)150 inline std::vector<bool> Split(const string& s, const string& delimiter) {
151 std::vector<bool> fields;
152 for (const auto& p : SplitToPos(s, delimiter)) {
153 // NOLINTNEXTLINE(runtime/deprecated_fn)
154 bool val = static_cast<bool>(strtol(s.data() + p.first, nullptr, 10));
155 fields.push_back(val);
156 }
157 return fields;
158 }
159
160 template <>
Split(const string & s,const string & delimiter)161 inline std::vector<std::complex<float>> Split(const string& s,
162 const string& delimiter) {
163 std::vector<std::complex<float>> fields;
164 for (const auto& p : SplitToPos(s, delimiter)) {
165 std::string sc = s.substr(p.first, p.second - p.first);
166 std::string::size_type sz_real, sz_img;
167 float real = std::stof(sc, &sz_real);
168 float img = std::stof(sc.substr(sz_real), &sz_img);
169 if (sz_real + sz_img + 1 != sc.length()) {
170 std::cerr << "There were errors in parsing string, " << sc
171 << ", to complex value." << std::endl;
172 return fields;
173 }
174 std::complex<float> c(real, img);
175 fields.push_back(c);
176 }
177 return fields;
178 }
179
180 template <>
Split(const string & s,const string & delimiter)181 inline std::vector<std::complex<double>> Split(const string& s,
182 const string& delimiter) {
183 std::vector<std::complex<double>> fields;
184 for (const auto& p : SplitToPos(s, delimiter)) {
185 std::string sc = s.substr(p.first, p.second - p.first);
186 std::string::size_type sz_real, sz_img;
187 double real = std::stod(sc, &sz_real);
188 double img = std::stod(sc.substr(sz_real), &sz_img);
189 if (sz_real + sz_img + 1 != sc.length()) {
190 std::cerr << "There were errors in parsing string, " << sc
191 << ", to complex value." << std::endl;
192 return fields;
193 }
194 std::complex<double> c(real, img);
195 fields.push_back(c);
196 }
197 return fields;
198 }
199
200 } // namespace testing
201 } // namespace tflite
202
203 #endif // TENSORFLOW_LITE_TESTING_SPLIT_H_
204