Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 2007-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/locale_classes.tcc
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{locale}
  28.  */
  29.  
  30. //
  31. // ISO C++ 14882: 22.1  Locales
  32. //
  33.  
  34. #ifndef _LOCALE_CLASSES_TCC
  35. #define _LOCALE_CLASSES_TCC 1
  36.  
  37. #pragma GCC system_header
  38.  
  39. namespace std _GLIBCXX_VISIBILITY(default)
  40. {
  41. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  42.  
  43.   template<typename _Facet>
  44.     locale::
  45.     locale(const locale& __other, _Facet* __f)
  46.     {
  47.       _M_impl = new _Impl(*__other._M_impl, 1);
  48.  
  49.       __try
  50.         { _M_impl->_M_install_facet(&_Facet::id, __f); }
  51.       __catch(...)
  52.         {
  53.           _M_impl->_M_remove_reference();
  54.           __throw_exception_again;
  55.         }
  56.       delete [] _M_impl->_M_names[0];
  57.       _M_impl->_M_names[0] = 0;   // Unnamed.
  58.     }
  59.  
  60.   template<typename _Facet>
  61.     locale
  62.     locale::
  63.     combine(const locale& __other) const
  64.     {
  65.       _Impl* __tmp = new _Impl(*_M_impl, 1);
  66.       __try
  67.         {
  68.           __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
  69.         }
  70.       __catch(...)
  71.         {
  72.           __tmp->_M_remove_reference();
  73.           __throw_exception_again;
  74.         }
  75.       return locale(__tmp);
  76.     }
  77.  
  78.   template<typename _CharT, typename _Traits, typename _Alloc>
  79.     bool
  80.     locale::
  81.     operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
  82.                const basic_string<_CharT, _Traits, _Alloc>& __s2) const
  83.     {
  84.       typedef std::collate<_CharT> __collate_type;
  85.       const __collate_type& __collate = use_facet<__collate_type>(*this);
  86.       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
  87.                                 __s2.data(), __s2.data() + __s2.length()) < 0);
  88.     }
  89.  
  90.   /**
  91.    *  @brief  Test for the presence of a facet.
  92.    *  @ingroup locales
  93.    *
  94.    *  has_facet tests the locale argument for the presence of the facet type
  95.    *  provided as the template parameter.  Facets derived from the facet
  96.    *  parameter will also return true.
  97.    *
  98.    *  @tparam  _Facet  The facet type to test the presence of.
  99.    *  @param  __loc  The locale to test.
  100.    *  @return  true if @p __loc contains a facet of type _Facet, else false.
  101.   */
  102.   template<typename _Facet>
  103.     bool
  104.     has_facet(const locale& __loc) throw()
  105.     {
  106.       const size_t __i = _Facet::id._M_id();
  107.       const locale::facet** __facets = __loc._M_impl->_M_facets;
  108.       return (__i < __loc._M_impl->_M_facets_size
  109. #if __cpp_rtti
  110.               && dynamic_cast<const _Facet*>(__facets[__i]));
  111. #else
  112.               && static_cast<const _Facet*>(__facets[__i]));
  113. #endif
  114.     }
  115.  
  116.   /**
  117.    *  @brief  Return a facet.
  118.    *  @ingroup locales
  119.    *
  120.    *  use_facet looks for and returns a reference to a facet of type Facet
  121.    *  where Facet is the template parameter.  If has_facet(locale) is true,
  122.    *  there is a suitable facet to return.  It throws std::bad_cast if the
  123.    *  locale doesn't contain a facet of type Facet.
  124.    *
  125.    *  @tparam  _Facet  The facet type to access.
  126.    *  @param  __loc  The locale to use.
  127.    *  @return  Reference to facet of type Facet.
  128.    *  @throw  std::bad_cast if @p __loc doesn't contain a facet of type _Facet.
  129.   */
  130.   template<typename _Facet>
  131.     const _Facet&
  132.     use_facet(const locale& __loc)
  133.     {
  134.       const size_t __i = _Facet::id._M_id();
  135.       const locale::facet** __facets = __loc._M_impl->_M_facets;
  136.       if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
  137.         __throw_bad_cast();
  138. #if __cpp_rtti
  139.       return dynamic_cast<const _Facet&>(*__facets[__i]);
  140. #else
  141.       return static_cast<const _Facet&>(*__facets[__i]);
  142. #endif
  143.     }
  144.  
  145.  
  146.   // Generic version does nothing.
  147.   template<typename _CharT>
  148.     int
  149.     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
  150.     { return 0; }
  151.  
  152.   // Generic version does nothing.
  153.   template<typename _CharT>
  154.     size_t
  155.     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
  156.     { return 0; }
  157.  
  158.   template<typename _CharT>
  159.     int
  160.     collate<_CharT>::
  161.     do_compare(const _CharT* __lo1, const _CharT* __hi1,
  162.                const _CharT* __lo2, const _CharT* __hi2) const
  163.     {
  164.       // strcoll assumes zero-terminated strings so we make a copy
  165.       // and then put a zero at the end.
  166.       const string_type __one(__lo1, __hi1);
  167.       const string_type __two(__lo2, __hi2);
  168.  
  169.       const _CharT* __p = __one.c_str();
  170.       const _CharT* __pend = __one.data() + __one.length();
  171.       const _CharT* __q = __two.c_str();
  172.       const _CharT* __qend = __two.data() + __two.length();
  173.  
  174.       // strcoll stops when it sees a nul character so we break
  175.       // the strings into zero-terminated substrings and pass those
  176.       // to strcoll.
  177.       for (;;)
  178.         {
  179.           const int __res = _M_compare(__p, __q);
  180.           if (__res)
  181.             return __res;
  182.  
  183.           __p += char_traits<_CharT>::length(__p);
  184.           __q += char_traits<_CharT>::length(__q);
  185.           if (__p == __pend && __q == __qend)
  186.             return 0;
  187.           else if (__p == __pend)
  188.             return -1;
  189.           else if (__q == __qend)
  190.             return 1;
  191.  
  192.           __p++;
  193.           __q++;
  194.         }
  195.     }
  196.  
  197.   template<typename _CharT>
  198.     typename collate<_CharT>::string_type
  199.     collate<_CharT>::
  200.     do_transform(const _CharT* __lo, const _CharT* __hi) const
  201.     {
  202.       string_type __ret;
  203.  
  204.       // strxfrm assumes zero-terminated strings so we make a copy
  205.       const string_type __str(__lo, __hi);
  206.  
  207.       const _CharT* __p = __str.c_str();
  208.       const _CharT* __pend = __str.data() + __str.length();
  209.  
  210.       size_t __len = (__hi - __lo) * 2;
  211.  
  212.       _CharT* __c = new _CharT[__len];
  213.  
  214.       __try
  215.         {
  216.           // strxfrm stops when it sees a nul character so we break
  217.           // the string into zero-terminated substrings and pass those
  218.           // to strxfrm.
  219.           for (;;)
  220.             {
  221.               // First try a buffer perhaps big enough.
  222.               size_t __res = _M_transform(__c, __p, __len);
  223.               // If the buffer was not large enough, try again with the
  224.               // correct size.
  225.               if (__res >= __len)
  226.                 {
  227.                   __len = __res + 1;
  228.                   delete [] __c, __c = 0;
  229.                   __c = new _CharT[__len];
  230.                   __res = _M_transform(__c, __p, __len);
  231.                 }
  232.  
  233.               __ret.append(__c, __res);
  234.               __p += char_traits<_CharT>::length(__p);
  235.               if (__p == __pend)
  236.                 break;
  237.  
  238.               __p++;
  239.               __ret.push_back(_CharT());
  240.             }
  241.         }
  242.       __catch(...)
  243.         {
  244.           delete [] __c;
  245.           __throw_exception_again;
  246.         }
  247.  
  248.       delete [] __c;
  249.  
  250.       return __ret;
  251.     }
  252.  
  253.   template<typename _CharT>
  254.     long
  255.     collate<_CharT>::
  256.     do_hash(const _CharT* __lo, const _CharT* __hi) const
  257.     {
  258.       unsigned long __val = 0;
  259.       for (; __lo < __hi; ++__lo)
  260.         __val =
  261.           *__lo + ((__val << 7)
  262.                    | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
  263.                                 __digits - 7)));
  264.       return static_cast<long>(__val);
  265.     }
  266.  
  267.   // Inhibit implicit instantiations for required instantiations,
  268.   // which are defined via explicit instantiations elsewhere.
  269. #if _GLIBCXX_EXTERN_TEMPLATE
  270.   extern template class collate<char>;
  271.   extern template class collate_byname<char>;
  272.  
  273.   extern template
  274.     const collate<char>&
  275.     use_facet<collate<char> >(const locale&);
  276.  
  277.   extern template
  278.     bool
  279.     has_facet<collate<char> >(const locale&);
  280.  
  281. #ifdef _GLIBCXX_USE_WCHAR_T
  282.   extern template class collate<wchar_t>;
  283.   extern template class collate_byname<wchar_t>;
  284.  
  285.   extern template
  286.     const collate<wchar_t>&
  287.     use_facet<collate<wchar_t> >(const locale&);
  288.  
  289.   extern template
  290.     bool
  291.     has_facet<collate<wchar_t> >(const locale&);
  292. #endif
  293. #endif
  294.  
  295. _GLIBCXX_END_NAMESPACE_VERSION
  296. } // namespace std
  297.  
  298. #endif
  299.