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

Generated on Thu Jul 23 21:16:09 2009 for libstdc++ by  doxygen 1.5.8