# locale_classes.tcc

Go to the documentation of this file.

    00001 // Locale support -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file locale_classes.tcc
    00031  *  This is an internal header file, included by other library headers.
    00032  *  You should not attempt to use it directly.
    00033  */
    00034
    00035 //
    00036 // ISO C++ 14882: 22.1  Locales
    00037 //
    00038
    00039 #ifndef _LOCALE_CLASSES_TCC
    00040 #define _LOCALE_CLASSES_TCC 1
    00041
    00042 #pragma GCC system_header
    00043
    00044 _GLIBCXX_BEGIN_NAMESPACE(std)
    00045
    00046   template<typename _Facet>
    00047     locale::
    00048     locale(const locale& __other, _Facet* __f)
    00049     {
    00050       _M_impl = new _Impl(*__other._M_impl, 1);
    00051
    00052       try
    00053     { _M_impl->_M_install_facet(&_Facet::id, __f); }
    00054       catch(...)
    00055     {
    00056       _M_impl->_M_remove_reference();
    00057       __throw_exception_again;
    00058     }
    00059       delete [] _M_impl->_M_names[0];
    00060       _M_impl->_M_names[0] = 0;   // Unnamed.
    00061     }
    00062
    00063   template<typename _Facet>
    00064     locale
    00065     locale::
    00066     combine(const locale& __other) const
    00067     {
    00068       _Impl* __tmp = new _Impl(*_M_impl, 1);
    00069       try
    00070     {
    00071       __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
    00072     }
    00073       catch(...)
    00074     {
    00075       __tmp->_M_remove_reference();
    00076       __throw_exception_again;
    00077     }
    00078       return locale(__tmp);
    00079     }
    00080
    00081   template<typename _CharT, typename _Traits, typename _Alloc>
    00082     bool
    00083     locale::
    00084     operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
    00085            const basic_string<_CharT, _Traits, _Alloc>& __s2) const
    00086     {
    00087       typedef std::collate<_CharT> __collate_type;
    00088       const __collate_type& __collate = use_facet<__collate_type>(*this);
    00089       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
    00090                 __s2.data(), __s2.data() + __s2.length()) < 0);
    00091     }
    00092
    00093
    00094   template<typename _Facet>
    00095     bool
    00096     has_facet(const locale& __loc) throw()
    00097     {
    00098       const size_t __i = _Facet::id._M_id();
    00099       const locale::facet** __facets = __loc._M_impl->_M_facets;
    00100       return (__i < __loc._M_impl->_M_facets_size
    00101 #ifdef __GXX_RTTI
    00102           && dynamic_cast<const _Facet*>(__facets[__i]));
    00103 #else
    00104               && static_cast<const _Facet*>(__facets[__i]));
    00105 #endif
    00106     }
    00107
    00108   template<typename _Facet>
    00109     const _Facet&
    00110     use_facet(const locale& __loc)
    00111     {
    00112       const size_t __i = _Facet::id._M_id();
    00113       const locale::facet** __facets = __loc._M_impl->_M_facets;
    00114       if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
    00115         __throw_bad_cast();
    00116 #ifdef __GXX_RTTI
    00117       return dynamic_cast<const _Facet&>(*__facets[__i]);
    00118 #else
    00119       return static_cast<const _Facet&>(*__facets[__i]);
    00120 #endif
    00121     }
    00122
    00123
    00124   // Generic version does nothing.
    00125   template<typename _CharT>
    00126     int
    00127     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
    00128     { return 0; }
    00129
    00130   // Generic version does nothing.
    00131   template<typename _CharT>
    00132     size_t
    00133     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
    00134     { return 0; }
    00135
    00136   template<typename _CharT>
    00137     int
    00138     collate<_CharT>::
    00139     do_compare(const _CharT* __lo1, const _CharT* __hi1,
    00140            const _CharT* __lo2, const _CharT* __hi2) const
    00141     {
    00142       // strcoll assumes zero-terminated strings so we make a copy
    00143       // and then put a zero at the end.
    00144       const string_type __one(__lo1, __hi1);
    00145       const string_type __two(__lo2, __hi2);
    00146
    00147       const _CharT* __p = __one.c_str();
    00148       const _CharT* __pend = __one.data() + __one.length();
    00149       const _CharT* __q = __two.c_str();
    00150       const _CharT* __qend = __two.data() + __two.length();
    00151
    00152       // strcoll stops when it sees a nul character so we break
    00153       // the strings into zero-terminated substrings and pass those
    00154       // to strcoll.
    00155       for (;;)
    00156     {
    00157       const int __res = _M_compare(__p, __q);
    00158       if (__res)
    00159         return __res;
    00160
    00161       __p += char_traits<_CharT>::length(__p);
    00162       __q += char_traits<_CharT>::length(__q);
    00163       if (__p == __pend && __q == __qend)
    00164         return 0;
    00165       else if (__p == __pend)
    00166         return -1;
    00167       else if (__q == __qend)
    00168         return 1;
    00169
    00170       __p++;
    00171       __q++;
    00172     }
    00173     }
    00174
    00175   template<typename _CharT>
    00176     typename collate<_CharT>::string_type
    00177     collate<_CharT>::
    00178     do_transform(const _CharT* __lo, const _CharT* __hi) const
    00179     {
    00180       string_type __ret;
    00181
    00182       // strxfrm assumes zero-terminated strings so we make a copy
    00183       const string_type __str(__lo, __hi);
    00184
    00185       const _CharT* __p = __str.c_str();
    00186       const _CharT* __pend = __str.data() + __str.length();
    00187
    00188       size_t __len = (__hi - __lo) * 2;
    00189
    00190       _CharT* __c = new _CharT[__len];
    00191
    00192       try
    00193     {
    00194       // strxfrm stops when it sees a nul character so we break
    00195       // the string into zero-terminated substrings and pass those
    00196       // to strxfrm.
    00197       for (;;)
    00198         {
    00199           // First try a buffer perhaps big enough.
    00200           size_t __res = _M_transform(__c, __p, __len);
    00201           // If the buffer was not large enough, try again with the
    00202           // correct size.
    00203           if (__res >= __len)
    00204         {
    00205           __len = __res + 1;
    00206           delete [] __c, __c = 0;
    00207           __c = new _CharT[__len];
    00208           __res = _M_transform(__c, __p, __len);
    00209         }
    00210
    00211           __ret.append(__c, __res);
    00212           __p += char_traits<_CharT>::length(__p);
    00213           if (__p == __pend)
    00214         break;
    00215
    00216           __p++;
    00217           __ret.push_back(_CharT());
    00218         }
    00219     }
    00220       catch(...)
    00221     {
    00222       delete [] __c;
    00223       __throw_exception_again;
    00224     }
    00225
    00226       delete [] __c;
    00227
    00228       return __ret;
    00229     }
    00230
    00231   template<typename _CharT>
    00232     long
    00233     collate<_CharT>::
    00234     do_hash(const _CharT* __lo, const _CharT* __hi) const
    00235     {
    00236       unsigned long __val = 0;
    00237       for (; __lo < __hi; ++__lo)
    00238     __val =
    00239       *__lo + ((__val << 7)
    00240            | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
    00241                 __digits - 7)));
    00242       return static_cast<long>(__val);
    00243     }
    00244
    00245   // Inhibit implicit instantiations for required instantiations,
    00246   // which are defined via explicit instantiations elsewhere.
    00247   // NB: This syntax is a GNU extension.
    00248 #if _GLIBCXX_EXTERN_TEMPLATE
    00249   extern template class collate<char>;
    00250   extern template class collate_byname<char>;
    00251
    00252   extern template
    00253     const collate<char>&
    00254     use_facet<collate<char> >(const locale&);
    00255
    00256   extern template
    00257     bool
    00258     has_facet<collate<char> >(const locale&);
    00259
    00260 #ifdef _GLIBCXX_USE_WCHAR_T
    00261   extern template class collate<wchar_t>;
    00262   extern template class collate_byname<wchar_t>;
    00263
    00264   extern template
    00265     const collate<wchar_t>&
    00266     use_facet<collate<wchar_t> >(const locale&);
    00267
    00268   extern template
    00269     bool
    00270     has_facet<collate<wchar_t> >(const locale&);
    00271 #endif
    00272 #endif
    00273
    00274 _GLIBCXX_END_NAMESPACE
    00275
    00276 #endif