00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS
00049 #define STLSOFT_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS_MAJOR 2
00053 # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS_MINOR 1
00054 # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS_REVISION 8
00055 # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_TRIM_FUNCTIONS_EDIT 37
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00074 # include <stlsoft/stlsoft.h>
00075 #endif
00076
00077 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00078 _MSC_VER < 1200
00079 # error stlsoft/string/trim_functions.hpp is not compatible with Visual C++ 5.0 or earlier
00080 #endif
00081
00082 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TRAITS
00083 # include <stlsoft/string/string_traits.hpp>
00084 #endif
00085 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00086 # include <stlsoft/shims/access/string.hpp>
00087 #endif
00088
00089 #ifndef STLSOFT_INCL_ALGORITHM
00090 # define STLSOFT_INCL_ALGORITHM
00091 # include <algorithm>
00092 #endif
00093 #ifndef STLSOFT_INCL_FUNCTIONAL
00094 # define STLSOFT_INCL_FUNCTIONAL
00095 # include <functional>
00096 #endif
00097
00098 #ifndef STLSOFT_INCL_H_STRING
00099 # define STLSOFT_INCL_H_STRING
00100 # include <string.h>
00101 #endif
00102 #ifndef STLSOFT_INCL_H_WCHAR
00103 # define STLSOFT_INCL_H_WCHAR
00104 # include <wchar.h>
00105 #endif
00106
00107 #ifdef STLSOFT_UNITTEST
00108 # include <string>
00109 # ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING
00110 # include <stlsoft/string/simple_string.hpp>
00111 # endif
00112 # ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW
00113 # include <stlsoft/string/string_view.hpp>
00114 # endif
00115 #endif
00116
00117
00118
00119
00120
00121 #ifndef _STLSOFT_NO_NAMESPACE
00122 namespace stlsoft
00123 {
00124 #endif
00125
00126
00127
00128 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00129
00130 struct trim_functions_impl
00131 {
00132 template <ss_typename_param_k I>
00133 static bool is_in_range(I from, I to, I it)
00134 {
00135 for(; from != to; ++from)
00136 {
00137 if(from == it)
00138 {
00139 return true;
00140 }
00141 }
00142
00143 return false;
00144 }
00145 };
00146
00147 inline char const* strchr_select(char const* s, char ch)
00148 {
00149 return ::strchr(s, ch);
00150 }
00151 inline wchar_t const* strchr_select(wchar_t const* s, wchar_t ch)
00152 {
00153 return ::wcschr(s, ch);
00154 }
00155
00156 template <ss_typename_param_k C>
00157 inline C const* default_trim_chars(C const* , ss_size_t& n)
00158 {
00159 static const C s_trimChars[] =
00160 {
00161 ' '
00162 , '\n'
00163 , '\r'
00164 , '\t'
00165 , '\v'
00166 , '\0'
00167 };
00168
00169 n = STLSOFT_NUM_ELEMENTS(s_trimChars) - 1;
00170
00171 return &s_trimChars[0];
00172 }
00173
00174 #endif
00175
00176
00177 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00178
00179 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00180 _MSC_VER < 1310
00181 template< ss_typename_param_k S
00182 , ss_typename_param_k C
00183 >
00184 inline S& trim_left_impl(S& str, C const* trimChars)
00185 #else
00186 template<ss_typename_param_k S>
00187 inline S& trim_left_impl(S& str, ss_typename_type_k string_traits<S>::char_type const* trimChars)
00188 #endif
00189 {
00190
00191 #ifdef STLSOFT_CF_std_NAMESPACE
00192 using namespace std;
00193 #endif
00194
00195 typedef string_traits<S> string_traits_t;
00196
00197 typedef ss_typename_type_k string_traits_t::char_type char_t;
00198
00199 typedef ss_typename_type_k string_traits_t::const_iterator iterator_t;
00200
00201 char_t const* (*pfn)(char_t const*, char_t) = ::stlsoft::strchr_select;
00202
00203
00204 const iterator_t it_b = str.begin();
00205 const iterator_t it_e = str.end();
00206 const iterator_t it_l = find_if(it_b, it_e, not1(bind1st(ptr_fun(pfn), trimChars)));
00207 iterator_t const& it_r = it_e;
00208
00209 return string_traits_t::assign_inplace(str, it_l, it_r);
00210 }
00211
00212 #endif
00213
00218 template<ss_typename_param_k S>
00219 inline S& trim_left(S& str)
00220 {
00221
00222 typedef string_traits<S> string_traits_t;
00223
00224 # if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00225 __BORLANDC__ < 0x0564
00226
00227 string_traits_t::char_type *p = NULL;
00228 # endif
00229
00230
00231 typedef ss_typename_type_k string_traits_t::char_type char_t;
00232
00233 ss_size_t n;
00234 char_t const* trimChars = default_trim_chars(static_cast<char_t const*>(0), n);
00235
00236 STLSOFT_SUPPRESS_UNUSED(n);
00237
00238 return trim_left_impl(str, trimChars);
00239 }
00240
00245 template< ss_typename_param_k S0
00246 , ss_typename_param_k S1
00247 >
00248 inline S0& trim_left(S0& str, S1 const& trimChars)
00249 {
00250 return trim_left_impl(str, stlsoft_ns_qual(c_str_ptr)(trimChars));
00251 }
00252
00253
00254
00255 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00256
00257 # if defined(__BORLANDC__)
00258 # pragma warn -8091 // Otherwise BC++ complains that rbegin()/rend() returns passed to find_if() are output iterators
00259 # pragma warn -8092 // Otherwise BC++ complains that rbegin()/rend() returns passed to find_if() are not iterators
00260 # endif
00261
00262 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00263 _MSC_VER < 1310
00264 template< ss_typename_param_k S
00265 , ss_typename_param_k C
00266 >
00267 inline S& trim_right_impl(S& str, C const* trimChars)
00268 #else
00269 template<ss_typename_param_k S>
00270 inline S& trim_right_impl(S& str, ss_typename_type_k string_traits<S>::char_type const* trimChars)
00271 #endif
00272 {
00273 S const& cstr = str;
00274
00275
00276 #ifdef STLSOFT_CF_std_NAMESPACE
00277 using namespace std;
00278 #endif
00279
00280 typedef string_traits<S> string_traits_t;
00281
00282 typedef ss_typename_type_k string_traits_t::char_type char_t;
00283
00284 typedef ss_typename_type_k string_traits_t::const_iterator iterator_t;
00285 typedef ss_typename_type_k string_traits_t::const_reverse_iterator reverse_iterator_t;
00286
00287 char_t const* (*pfn)(char_t const*, char_t) = ::stlsoft::strchr_select;
00288
00289
00290 const iterator_t it_b = cstr.begin();
00291
00292 const iterator_t it_l = it_b;
00293 const reverse_iterator_t rit = find_if(cstr.rbegin(), cstr.rend(), not1(bind1st(ptr_fun(pfn), trimChars)));
00294 const iterator_t it_r = rit.base();
00295
00296 return string_traits_t::assign_inplace(str, it_l, it_r);
00297 }
00298
00299 # if defined(__BORLANDC__)
00300 # pragma warn .8092
00301 # pragma warn .8091
00302 # endif
00303
00304 #endif
00305
00310 template<ss_typename_param_k S>
00311 inline S& trim_right(S& str)
00312 {
00313
00314 typedef string_traits<S> string_traits_t;
00315
00316 # if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00317 __BORLANDC__ < 0x0564
00318
00319 string_traits_t::char_type *p = NULL;
00320 # endif
00321
00322
00323 typedef ss_typename_type_k string_traits_t::char_type char_t;
00324
00325 ss_size_t n;
00326 char_t const* trimChars = default_trim_chars(static_cast<char_t const*>(0), n);
00327
00328 STLSOFT_SUPPRESS_UNUSED(n);
00329
00330 return trim_right_impl(str, trimChars);
00331 }
00332
00337 template< ss_typename_param_k S0
00338 , ss_typename_param_k S1
00339 >
00340 inline S0& trim_right(S0& str, S1 const& trimChars)
00341 {
00342 return trim_right_impl(str, stlsoft_ns_qual(c_str_ptr)(trimChars));
00343 }
00344
00345
00346
00347
00348 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00349
00350 # if defined(__BORLANDC__)
00351 # pragma warn -8091 // Otherwise BC++ complains that rbegin()/rend() returns passed to find_if() are output iterators
00352 # pragma warn -8092 // Otherwise BC++ complains that rbegin()/rend() returns passed to find_if() are not iterators
00353 # endif
00354
00355 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00356 _MSC_VER < 1310
00357 template< ss_typename_param_k S
00358 , ss_typename_param_k C
00359 >
00360 inline S& trim_all_impl(S& str, C const* trimChars)
00361 #else
00362 template<ss_typename_param_k S>
00363 inline S& trim_all_impl(S& str, ss_typename_type_k string_traits<S>::char_type const* trimChars)
00364 #endif
00365 {
00366 S const& cstr = str;
00367
00368
00369 #ifdef STLSOFT_CF_std_NAMESPACE
00370 using namespace std;
00371 #endif
00372
00373 typedef string_traits<S> string_traits_t;
00374
00375 typedef ss_typename_type_k string_traits_t::char_type char_t;
00376
00377 typedef ss_typename_type_k string_traits_t::const_iterator iterator_t;
00378 typedef ss_typename_type_k string_traits_t::const_reverse_iterator reverse_iterator_t;
00379
00380 char_t const* (*pfn)(char_t const*, char_t) = ::stlsoft::strchr_select;
00381
00382
00383 const iterator_t it_b = cstr.begin();
00384 const iterator_t it_e = cstr.end();
00385 const iterator_t it_l = find_if(it_b, it_e, not1(bind1st(ptr_fun(pfn), trimChars)));
00386
00387 STLSOFT_MESSAGE_ASSERT("iterator not in range", (it_e == it_l || trim_functions_impl::is_in_range(it_b, it_e, it_l)));
00388
00389 iterator_t it_r;
00390
00391 if(it_l == it_e)
00392 {
00393 it_r = it_e;
00394 }
00395 else
00396 {
00397 const reverse_iterator_t itr_b = cstr.rbegin();
00398 const reverse_iterator_t itr_e = cstr.rend();
00399 const reverse_iterator_t rit = find_if(itr_b, itr_e, not1(bind1st(ptr_fun(pfn), trimChars)));
00400
00401 STLSOFT_MESSAGE_ASSERT("iterator not in range", (itr_e == rit || trim_functions_impl::is_in_range(itr_b, itr_e, rit)));
00402
00403 it_r = rit.base();
00404
00405 STLSOFT_MESSAGE_ASSERT("iterator not in range", (it_e == it_r || trim_functions_impl::is_in_range(it_b, it_e, it_r)));
00406 }
00407
00408 STLSOFT_MESSAGE_ASSERT("right-hand iterator not in range [left-hand, end)", (it_e == it_r || trim_functions_impl::is_in_range(it_l, it_e, it_r)));
00409
00410 return string_traits_t::assign_inplace(str, it_l, it_r);
00411 }
00412
00413 # if defined(__BORLANDC__)
00414 # pragma warn .8092
00415 # pragma warn .8091
00416 # endif
00417
00418 #endif
00419
00424 template<ss_typename_param_k S>
00425 inline S& trim_all(S& str)
00426 {
00427
00428 typedef string_traits<S> string_traits_t;
00429
00430 # if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00431 __BORLANDC__ < 0x0564
00432
00433 string_traits_t::char_type *p = NULL;
00434 # endif
00435
00436
00437 typedef ss_typename_type_k string_traits_t::char_type char_t;
00438
00439 ss_size_t n;
00440 char_t const* trimChars = default_trim_chars(static_cast<char_t const*>(0), n);
00441
00442 STLSOFT_SUPPRESS_UNUSED(n);
00443
00444 return trim_all_impl(str, trimChars);
00445 }
00446
00451 template< ss_typename_param_k S0
00452 , ss_typename_param_k S1
00453 >
00454 inline S0& trim_all(S0& str, S1 const& trimChars)
00455 {
00456 return trim_all_impl(str, stlsoft_ns_qual(c_str_ptr)(trimChars));
00457 }
00458
00459
00460 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00461
00462 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00463 _MSC_VER < 1310
00464 template< ss_typename_param_k S
00465 , ss_typename_param_k C
00466 >
00467 inline S& remove_all_impl(S& str, C const* removeChars)
00468 #else
00469 template<ss_typename_param_k S>
00470 inline S& remove_all_impl(S& str, ss_typename_type_k S::value_type const* removeChars)
00471 #endif
00472 {
00473
00474 #ifdef STLSOFT_CF_std_NAMESPACE
00475 using namespace std;
00476 #endif
00477
00478 typedef string_traits<S> string_traits_t;
00479
00480 typedef ss_typename_type_k string_traits_t::char_type char_t;
00481
00482 typedef ss_typename_type_k string_traits_t::iterator iterator_t;
00483
00484 char_t const* (*pfn)(char_t const*, char_t) = ::stlsoft::strchr_select;
00485
00486
00487 iterator_t it_b = str.begin();
00488 iterator_t it_e = str.end();
00489 const iterator_t it_l = it_b;
00490 const iterator_t it_r = remove_if(it_b, it_e, bind1st(ptr_fun(pfn), removeChars));
00491
00492 return string_traits_t::assign_inplace(str, it_l, it_r);
00493 }
00494
00495 #endif
00496
00501 template<ss_typename_param_k S>
00502 inline S& remove_all(S& str)
00503 {
00504
00505 typedef string_traits<S> string_traits_t;
00506
00507 # if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00508 __BORLANDC__ < 0x0564
00509
00510 string_traits_t::char_type *p = NULL;
00511 # endif
00512
00513
00514 typedef ss_typename_type_k string_traits_t::char_type char_t;
00515
00516 ss_size_t n;
00517 char_t const* removeChars = default_trim_chars(static_cast<char_t const*>(0), n);
00518
00519 STLSOFT_SUPPRESS_UNUSED(n);
00520
00521 return remove_all_impl(str, removeChars);
00522 }
00523
00528 template< ss_typename_param_k S0
00529 , ss_typename_param_k S1
00530 >
00531 inline S0& remove_all(S0& str, S1 const& removeChars)
00532 {
00533 return remove_all_impl(str, stlsoft_ns_qual(c_str_ptr)(removeChars));
00534 }
00535
00537
00538
00539 #ifdef STLSOFT_UNITTEST
00540 # include "./unittest/trim_functions_unittest_.h"
00541 #endif
00542
00543
00544
00545 #ifndef _STLSOFT_NO_NAMESPACE
00546 }
00547 #endif
00548
00549
00550
00551 #endif
00552
00553