xref: /aosp_15_r20/external/armnn/include/armnn/utility/StringUtils.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2020 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <iostream>
9 #include <sstream>
10 #include <algorithm>
11 #include <vector>
12 #include <armnn/Exceptions.hpp>
13 
14 namespace armnn
15 {
16 
17 namespace stringUtils
18 {
19 
20 /// Function to take a string and a list of delimiters and split the string into tokens based on those delimiters
21 /// This assumes that tokens are also to be split by newlines
22 /// Enabling tokenCompression merges adjacent delimiters together, preventing empty tokens
StringTokenizer(const std::string & str,const char * delimiters,bool tokenCompression=true)23 inline std::vector<std::string> StringTokenizer(const std::string& str,
24                                                 const char* delimiters,
25                                                 bool tokenCompression = true)
26 {
27     std::stringstream stringStream(str);
28     std::string line;
29     std::vector<std::string> tokenVector;
30     while (std::getline(stringStream, line))
31     {
32         std::size_t prev = 0;
33         std::size_t pos;
34         while ((pos = line.find_first_of(delimiters, prev)) != std::string::npos)
35         {
36             // Ignore adjacent tokens
37             if (pos > prev)
38             {
39                 tokenVector.push_back(line.substr(prev, pos - prev));
40             }
41             // Unless token compression is disabled
42             else if (!tokenCompression)
43             {
44                 tokenVector.push_back(line.substr(prev, pos - prev));
45             }
46             prev = pos + 1;
47         }
48         if (prev < line.length())
49         {
50             tokenVector.push_back(line.substr(prev, std::string::npos));
51         }
52     }
53     return tokenVector;
54 }
55 
56 // Set of 3 utility functions for trimming std::strings
57 // Default char set for common whitespace characters
58 
59 ///
60 /// Trim from the start of a string
61 ///
StringStartTrim(std::string & str,const std::string & chars="\\t\\n\\v\\f\\r ")62 inline std::string& StringStartTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
63 {
64     str.erase(0, str.find_first_not_of(chars));
65     return str;
66 }
67 
68 ///
69 /// Trim for the end of a string
70 ///
StringEndTrim(std::string & str,const std::string & chars="\\t\\n\\v\\f\\r ")71 inline std::string& StringEndTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
72 {
73     str.erase(str.find_last_not_of(chars) + 1);
74     return str;
75 }
76 
77 ///
78 /// Trim from both the start and the end of a string
79 ///
StringTrim(std::string & str,const std::string & chars="\\t\\n\\v\\f\\r ")80 inline std::string& StringTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
81 {
82     return StringStartTrim(StringEndTrim(str, chars), chars);
83 }
84 
85 ///
86 /// Trim from both the start and the end of a string, returns a trimmed copy of the string
87 ///
StringTrimCopy(const std::string & str,const std::string & chars="\\t\\n\\v\\f\\r ")88 inline std::string StringTrimCopy(const std::string& str, const std::string& chars = "\t\n\v\f\r ")
89 {
90     std::string strCopy = str;
91     return StringStartTrim(StringEndTrim(strCopy, chars), chars);
92 }
93 
94 /// Takes a vector of strings and concatenates them together into one long std::string with an optional
95 /// seperator between each.
StringConcat(const std::vector<std::string> & strings,std::string seperator="")96 inline std::string StringConcat(const std::vector<std::string>& strings, std::string seperator = "")
97 {
98     std::stringstream ss;
99     for (auto string : strings)
100     {
101         ss << string << seperator;
102     }
103     return ss.str();
104 }
105 
106 ///
107 /// Iterates over a given str and replaces all instance of substring oldStr with newStr
108 ///
StringReplaceAll(std::string & str,const std::string & oldStr,const std::string & newStr)109 inline void StringReplaceAll(std::string& str,
110                              const std::string& oldStr,
111                              const std::string& newStr)
112 {
113     std::string::size_type pos = 0u;
114     while ((pos = str.find(oldStr, pos)) != std::string::npos)
115     {
116         str.replace(pos, oldStr.length(), newStr);
117         pos += newStr.length();
118     }
119 }
120 
121 ///
122 /// Converts a string to bool.
123 /// Accepts "true", "false" (case-insensitive) and numbers, 1 (true) or 0 (false).
124 ///
125 /// \param s               String to convert to bool
126 /// \param throw_on_error  Bool variable to suppress error if conversion failed (Will return false in that case)
127 /// \return bool value
128 ///
StringToBool(const std::string & s,bool throw_on_error=true)129 inline bool StringToBool(const std::string& s, bool throw_on_error = true)
130 {
131     // in case of failure to convert returns false
132     auto result = false;
133 
134     // isstringstream fails if parsing didn't work
135     std::istringstream is(s);
136 
137     // try integer conversion first. For the case s is a number
138     is >> result;
139 
140     if (is.fail())
141     {
142         // transform to lower case to make case-insensitive
143         std::string s_lower = s;
144         std::transform(s_lower.begin(),
145                        s_lower.end(),
146                        s_lower.begin(),
147                        [](unsigned char c){ return std::tolower(c); });
148         is.str(s_lower);
149         // try boolean -> s="false" or "true"
150         is.clear();
151         is >> std::boolalpha >> result;
152     }
153 
154     if (is.fail() && throw_on_error)
155     {
156         throw armnn::InvalidArgumentException(s + " is not convertable to bool");
157     }
158 
159     return result;
160 }
161 
162 } // namespace stringUtils
163 
164 } // namespace armnn