aboutsummaryrefslogtreecommitdiff
path: root/include/armnn/utility/StringUtils.hpp
blob: 172b1798c571c2fc2b90e91bdb1068757f1440db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//
// Copyright © 2020 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <armnn/Exceptions.hpp>

namespace armnn
{

namespace stringUtils
{

/// Function to take a string and a list of delimiters and split the string into tokens based on those delimiters
/// This assumes that tokens are also to be split by newlines
/// Enabling tokenCompression merges adjacent delimiters together, preventing empty tokens
inline std::vector<std::string> StringTokenizer(const std::string& str,
                                                const char* delimiters,
                                                bool tokenCompression = true)
{
    std::stringstream stringStream(str);
    std::string line;
    std::vector<std::string> tokenVector;
    while (std::getline(stringStream, line))
    {
        std::size_t prev = 0;
        std::size_t pos;
        while ((pos = line.find_first_of(delimiters, prev)) != std::string::npos)
        {
            // Ignore adjacent tokens
            if (pos > prev)
            {
                tokenVector.push_back(line.substr(prev, pos - prev));
            }
            // Unless token compression is disabled
            else if (!tokenCompression)
            {
                tokenVector.push_back(line.substr(prev, pos - prev));
            }
            prev = pos + 1;
        }
        if (prev < line.length())
        {
            tokenVector.push_back(line.substr(prev, std::string::npos));
        }
    }
    return tokenVector;
}

// Set of 3 utility functions for trimming std::strings
// Default char set for common whitespace characters

///
/// Trim from the start of a string
///
inline std::string& StringStartTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    str.erase(0, str.find_first_not_of(chars));
    return str;
}

///
/// Trim for the end of a string
///
inline std::string& StringEndTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    str.erase(str.find_last_not_of(chars) + 1);
    return str;
}

///
/// Trim from both the start and the end of a string
///
inline std::string& StringTrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    return StringStartTrim(StringEndTrim(str, chars), chars);
}

///
/// Trim from both the start and the end of a string, returns a trimmed copy of the string
///
inline std::string StringTrimCopy(const std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    std::string strCopy = str;
    return StringStartTrim(StringEndTrim(strCopy, chars), chars);
}

/// Takes a vector of strings and concatenates them together into one long std::string with an optional
/// seperator between each.
inline std::string StringConcat(const std::vector<std::string>& strings, std::string seperator = "")
{
    std::stringstream ss;
    for (auto string : strings)
    {
        ss << string << seperator;
    }
    return ss.str();
}

///
/// Iterates over a given str and replaces all instance of substring oldStr with newStr
///
inline void StringReplaceAll(std::string& str,
                             const std::string& oldStr,
                             const std::string& newStr)
{
    std::string::size_type pos = 0u;
    while ((pos = str.find(oldStr, pos)) != std::string::npos)
    {
        str.replace(pos, oldStr.length(), newStr);
        pos += newStr.length();
    }
}

///
/// Converts a string to bool.
/// Accepts "true", "false" (case-insensitive) and numbers, 1 (true) or 0 (false).
///
/// \param s               String to convert to bool
/// \param throw_on_error  Bool variable to suppress error if conversion failed (Will return false in that case)
/// \return bool value
///
inline bool StringToBool(const std::string& s, bool throw_on_error = true)
{
    // in case of failure to convert returns false
    auto result = false;

    // isstringstream fails if parsing didn't work
    std::istringstream is(s);

    // try integer conversion first. For the case s is a number
    is >> result;

    if (is.fail())
    {
        // transform to lower case to make case-insensitive
        std::string s_lower = s;
        std::transform(s_lower.begin(),
                       s_lower.end(),
                       s_lower.begin(),
                       [](unsigned char c){ return std::tolower(c); });
        is.str(s_lower);
        // try boolean -> s="false" or "true"
        is.clear();
        is >> std::boolalpha >> result;
    }

    if (is.fail() && throw_on_error)
    {
        throw armnn::InvalidArgumentException(s + " is not convertable to bool");
    }

    return result;
}

} // namespace stringUtils

} // namespace armnn