log4cplus 2.0.8
stringhelper.h
Go to the documentation of this file.
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
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
39namespace log4cplus {
40 namespace helpers {
41
47
48
54
55
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 {
75 typedef typename StringType::size_type size_type;
76 size_type const slen = s.length();
77 size_type first = 0;
78 size_type i = 0;
79 for (i=0; i < slen; ++i)
80 {
81 if (s[i] == c)
82 {
83 *result = StringType (s, first, i - first);
84 ++result;
85 if (collapseTokens)
86 while (i+1 < slen && s[i+1] == c)
87 ++i;
88 first = i + 1;
89 }
90 }
91 if (first != i)
92 *result = StringType (s, first, i - first);
93 else if (! collapseTokens && first == i)
94 *result = StringType ();
95 }
96
97
98 template <typename intType, typename stringType, bool isSigned>
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 {
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.
117 value == (std::numeric_limits<intType>::min) ()))
118 {
119 intType const r = value / 10;
120 intType const a = (-r) * 10;
121 intType const mod = -(a + value);
122 value = -r;
123
124 *(it - 1)
125 = static_cast<charType>(LOG4CPLUS_TEXT('0') + mod);
126 --it;
127 }
128 else
129 value = -value;
130 }
131
132 static
133 bool
134 is_negative (intType val)
135 {
136 return val < 0;
137 }
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 {
148 // This will never be called for unsigned types.
149 }
150
151 static
152 bool
153 is_negative (intType)
154 {
155 return false;
156 }
157 };
158
159
160 template <class stringType, class intType>
161 inline
162 void
163 convertIntegerToString (stringType & str, intType value)
164 {
165 typedef std::numeric_limits<intType> intTypeLimits;
166 typedef typename stringType::value_type charType;
167 typedef ConvertIntegerToStringHelper<intType, charType,
168 intTypeLimits::is_signed> HelperType;
169
170 charType buffer[intTypeLimits::digits10 + 2];
171 const std::size_t buffer_size
172 = sizeof (buffer) / sizeof (charType);
173
174 charType * it = &buffer[buffer_size];
175 charType const * const buf_end = &buffer[buffer_size];
176
177 if (LOG4CPLUS_UNLIKELY (value == 0))
178 {
179 --it;
180 *it = LOG4CPLUS_TEXT('0');
181 }
182 else
183 {
184 bool const negative = HelperType::is_negative (value);
185 if (negative)
186 HelperType::step1 (it, value);
187
188 for (; value != 0; --it)
189 {
190 intType mod = value % 10;
191 value = value / 10;
192 *(it - 1) = static_cast<charType>(LOG4CPLUS_TEXT('0')
193 + mod);
194 }
195
196 if (negative)
197 {
198 --it;
199 *it = LOG4CPLUS_TEXT('-');
200 }
201 }
202
203 str.assign (static_cast<charType const *>(it), buf_end);
204 }
205
206
207 template<class intType>
208 inline
209 tstring
211 {
212 tstring result;
213 convertIntegerToString (result, value);
214 return result;
215 }
216
217
218 template<class intType>
219 inline
220 std::string
222 {
223 std::string result;
224 convertIntegerToString (result, value);
225 return result;
226 }
227
228
230 template <typename Iterator, typename Separator>
231 inline
232 void
233 join_worker (tstring & result, Iterator & start, Iterator & last,
234 Separator const & sep)
235 {
236 if (start != last)
237 result = *start++;
238
239 for (; start != last; ++start)
240 {
241 result += sep;
242 result += *start;
243 }
244 }
245
247 template <typename Iterator>
248 inline
249 void
250 join (tstring & result, Iterator start, Iterator last,
251 tstring const & sep)
252 {
253 join_worker (result, start, last, sep);
254 }
255
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_
#define LOG4CPLUS_TEXT(STRING)
Definition clogger.h:72
#define LOG4CPLUS_UNLIKELY(cond)
Definition config.hxx:141
LOG4CPLUS_EXPORT log4cplus::tstring toUpper(const log4cplus::tstring &s)
Returns s in upper case.
void join_worker(tstring &result, Iterator &start, Iterator &last, Separator const &sep)
Join a list of items into a string.
void join(tstring &result, Iterator start, Iterator last, tstring const &sep)
Join a list of items into a string.
void convertIntegerToString(stringType &str, intType value)
void tokenize(const StringType &s, typename StringType::value_type c, OutputIter result, bool collapseTokens=true)
Tokenize s using c as the delimiter and put the resulting tokens in _result.
std::string convertIntegerToNarrowString(intType value)
LOG4CPLUS_EXPORT log4cplus::tstring toLower(const log4cplus::tstring &s)
Returns s in lower case.
std::basic_string< tchar > tstring
Definition tstring.h:39
char tchar
Definition tchar.h:56
#define LOG4CPLUS_EXPORT
Definition win32.h:141