libstdc++
vstring_util.h
Go to the documentation of this file.
00001 // Versatile string utility -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file ext/vstring_util.h
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{ext/vstring.h}
00029  */
00030 
00031 #ifndef _VSTRING_UTIL_H
00032 #define _VSTRING_UTIL_H 1
00033 
00034 #pragma GCC system_header
00035 
00036 #include <ext/vstring_fwd.h>
00037 #include <debug/debug.h>
00038 #include <bits/stl_function.h>  // For less
00039 #include <bits/functexcept.h>
00040 #include <bits/localefwd.h>
00041 #include <bits/ostream_insert.h>
00042 #include <bits/stl_iterator.h>
00043 #include <ext/numeric_traits.h>
00044 #include <bits/move.h>
00045 #include <bits/range_access.h>
00046 
00047 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00048 {
00049 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00050 
00051   template<typename _CharT, typename _Traits, typename _Alloc>
00052     struct __vstring_utility
00053     {
00054       typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
00055 
00056       typedef _Traits                       traits_type;
00057       typedef typename _Traits::char_type           value_type;
00058       typedef typename _CharT_alloc_type::size_type     size_type;
00059       typedef typename _CharT_alloc_type::difference_type   difference_type;
00060       typedef typename _CharT_alloc_type::pointer       pointer;
00061       typedef typename _CharT_alloc_type::const_pointer     const_pointer;
00062 
00063       // For __sso_string.
00064       typedef __gnu_cxx::
00065       __normal_iterator<pointer, __gnu_cxx::
00066             __versa_string<_CharT, _Traits, _Alloc,
00067                        __sso_string_base> >
00068     __sso_iterator;
00069       typedef __gnu_cxx::
00070       __normal_iterator<const_pointer, __gnu_cxx::
00071             __versa_string<_CharT, _Traits, _Alloc,
00072                        __sso_string_base> >
00073     __const_sso_iterator;
00074 
00075       // For __rc_string.
00076       typedef __gnu_cxx::
00077       __normal_iterator<pointer, __gnu_cxx::
00078             __versa_string<_CharT, _Traits, _Alloc,
00079                        __rc_string_base> >
00080     __rc_iterator;
00081       typedef __gnu_cxx::
00082       __normal_iterator<const_pointer, __gnu_cxx::
00083             __versa_string<_CharT, _Traits, _Alloc,
00084                        __rc_string_base> >
00085     __const_rc_iterator;
00086 
00087       // NB:  When the allocator is empty, deriving from it saves space
00088       // (http://www.cantrip.org/emptyopt.html).
00089       template<typename _Alloc1>
00090     struct _Alloc_hider
00091     : public _Alloc1
00092     {
00093       _Alloc_hider(_CharT* __ptr)
00094       : _Alloc1(), _M_p(__ptr) { }
00095 
00096       _Alloc_hider(const _Alloc1& __a, _CharT* __ptr)
00097       : _Alloc1(__a), _M_p(__ptr) { }
00098 
00099       _CharT*  _M_p; // The actual data.
00100     };
00101 
00102       // When __n = 1 way faster than the general multichar
00103       // traits_type::copy/move/assign.
00104       static void
00105       _S_copy(_CharT* __d, const _CharT* __s, size_type __n)
00106       {
00107     if (__n == 1)
00108       traits_type::assign(*__d, *__s);
00109     else
00110       traits_type::copy(__d, __s, __n);
00111       }
00112 
00113       static void
00114       _S_move(_CharT* __d, const _CharT* __s, size_type __n)
00115       {
00116     if (__n == 1)
00117       traits_type::assign(*__d, *__s);
00118     else
00119       traits_type::move(__d, __s, __n);
00120       }
00121 
00122       static void
00123       _S_assign(_CharT* __d, size_type __n, _CharT __c)
00124       {
00125     if (__n == 1)
00126       traits_type::assign(*__d, __c);
00127     else
00128       traits_type::assign(__d, __n, __c);
00129       }
00130 
00131       // _S_copy_chars is a separate template to permit specialization
00132       // to optimize for the common case of pointers as iterators.
00133       template<typename _Iterator>
00134     static void
00135     _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
00136     {
00137       for (; __k1 != __k2; ++__k1, ++__p)
00138         traits_type::assign(*__p, *__k1); // These types are off.
00139     }
00140 
00141       static void
00142       _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2)
00143       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00144 
00145       static void
00146       _S_copy_chars(_CharT* __p, __const_sso_iterator __k1,
00147             __const_sso_iterator __k2)
00148       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00149 
00150       static void
00151       _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2)
00152       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00153 
00154       static void
00155       _S_copy_chars(_CharT* __p, __const_rc_iterator __k1,
00156             __const_rc_iterator __k2)
00157       { _S_copy_chars(__p, __k1.base(), __k2.base()); }
00158 
00159       static void
00160       _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
00161       { _S_copy(__p, __k1, __k2 - __k1); }
00162 
00163       static void
00164       _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
00165       { _S_copy(__p, __k1, __k2 - __k1); }
00166 
00167       static int
00168       _S_compare(size_type __n1, size_type __n2)
00169       {
00170     const difference_type __d = difference_type(__n1 - __n2);
00171 
00172     if (__d > __numeric_traits_integer<int>::__max)
00173       return __numeric_traits_integer<int>::__max;
00174     else if (__d < __numeric_traits_integer<int>::__min)
00175       return __numeric_traits_integer<int>::__min;
00176     else
00177       return int(__d);
00178       }
00179     };
00180 
00181 _GLIBCXX_END_NAMESPACE_VERSION
00182 } // namespace
00183 
00184 #endif /* _VSTRING_UTIL_H */