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

Generated on Wed Mar 26 00:43:00 2008 for libstdc++ by  doxygen 1.5.1