gcc/libstdc++-v3/include/bits/locale_classes.tcc
Paolo Carlini 84b31797f3 locale_facets.h (class collate, [...]): Move...
2007-04-24  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/locale_facets.h (class collate, class collate_byname):
	Move...
	* include/bits/locale_classes.h: ... here.
	* include/bits/locale_facets.tcc (locale::combine, locale::operator(),
	has_facet, use_facet, collate::_M_compare, collate::_M_transform,
	collate::do_compare, collate::do_transform, collate::do_hash): Move...
	* include/bits/locale_classes.tcc: ... here, new.
	* include/Makefile.am: Add.
	* testsuite/util/testsuite_abi.h: Include <locale>.
	* include/std/locale: Tweak.
	* include/std/istream: Likewise.
	* include/std/ostream: Likewise.
	* include/bits/codecvt.h: Likewise.
	* include/Makefile.in: Regenerate.

	* include/bits/codecvt.h: Adjust extern template declarations.
	* include/bits/ostream_insert.h: Likewise.
	* include/bits/ostream.tcc: Likewise.

	* include/bits/locale_facets.h: Do not include <bits/codecvt.h>.
	* include/std/fstream: Do it here.
	* include/bits/locale_facets_nonio.h: Likewise.

From-SVN: r124114
2007-04-24 18:57:12 +00:00

244 lines
6.6 KiB
C++

// Locale support -*- C++ -*-
// Copyright (C) 2007 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file locale_classes.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882: 22.1 Locales
//
#ifndef _LOCALE_CLASSES_TCC
#define _LOCALE_CLASSES_TCC 1
#pragma GCC system_header
_GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Facet>
locale::locale(const locale& __other, _Facet* __f)
{
_M_impl = new _Impl(*__other._M_impl, 1);
try
{ _M_impl->_M_install_facet(&_Facet::id, __f); }
catch(...)
{
_M_impl->_M_remove_reference();
__throw_exception_again;
}
delete [] _M_impl->_M_names[0];
_M_impl->_M_names[0] = 0; // Unnamed.
}
template<typename _Facet>
locale
locale::combine(const locale& __other) const
{
_Impl* __tmp = new _Impl(*_M_impl, 1);
try
{
__tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
}
catch(...)
{
__tmp->_M_remove_reference();
__throw_exception_again;
}
return locale(__tmp);
}
template<typename _CharT, typename _Traits, typename _Alloc>
bool
locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
const basic_string<_CharT, _Traits, _Alloc>& __s2) const
{
typedef std::collate<_CharT> __collate_type;
const __collate_type& __collate = use_facet<__collate_type>(*this);
return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
__s2.data(), __s2.data() + __s2.length()) < 0);
}
// Generic version does nothing.
template<typename _CharT>
int
collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
{ return 0; }
// Generic version does nothing.
template<typename _CharT>
size_t
collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
{ return 0; }
template<typename _CharT>
int
collate<_CharT>::
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{
// strcoll assumes zero-terminated strings so we make a copy
// and then put a zero at the end.
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
const _CharT* __p = __one.c_str();
const _CharT* __pend = __one.data() + __one.length();
const _CharT* __q = __two.c_str();
const _CharT* __qend = __two.data() + __two.length();
// strcoll stops when it sees a nul character so we break
// the strings into zero-terminated substrings and pass those
// to strcoll.
for (;;)
{
const int __res = _M_compare(__p, __q);
if (__res)
return __res;
__p += char_traits<_CharT>::length(__p);
__q += char_traits<_CharT>::length(__q);
if (__p == __pend && __q == __qend)
return 0;
else if (__p == __pend)
return -1;
else if (__q == __qend)
return 1;
__p++;
__q++;
}
}
template<typename _CharT>
typename collate<_CharT>::string_type
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
string_type __ret;
// strxfrm assumes zero-terminated strings so we make a copy
const string_type __str(__lo, __hi);
const _CharT* __p = __str.c_str();
const _CharT* __pend = __str.data() + __str.length();
size_t __len = (__hi - __lo) * 2;
_CharT* __c = new _CharT[__len];
try
{
// strxfrm stops when it sees a nul character so we break
// the string into zero-terminated substrings and pass those
// to strxfrm.
for (;;)
{
// First try a buffer perhaps big enough.
size_t __res = _M_transform(__c, __p, __len);
// If the buffer was not large enough, try again with the
// correct size.
if (__res >= __len)
{
__len = __res + 1;
delete [] __c, __c = 0;
__c = new _CharT[__len];
__res = _M_transform(__c, __p, __len);
}
__ret.append(__c, __res);
__p += char_traits<_CharT>::length(__p);
if (__p == __pend)
break;
__p++;
__ret.push_back(_CharT());
}
}
catch(...)
{
delete [] __c;
__throw_exception_again;
}
delete [] __c;
return __ret;
}
template<typename _CharT>
long
collate<_CharT>::
do_hash(const _CharT* __lo, const _CharT* __hi) const
{
unsigned long __val = 0;
for (; __lo < __hi; ++__lo)
__val =
*__lo + ((__val << 7)
| (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
__digits - 7)));
return static_cast<long>(__val);
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class collate<char>;
extern template class collate_byname<char>;
extern template
const collate<char>&
use_facet<collate<char> >(const locale&);
extern template
bool
has_facet<collate<char> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class collate<wchar_t>;
extern template class collate_byname<wchar_t>;
extern template
const collate<wchar_t>&
use_facet<collate<wchar_t> >(const locale&);
extern template
bool
has_facet<collate<wchar_t> >(const locale&);
#endif
#endif
_GLIBCXX_END_NAMESPACE
#endif