log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Module: Log4CPLUS 00003 // File: stringhelper.h 00004 // Created: 3/2003 00005 // Author: Tad E. Smith 00006 // 00007 // 00008 // Copyright 2003-2010 Tad E. Smith 00009 // 00010 // Licensed under the Apache License, Version 2.0 (the "License"); 00011 // you may not use this file except in compliance with the License. 00012 // You may obtain a copy of the License at 00013 // 00014 // http://www.apache.org/licenses/LICENSE-2.0 00015 // 00016 // Unless required by applicable law or agreed to in writing, software 00017 // distributed under the License is distributed on an "AS IS" BASIS, 00018 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 // See the License for the specific language governing permissions and 00020 // limitations under the License. 00021 00024 #ifndef LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ 00025 #define LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ 00026 00027 #include <log4cplus/config.hxx> 00028 00029 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00030 #pragma once 00031 #endif 00032 00033 #include <log4cplus/tstring.h> 00034 00035 #include <algorithm> 00036 #include <limits> 00037 00038 00039 namespace log4cplus { 00040 namespace helpers { 00041 00045 LOG4CPLUS_EXPORT log4cplus::tstring toUpper(const log4cplus::tstring& s); 00046 00047 00051 LOG4CPLUS_EXPORT log4cplus::tstring toLower(const log4cplus::tstring& s); 00052 00053 00067 template <class StringType, class OutputIter> 00068 inline 00069 void 00070 tokenize(const StringType& s, typename StringType::value_type c, 00071 OutputIter result, bool collapseTokens = true) 00072 { 00073 typedef typename StringType::size_type size_type; 00074 size_type const slen = s.length(); 00075 size_type first = 0; 00076 size_type i = 0; 00077 for (i=0; i < slen; ++i) 00078 { 00079 if (s[i] == c) 00080 { 00081 *result = StringType (s, first, i - first); 00082 ++result; 00083 if (collapseTokens) 00084 while (i+1 < slen && s[i+1] == c) 00085 ++i; 00086 first = i + 1; 00087 } 00088 } 00089 if (first != i) 00090 *result = StringType (s, first, i - first); 00091 } 00092 00093 00094 template <typename intType, bool isSigned> 00095 struct ConvertIntegerToStringHelper; 00096 00097 00098 template <typename intType> 00099 struct ConvertIntegerToStringHelper<intType, true> 00100 { 00101 static inline 00102 void 00103 step1 (tchar * & it, intType & value) 00104 { 00105 // The sign of the result of the modulo operator is 00106 // implementation defined. That's why we work with 00107 // positive counterpart instead. Also, in twos 00108 // complement arithmetic the smallest negative number 00109 // does not have positive counterpart; the range is 00110 // asymetric. That's why we handle the case of value 00111 // == min() specially here. 00112 if (value == (std::numeric_limits<intType>::min) ()) 00113 { 00114 intType const r = value / 10; 00115 intType const a = (-r) * 10; 00116 intType const mod = -(a + value); 00117 value = -r; 00118 00119 *(it - 1) = LOG4CPLUS_TEXT('0') + static_cast<tchar>(mod); 00120 --it; 00121 } 00122 else 00123 value = -value; 00124 } 00125 00126 static inline 00127 bool 00128 is_negative (intType val) 00129 { 00130 return val < 0; 00131 } 00132 }; 00133 00134 00135 template <typename intType> 00136 struct ConvertIntegerToStringHelper<intType, false> 00137 { 00138 static inline 00139 void 00140 step1 (tchar * &, intType &) 00141 { 00142 // This will never be called for unsigned types. 00143 } 00144 00145 static inline 00146 bool 00147 is_negative (intType) 00148 { 00149 return false; 00150 } 00151 }; 00152 00153 00154 template<class intType> 00155 inline 00156 void 00157 convertIntegerToString (tstring & str, intType value) 00158 { 00159 typedef std::numeric_limits<intType> intTypeLimits; 00160 typedef ConvertIntegerToStringHelper<intType, intTypeLimits::is_signed> 00161 HelperType; 00162 00163 const std::size_t buffer_size 00164 = intTypeLimits::digits10 + 2; 00165 tchar buffer[buffer_size]; 00166 tchar * it = &buffer[buffer_size]; 00167 tchar const * const buf_end = it; 00168 00169 if (value == 0) 00170 { 00171 --it; 00172 *it = LOG4CPLUS_TEXT('0'); 00173 } 00174 00175 bool const negative = HelperType::is_negative (value); 00176 if (negative) 00177 HelperType::step1 (it, value); 00178 00179 for (; value != 0; --it) 00180 { 00181 intType mod = value % 10; 00182 value = value / 10; 00183 *(it - 1) = LOG4CPLUS_TEXT('0') + static_cast<tchar>(mod); 00184 } 00185 00186 if (negative) 00187 { 00188 --it; 00189 *it = LOG4CPLUS_TEXT('-'); 00190 } 00191 00192 str.assign (static_cast<tchar const *>(it), buf_end); 00193 } 00194 00195 00196 template<class intType> 00197 inline 00198 tstring 00199 convertIntegerToString (intType value) 00200 { 00201 tstring result; 00202 convertIntegerToString (result, value); 00203 return result; 00204 } 00205 00206 } // namespace helpers 00207 00208 } // namespace log4cplus 00209 00210 #endif // LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_