# locale_classes.tcc

Go to the documentation of this file.

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