/src/log4cplus/include/log4cplus/helpers/stringhelper.h
Line | Count | Source |
1 | | // -*- C++ -*- |
2 | | // Module: Log4CPLUS |
3 | | // File: stringhelper.h |
4 | | // Created: 3/2003 |
5 | | // Author: Tad E. Smith |
6 | | // |
7 | | // |
8 | | // Copyright 2003-2017 Tad E. Smith |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
11 | | // you may not use this file except in compliance with the License. |
12 | | // You may obtain a copy of the License at |
13 | | // |
14 | | // http://www.apache.org/licenses/LICENSE-2.0 |
15 | | // |
16 | | // Unless required by applicable law or agreed to in writing, software |
17 | | // distributed under the License is distributed on an "AS IS" BASIS, |
18 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
19 | | // See the License for the specific language governing permissions and |
20 | | // limitations under the License. |
21 | | |
22 | | /** @file */ |
23 | | |
24 | | #ifndef LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ |
25 | | #define LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ |
26 | | |
27 | | #include <log4cplus/config.hxx> |
28 | | |
29 | | #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) |
30 | | #pragma once |
31 | | #endif |
32 | | |
33 | | #include <log4cplus/tstring.h> |
34 | | |
35 | | #include <algorithm> |
36 | | #include <limits> |
37 | | |
38 | | |
39 | | namespace log4cplus { |
40 | | namespace helpers { |
41 | | |
42 | | /** |
43 | | * Returns <code>s</code> in upper case. |
44 | | */ |
45 | | LOG4CPLUS_EXPORT log4cplus::tstring toUpper(const log4cplus::tstring& s); |
46 | | LOG4CPLUS_EXPORT tchar toUpper(tchar); |
47 | | |
48 | | |
49 | | /** |
50 | | * Returns <code>s</code> in lower case. |
51 | | */ |
52 | | LOG4CPLUS_EXPORT log4cplus::tstring toLower(const log4cplus::tstring& s); |
53 | | LOG4CPLUS_EXPORT tchar toLower(tchar); |
54 | | |
55 | | |
56 | | /** |
57 | | * Tokenize <code>s</code> using <code>c</code> as the delimiter and |
58 | | * put the resulting tokens in <code>_result</code>. If |
59 | | * <code>collapseTokens</code> is false, multiple adjacent delimiters |
60 | | * will result in zero length tokens. |
61 | | * |
62 | | * <b>Example:</b> |
63 | | * <pre> |
64 | | * string s = // Set string with '.' as delimiters |
65 | | * list<log4cplus::tstring> tokens; |
66 | | * tokenize(s, '.', back_insert_iterator<list<string> >(tokens)); |
67 | | * </pre> |
68 | | */ |
69 | | template <class StringType, class OutputIter> |
70 | | inline |
71 | | void |
72 | | tokenize(const StringType& s, typename StringType::value_type c, |
73 | | OutputIter result, bool collapseTokens = true) |
74 | 120k | { |
75 | 120k | typedef typename StringType::size_type size_type; |
76 | 120k | size_type const slen = s.length(); |
77 | 120k | size_type first = 0; |
78 | 120k | size_type i = 0; |
79 | 1.56M | for (i=0; i < slen; ++i) |
80 | 1.44M | { |
81 | 1.44M | if (s[i] == c) |
82 | 120k | { |
83 | 120k | *result = StringType (s, first, i - first); |
84 | 120k | ++result; |
85 | 120k | if (collapseTokens) |
86 | 120k | while (i+1 < slen && s[i+1] == c) |
87 | 0 | ++i; |
88 | 120k | first = i + 1; |
89 | 120k | } |
90 | 1.44M | } |
91 | 120k | if (first != i) |
92 | 120k | *result = StringType (s, first, i - first); |
93 | 0 | else if (! collapseTokens && first == i) |
94 | 0 | *result = StringType (); |
95 | 120k | } |
96 | | |
97 | | |
98 | | template <typename intType, typename stringType, bool isSigned> |
99 | | struct ConvertIntegerToStringHelper; |
100 | | |
101 | | |
102 | | template <typename intType, typename charType> |
103 | | struct ConvertIntegerToStringHelper<intType, charType, true> |
104 | | { |
105 | | static inline |
106 | | void |
107 | | step1 (charType * & it, intType & value) |
108 | 0 | { |
109 | | // The sign of the result of the modulo operator is |
110 | | // implementation defined. That's why we work with |
111 | | // positive counterpart instead. Also, in twos |
112 | | // complement arithmetic the smallest negative number |
113 | | // does not have positive counterpart; the range is |
114 | | // asymetric. That's why we handle the case of value |
115 | | // == min() specially here. |
116 | 0 | if (LOG4CPLUS_UNLIKELY ( |
117 | 0 | value == (std::numeric_limits<intType>::min) ())) |
118 | 0 | { |
119 | 0 | intType const r = value / 10; |
120 | 0 | intType const a = (-r) * 10; |
121 | 0 | intType const mod = -(a + value); |
122 | 0 | value = -r; |
123 | |
|
124 | 0 | *(it - 1) |
125 | 0 | = static_cast<charType>(LOG4CPLUS_TEXT('0') + mod); |
126 | 0 | --it; |
127 | 0 | } |
128 | 0 | else |
129 | 0 | value = -value; |
130 | 0 | } Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<int, char, true>::step1(char*&, int&) Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<long, char, true>::step1(char*&, long&) |
131 | | |
132 | | static |
133 | | bool |
134 | | is_negative (intType val) |
135 | 1.12M | { |
136 | 1.12M | return val < 0; |
137 | 1.12M | } log4cplus::helpers::ConvertIntegerToStringHelper<int, char, true>::is_negative(int) Line | Count | Source | 135 | 561k | { | 136 | 561k | return val < 0; | 137 | 561k | } |
log4cplus::helpers::ConvertIntegerToStringHelper<long, char, true>::is_negative(long) Line | Count | Source | 135 | 560k | { | 136 | 560k | return val < 0; | 137 | 560k | } |
|
138 | | }; |
139 | | |
140 | | |
141 | | template <typename intType, typename charType> |
142 | | struct ConvertIntegerToStringHelper<intType, charType, false> |
143 | | { |
144 | | static inline |
145 | | void |
146 | | step1 (charType * &, intType &) |
147 | 0 | { |
148 | | // This will never be called for unsigned types. |
149 | 0 | } Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<unsigned int, char, false>::step1(char*&, unsigned int&) Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<unsigned short, char, false>::step1(char*&, unsigned short&) Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<unsigned long, char, false>::step1(char*&, unsigned long&) |
150 | | |
151 | | static |
152 | | bool |
153 | | is_negative (intType) |
154 | 120k | { |
155 | 120k | return false; |
156 | 120k | } log4cplus::helpers::ConvertIntegerToStringHelper<unsigned int, char, false>::is_negative(unsigned int) Line | Count | Source | 154 | 120k | { | 155 | 120k | return false; | 156 | 120k | } |
Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<unsigned short, char, false>::is_negative(unsigned short) Unexecuted instantiation: log4cplus::helpers::ConvertIntegerToStringHelper<unsigned long, char, false>::is_negative(unsigned long) |
157 | | }; |
158 | | |
159 | | |
160 | | template <class stringType, class intType> |
161 | | inline |
162 | | void |
163 | | convertIntegerToString (stringType & str, intType value) |
164 | 1.24M | { |
165 | 1.24M | typedef std::numeric_limits<intType> intTypeLimits; |
166 | 1.24M | typedef typename stringType::value_type charType; |
167 | 1.24M | typedef ConvertIntegerToStringHelper<intType, charType, |
168 | 1.24M | intTypeLimits::is_signed> HelperType; |
169 | | |
170 | 1.24M | charType buffer[intTypeLimits::digits10 + 2]; |
171 | 1.24M | const std::size_t buffer_size |
172 | 1.24M | = sizeof (buffer) / sizeof (charType); |
173 | | |
174 | 1.24M | charType * it = &buffer[buffer_size]; |
175 | 1.24M | charType const * const buf_end = &buffer[buffer_size]; |
176 | | |
177 | 1.24M | if (LOG4CPLUS_UNLIKELY (value == 0)) |
178 | 521 | { |
179 | 521 | --it; |
180 | 521 | *it = LOG4CPLUS_TEXT('0'); |
181 | 521 | } |
182 | 1.24M | else |
183 | 1.24M | { |
184 | 1.24M | bool const negative = HelperType::is_negative (value); |
185 | 1.24M | if (negative) |
186 | 0 | HelperType::step1 (it, value); |
187 | | |
188 | 5.96M | for (; value != 0; --it) |
189 | 4.72M | { |
190 | 4.72M | intType mod = value % 10; |
191 | 4.72M | value = value / 10; |
192 | 4.72M | *(it - 1) = static_cast<charType>(LOG4CPLUS_TEXT('0') |
193 | 4.72M | + mod); |
194 | 4.72M | } |
195 | | |
196 | 1.24M | if (negative) |
197 | 0 | { |
198 | 0 | --it; |
199 | 0 | *it = LOG4CPLUS_TEXT('-'); |
200 | 0 | } |
201 | 1.24M | } |
202 | | |
203 | 1.24M | str.assign (static_cast<charType const *>(it), buf_end); |
204 | 1.24M | } void log4cplus::helpers::convertIntegerToString<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int) Line | Count | Source | 164 | 120k | { | 165 | 120k | typedef std::numeric_limits<intType> intTypeLimits; | 166 | 120k | typedef typename stringType::value_type charType; | 167 | 120k | typedef ConvertIntegerToStringHelper<intType, charType, | 168 | 120k | intTypeLimits::is_signed> HelperType; | 169 | | | 170 | 120k | charType buffer[intTypeLimits::digits10 + 2]; | 171 | 120k | const std::size_t buffer_size | 172 | 120k | = sizeof (buffer) / sizeof (charType); | 173 | | | 174 | 120k | charType * it = &buffer[buffer_size]; | 175 | 120k | charType const * const buf_end = &buffer[buffer_size]; | 176 | | | 177 | 120k | if (LOG4CPLUS_UNLIKELY (value == 0)) | 178 | 0 | { | 179 | 0 | --it; | 180 | 0 | *it = LOG4CPLUS_TEXT('0'); | 181 | 0 | } | 182 | 120k | else | 183 | 120k | { | 184 | 120k | bool const negative = HelperType::is_negative (value); | 185 | 120k | if (negative) | 186 | 0 | HelperType::step1 (it, value); | 187 | | | 188 | 241k | for (; value != 0; --it) | 189 | 120k | { | 190 | 120k | intType mod = value % 10; | 191 | 120k | value = value / 10; | 192 | 120k | *(it - 1) = static_cast<charType>(LOG4CPLUS_TEXT('0') | 193 | 120k | + mod); | 194 | 120k | } | 195 | | | 196 | 120k | if (negative) | 197 | 0 | { | 198 | 0 | --it; | 199 | 0 | *it = LOG4CPLUS_TEXT('-'); | 200 | 0 | } | 201 | 120k | } | 202 | | | 203 | 120k | str.assign (static_cast<charType const *>(it), buf_end); | 204 | 120k | } |
void log4cplus::helpers::convertIntegerToString<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int) Line | Count | Source | 164 | 561k | { | 165 | 561k | typedef std::numeric_limits<intType> intTypeLimits; | 166 | 561k | typedef typename stringType::value_type charType; | 167 | 561k | typedef ConvertIntegerToStringHelper<intType, charType, | 168 | 561k | intTypeLimits::is_signed> HelperType; | 169 | | | 170 | 561k | charType buffer[intTypeLimits::digits10 + 2]; | 171 | 561k | const std::size_t buffer_size | 172 | 561k | = sizeof (buffer) / sizeof (charType); | 173 | | | 174 | 561k | charType * it = &buffer[buffer_size]; | 175 | 561k | charType const * const buf_end = &buffer[buffer_size]; | 176 | | | 177 | 561k | if (LOG4CPLUS_UNLIKELY (value == 0)) | 178 | 0 | { | 179 | 0 | --it; | 180 | 0 | *it = LOG4CPLUS_TEXT('0'); | 181 | 0 | } | 182 | 561k | else | 183 | 561k | { | 184 | 561k | bool const negative = HelperType::is_negative (value); | 185 | 561k | if (negative) | 186 | 0 | HelperType::step1 (it, value); | 187 | | | 188 | 3.53M | for (; value != 0; --it) | 189 | 2.97M | { | 190 | 2.97M | intType mod = value % 10; | 191 | 2.97M | value = value / 10; | 192 | 2.97M | *(it - 1) = static_cast<charType>(LOG4CPLUS_TEXT('0') | 193 | 2.97M | + mod); | 194 | 2.97M | } | 195 | | | 196 | 561k | if (negative) | 197 | 0 | { | 198 | 0 | --it; | 199 | 0 | *it = LOG4CPLUS_TEXT('-'); | 200 | 0 | } | 201 | 561k | } | 202 | | | 203 | 561k | str.assign (static_cast<charType const *>(it), buf_end); | 204 | 561k | } |
Unexecuted instantiation: void log4cplus::helpers::convertIntegerToString<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned short) Unexecuted instantiation: void log4cplus::helpers::convertIntegerToString<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long) void log4cplus::helpers::convertIntegerToString<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, long) Line | Count | Source | 164 | 561k | { | 165 | 561k | typedef std::numeric_limits<intType> intTypeLimits; | 166 | 561k | typedef typename stringType::value_type charType; | 167 | 561k | typedef ConvertIntegerToStringHelper<intType, charType, | 168 | 561k | intTypeLimits::is_signed> HelperType; | 169 | | | 170 | 561k | charType buffer[intTypeLimits::digits10 + 2]; | 171 | 561k | const std::size_t buffer_size | 172 | 561k | = sizeof (buffer) / sizeof (charType); | 173 | | | 174 | 561k | charType * it = &buffer[buffer_size]; | 175 | 561k | charType const * const buf_end = &buffer[buffer_size]; | 176 | | | 177 | 561k | if (LOG4CPLUS_UNLIKELY (value == 0)) | 178 | 521 | { | 179 | 521 | --it; | 180 | 521 | *it = LOG4CPLUS_TEXT('0'); | 181 | 521 | } | 182 | 560k | else | 183 | 560k | { | 184 | 560k | bool const negative = HelperType::is_negative (value); | 185 | 560k | if (negative) | 186 | 0 | HelperType::step1 (it, value); | 187 | | | 188 | 2.18M | for (; value != 0; --it) | 189 | 1.62M | { | 190 | 1.62M | intType mod = value % 10; | 191 | 1.62M | value = value / 10; | 192 | 1.62M | *(it - 1) = static_cast<charType>(LOG4CPLUS_TEXT('0') | 193 | 1.62M | + mod); | 194 | 1.62M | } | 195 | | | 196 | 560k | if (negative) | 197 | 0 | { | 198 | 0 | --it; | 199 | 0 | *it = LOG4CPLUS_TEXT('-'); | 200 | 0 | } | 201 | 560k | } | 202 | | | 203 | 561k | str.assign (static_cast<charType const *>(it), buf_end); | 204 | 561k | } |
|
205 | | |
206 | | |
207 | | template<class intType> |
208 | | inline |
209 | | tstring |
210 | | convertIntegerToString (intType value) |
211 | 120k | { |
212 | 120k | tstring result; |
213 | 120k | convertIntegerToString (result, value); |
214 | 120k | return result; |
215 | 120k | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > log4cplus::helpers::convertIntegerToString<unsigned int>(unsigned int) Line | Count | Source | 211 | 120k | { | 212 | 120k | tstring result; | 213 | 120k | convertIntegerToString (result, value); | 214 | 120k | return result; | 215 | 120k | } |
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > log4cplus::helpers::convertIntegerToString<int>(int) |
216 | | |
217 | | |
218 | | template<class intType> |
219 | | inline |
220 | | std::string |
221 | | convertIntegerToNarrowString (intType value) |
222 | 0 | { |
223 | 0 | std::string result; |
224 | 0 | convertIntegerToString (result, value); |
225 | 0 | return result; |
226 | 0 | } Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > log4cplus::helpers::convertIntegerToNarrowString<unsigned short>(unsigned short) Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > log4cplus::helpers::convertIntegerToNarrowString<unsigned long>(unsigned long) |
227 | | |
228 | | |
229 | | //! Join a list of items into a string. |
230 | | template <typename Iterator, typename Separator> |
231 | | inline |
232 | | void |
233 | | join_worker (tstring & result, Iterator & start, Iterator & last, |
234 | | Separator const & sep) |
235 | 0 | { |
236 | 0 | if (start != last) |
237 | 0 | result = *start++; |
238 | |
|
239 | 0 | for (; start != last; ++start) |
240 | 0 | { |
241 | 0 | result += sep; |
242 | 0 | result += *start; |
243 | 0 | } |
244 | 0 | } |
245 | | |
246 | | //! Join a list of items into a string. |
247 | | template <typename Iterator> |
248 | | inline |
249 | | void |
250 | | join (tstring & result, Iterator start, Iterator last, |
251 | | tstring const & sep) |
252 | 0 | { |
253 | 0 | join_worker (result, start, last, sep); |
254 | 0 | } |
255 | | |
256 | | //! Join a list of items into a string. |
257 | | template <typename Iterator> |
258 | | inline |
259 | | void |
260 | | join (tstring & result, Iterator start, Iterator last, |
261 | | tstring::value_type sep) |
262 | | { |
263 | | join_worker (result, start, last, sep); |
264 | | } |
265 | | |
266 | | |
267 | | } // namespace helpers |
268 | | |
269 | | } // namespace log4cplus |
270 | | |
271 | | #endif // LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ |