log4cplus  1.1.0
stringhelper.h
Go to the documentation of this file.
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_