localefwd.h revision 97403
197403Sobrien// Locale support -*- C++ -*-
297403Sobrien
397403Sobrien// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
1997403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien//
3297403Sobrien// ISO C++ 14882: 22.1  Locales
3397403Sobrien//
3497403Sobrien
3597403Sobrien/** @file localefwd.h
3697403Sobrien *  This is an internal header file, included by other library headers.
3797403Sobrien *  You should not attempt to use it directly.
3897403Sobrien */
3997403Sobrien
4097403Sobrien#ifndef _CPP_BITS_LOCCORE_H
4197403Sobrien#define _CPP_BITS_LOCCORE_H	1
4297403Sobrien
4397403Sobrien#pragma GCC system_header
4497403Sobrien
4597403Sobrien#include <bits/c++config.h>
4697403Sobrien#include <bits/c++locale.h>     // Defines __c_locale, config-specific includes
4797403Sobrien#include <climits>		// For CHAR_BIT
4897403Sobrien#include <cctype>		// For isspace, etc.
4997403Sobrien#include <string> 		// For string.
5097403Sobrien#include <bits/functexcept.h>
5197403Sobrien#include <bits/atomicity.h>
5297403Sobrien
5397403Sobriennamespace std
5497403Sobrien{
5597403Sobrien  // 22.1.1 Locale
5697403Sobrien  class locale;
5797403Sobrien
5897403Sobrien  // 22.1.3 Convenience interfaces
5997403Sobrien  template<typename _CharT>
6097403Sobrien    inline bool
6197403Sobrien    isspace(_CharT, const locale&);
6297403Sobrien
6397403Sobrien  template<typename _CharT>
6497403Sobrien    inline bool
6597403Sobrien    isprint(_CharT, const locale&);
6697403Sobrien
6797403Sobrien  template<typename _CharT>
6897403Sobrien    inline bool
6997403Sobrien    iscntrl(_CharT, const locale&);
7097403Sobrien
7197403Sobrien  template<typename _CharT>
7297403Sobrien    inline bool
7397403Sobrien    isupper(_CharT, const locale&);
7497403Sobrien
7597403Sobrien  template<typename _CharT>
7697403Sobrien    inline bool
7797403Sobrien    islower(_CharT, const locale&);
7897403Sobrien
7997403Sobrien  template<typename _CharT>
8097403Sobrien    inline bool
8197403Sobrien    isalpha(_CharT, const locale&);
8297403Sobrien
8397403Sobrien  template<typename _CharT>
8497403Sobrien    inline bool
8597403Sobrien    isdigit(_CharT, const locale&);
8697403Sobrien
8797403Sobrien  template<typename _CharT>
8897403Sobrien    inline bool
8997403Sobrien    ispunct(_CharT, const locale&);
9097403Sobrien
9197403Sobrien  template<typename _CharT>
9297403Sobrien    inline bool
9397403Sobrien    isxdigit(_CharT, const locale&);
9497403Sobrien
9597403Sobrien  template<typename _CharT>
9697403Sobrien    inline bool
9797403Sobrien    isalnum(_CharT, const locale&);
9897403Sobrien
9997403Sobrien  template<typename _CharT>
10097403Sobrien    inline bool
10197403Sobrien    isgraph(_CharT, const locale&);
10297403Sobrien
10397403Sobrien  template<typename _CharT>
10497403Sobrien    inline _CharT
10597403Sobrien    toupper(_CharT, const locale&);
10697403Sobrien
10797403Sobrien  template<typename _CharT>
10897403Sobrien    inline _CharT
10997403Sobrien    tolower(_CharT, const locale&);
11097403Sobrien
11197403Sobrien
11297403Sobrien  // 22.2.1 and 22.2.1.3 ctype
11397403Sobrien  class ctype_base;
11497403Sobrien  template<typename _CharT>
11597403Sobrien    class ctype;
11697403Sobrien  template<> class ctype<char>;
11797403Sobrien#ifdef _GLIBCPP_USE_WCHAR_T
11897403Sobrien  template<> class ctype<wchar_t>;
11997403Sobrien#endif
12097403Sobrien  template<typename _CharT>
12197403Sobrien    class ctype_byname;
12297403Sobrien  // NB: Specialized for char and wchar_t in locale_facets.h.
12397403Sobrien
12497403Sobrien  class codecvt_base;
12597403Sobrien  class __enc_traits;
12697403Sobrien  template<typename _InternT, typename _ExternT, typename _StateT>
12797403Sobrien    class codecvt;
12897403Sobrien  template<> class codecvt<char, char, mbstate_t>;
12997403Sobrien#ifdef _GLIBCPP_USE_WCHAR_T
13097403Sobrien  template<> class codecvt<wchar_t, char, mbstate_t>;
13197403Sobrien#endif
13297403Sobrien  template<typename _InternT, typename _ExternT, typename _StateT>
13397403Sobrien    class codecvt_byname;
13497403Sobrien
13597403Sobrien  // 22.2.2 and 22.2.3 numeric
13697403Sobrien  template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
13797403Sobrien    class num_get;
13897403Sobrien  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
13997403Sobrien    class num_put;
14097403Sobrien  template<typename _CharT> class numpunct;
14197403Sobrien  template<typename _CharT> class numpunct_byname;
14297403Sobrien
14397403Sobrien  // 22.2.4 collation
14497403Sobrien  template<typename _CharT>
14597403Sobrien    class collate;
14697403Sobrien  template<typename _CharT> class
14797403Sobrien    collate_byname;
14897403Sobrien
14997403Sobrien  // 22.2.5 date and time
15097403Sobrien  class time_base;
15197403Sobrien  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
15297403Sobrien    class time_get;
15397403Sobrien  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
15497403Sobrien    class time_get_byname;
15597403Sobrien  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
15697403Sobrien    class time_put;
15797403Sobrien  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
15897403Sobrien    class time_put_byname;
15997403Sobrien
16097403Sobrien  // 22.2.6 money
16197403Sobrien  class money_base;
16297403Sobrien  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
16397403Sobrien    class money_get;
16497403Sobrien  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
16597403Sobrien    class money_put;
16697403Sobrien  template<typename _CharT, bool _Intl = false>
16797403Sobrien    class moneypunct;
16897403Sobrien  template<typename _CharT, bool _Intl = false>
16997403Sobrien    class moneypunct_byname;
17097403Sobrien
17197403Sobrien  // 22.2.7 message retrieval
17297403Sobrien  class messages_base;
17397403Sobrien  template<typename _CharT>
17497403Sobrien    class messages;
17597403Sobrien  template<typename _CharT>
17697403Sobrien    class messages_byname;
17797403Sobrien
17897403Sobrien  // 22.1.1 Class locale
17997403Sobrien  class locale
18097403Sobrien  {
18197403Sobrien  public:
18297403Sobrien    // Types:
18397403Sobrien    typedef unsigned int 	category;
18497403Sobrien
18597403Sobrien    // Forward decls and friends:
18697403Sobrien    class facet;
18797403Sobrien    class id;
18897403Sobrien    class _Impl;
18997403Sobrien
19097403Sobrien    friend class facet;
19197403Sobrien    friend class _Impl;
19297403Sobrien
19397403Sobrien    template<typename _Facet>
19497403Sobrien      friend const _Facet&
19597403Sobrien      use_facet(const locale&);
19697403Sobrien
19797403Sobrien    template<typename _Facet>
19897403Sobrien      friend bool
19997403Sobrien      has_facet(const locale&) throw();
20097403Sobrien
20197403Sobrien    // Category values:
20297403Sobrien    // NB: Order must match _S_facet_categories definition in locale.cc
20397403Sobrien    static const category none		= 0;
20497403Sobrien    static const category ctype 	= 1L << 0;
20597403Sobrien    static const category numeric 	= 1L << 1;
20697403Sobrien    static const category collate  	= 1L << 2;
20797403Sobrien    static const category time 		= 1L << 3;
20897403Sobrien    static const category monetary 	= 1L << 4;
20997403Sobrien    static const category messages 	= 1L << 5;
21097403Sobrien    static const category all 		= (collate | ctype | monetary |
21197403Sobrien				 	   numeric | time  | messages);
21297403Sobrien
21397403Sobrien    // Construct/copy/destroy:
21497403Sobrien    locale() throw();
21597403Sobrien
21697403Sobrien    locale(const locale& __other) throw();
21797403Sobrien
21897403Sobrien    explicit
21997403Sobrien    locale(const char* __s);
22097403Sobrien
22197403Sobrien    locale(const locale& __base, const char* __s, category __cat);
22297403Sobrien
22397403Sobrien    locale(const locale& __base, const locale& __add, category __cat);
22497403Sobrien
22597403Sobrien    template<typename _Facet>
22697403Sobrien      locale(const locale& __other, _Facet* __f);
22797403Sobrien
22897403Sobrien    ~locale() throw();
22997403Sobrien
23097403Sobrien    const locale&
23197403Sobrien    operator=(const locale& __other) throw();
23297403Sobrien
23397403Sobrien    template<typename _Facet>
23497403Sobrien      locale
23597403Sobrien      combine(const locale& __other) const;
23697403Sobrien
23797403Sobrien    // Locale operations:
23897403Sobrien    string
23997403Sobrien    name() const;
24097403Sobrien
24197403Sobrien    bool
24297403Sobrien    operator==(const locale& __other) const throw ();
24397403Sobrien
24497403Sobrien    inline bool
24597403Sobrien    operator!=(const locale& __other) const throw ()
24697403Sobrien    { return !(this->operator==(__other));  }
24797403Sobrien
24897403Sobrien    template<typename _Char, typename _Traits, typename _Alloc>
24997403Sobrien      bool
25097403Sobrien      operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
25197403Sobrien		 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
25297403Sobrien
25397403Sobrien    // Global locale objects:
25497403Sobrien    static locale
25597403Sobrien    global(const locale&);
25697403Sobrien
25797403Sobrien    static const locale&
25897403Sobrien    classic();
25997403Sobrien
26097403Sobrien  private:
26197403Sobrien    // The (shared) implementation
26297403Sobrien    _Impl* 		_M_impl;
26397403Sobrien
26497403Sobrien    // The "C" reference locale
26597403Sobrien    static _Impl* 	_S_classic;
26697403Sobrien
26797403Sobrien    // Current global reference locale
26897403Sobrien    static _Impl* 	_S_global;
26997403Sobrien
27097403Sobrien    static const size_t	_S_num_categories = 6;
27197403Sobrien
27297403Sobrien    explicit
27397403Sobrien    locale(_Impl*) throw();
27497403Sobrien
27597403Sobrien    static inline void
27697403Sobrien    _S_initialize()
27797403Sobrien    {
27897403Sobrien      if (!_S_classic)
27997403Sobrien	classic();
28097403Sobrien    }
28197403Sobrien
28297403Sobrien    static category
28397403Sobrien    _S_normalize_category(category);
28497403Sobrien
28597403Sobrien    void
28697403Sobrien    _M_coalesce(const locale& __base, const locale& __add, category __cat);
28797403Sobrien  };
28897403Sobrien
28997403Sobrien
29097403Sobrien  // Implementation object for locale
29197403Sobrien  class locale::_Impl
29297403Sobrien  {
29397403Sobrien  public:
29497403Sobrien    // Friends.
29597403Sobrien    friend class locale;
29697403Sobrien    friend class locale::facet;
29797403Sobrien
29897403Sobrien    template<typename _Facet>
29997403Sobrien      friend const _Facet&
30097403Sobrien      use_facet(const locale&);
30197403Sobrien
30297403Sobrien    template<typename _Facet>
30397403Sobrien      friend bool
30497403Sobrien      has_facet(const locale&) throw();
30597403Sobrien
30697403Sobrien  private:
30797403Sobrien    // Data Members.
30897403Sobrien    _Atomic_word			_M_references;
30997403Sobrien    facet** 				_M_facets;
31097403Sobrien    size_t 				_M_facets_size;
31197403Sobrien    const char* 			_M_names[_S_num_categories];
31297403Sobrien    static const locale::id* const 	_S_id_ctype[];
31397403Sobrien    static const locale::id* const 	_S_id_numeric[];
31497403Sobrien    static const locale::id* const 	_S_id_collate[];
31597403Sobrien    static const locale::id* const 	_S_id_time[];
31697403Sobrien    static const locale::id* const 	_S_id_monetary[];
31797403Sobrien    static const locale::id* const 	_S_id_messages[];
31897403Sobrien    static const locale::id* const* const _S_facet_categories[];
31997403Sobrien
32097403Sobrien    inline void
32197403Sobrien    _M_add_reference() throw()
32297403Sobrien    { __atomic_add(&_M_references, 1); }
32397403Sobrien
32497403Sobrien    inline void
32597403Sobrien    _M_remove_reference() throw()
32697403Sobrien    {
32797403Sobrien      if (__exchange_and_add(&_M_references, -1) == 1)
32897403Sobrien	{
32997403Sobrien	  try
33097403Sobrien	    { delete this; }
33197403Sobrien	  catch(...)
33297403Sobrien	    { }
33397403Sobrien	}
33497403Sobrien    }
33597403Sobrien
33697403Sobrien    _Impl(const _Impl&, size_t);
33797403Sobrien    _Impl(const char*, size_t);
33897403Sobrien    _Impl(facet**, size_t, bool);
33997403Sobrien
34097403Sobrien   ~_Impl() throw();
34197403Sobrien
34297403Sobrien    _Impl(const _Impl&);  // Not defined.
34397403Sobrien
34497403Sobrien    void
34597403Sobrien    operator=(const _Impl&);  // Not defined.
34697403Sobrien
34797403Sobrien    inline bool
34897403Sobrien    _M_check_same_name()
34997403Sobrien    {
35097403Sobrien      bool __ret = true;
35197403Sobrien      for (size_t i = 0; __ret && i < _S_num_categories - 1; ++i)
35297403Sobrien	__ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0);
35397403Sobrien      return __ret;
35497403Sobrien    }
35597403Sobrien
35697403Sobrien    void
35797403Sobrien    _M_replace_categories(const _Impl*, category);
35897403Sobrien
35997403Sobrien    void
36097403Sobrien    _M_replace_category(const _Impl*, const locale::id* const*);
36197403Sobrien
36297403Sobrien    void
36397403Sobrien    _M_replace_facet(const _Impl*, const locale::id*);
36497403Sobrien
36597403Sobrien    void
36697403Sobrien    _M_install_facet(const locale::id*, facet*);
36797403Sobrien
36897403Sobrien    template<typename _Facet>
36997403Sobrien      inline void
37097403Sobrien      _M_init_facet(_Facet* __facet)
37197403Sobrien      { _M_install_facet(&_Facet::id, __facet);  }
37297403Sobrien  };
37397403Sobrien
37497403Sobrien  template<typename _Facet>
37597403Sobrien    locale::locale(const locale& __other, _Facet* __f)
37697403Sobrien    {
37797403Sobrien      _M_impl = new _Impl(*__other._M_impl, 1);
37897403Sobrien      _M_impl->_M_install_facet(&_Facet::id, __f);
37997403Sobrien      for (size_t __i = 0; __i < _S_num_categories; ++__i)
38097403Sobrien	_M_impl->_M_names[__i] = "*";
38197403Sobrien    }
38297403Sobrien
38397403Sobrien  // 22.1.1.1.2  Class locale::facet
38497403Sobrien  class locale::facet
38597403Sobrien  {
38697403Sobrien  private:
38797403Sobrien    friend class locale;
38897403Sobrien    friend class locale::_Impl;
38997403Sobrien
39097403Sobrien    _Atomic_word _M_references;
39197403Sobrien
39297403Sobrien  protected:
39397403Sobrien    // Contains data from the underlying "C" library for default "C"
39497403Sobrien    // or "POSIX" locale.
39597403Sobrien    static __c_locale		     _S_c_locale;
39697403Sobrien
39797403Sobrien    explicit
39897403Sobrien    facet(size_t __refs = 0) throw();
39997403Sobrien
40097403Sobrien    virtual
40197403Sobrien    ~facet();
40297403Sobrien
40397403Sobrien    static void
40497403Sobrien    _S_create_c_locale(__c_locale& __cloc, const char* __s,
40597403Sobrien		       __c_locale __old = 0);
40697403Sobrien
40797403Sobrien    static __c_locale
40897403Sobrien    _S_clone_c_locale(__c_locale& __cloc);
40997403Sobrien
41097403Sobrien    static void
41197403Sobrien    _S_destroy_c_locale(__c_locale& __cloc);
41297403Sobrien
41397403Sobrien  private:
41497403Sobrien    void
41597403Sobrien    _M_add_reference() throw();
41697403Sobrien
41797403Sobrien    void
41897403Sobrien    _M_remove_reference() throw();
41997403Sobrien
42097403Sobrien    facet(const facet&);  // Not defined.
42197403Sobrien
42297403Sobrien    void
42397403Sobrien    operator=(const facet&);  // Not defined.
42497403Sobrien  };
42597403Sobrien
42697403Sobrien
42797403Sobrien  // 22.1.1.1.3 Class locale::id
42897403Sobrien  class locale::id
42997403Sobrien  {
43097403Sobrien  private:
43197403Sobrien    friend class locale;
43297403Sobrien    friend class locale::_Impl;
43397403Sobrien    template<typename _Facet>
43497403Sobrien      friend const _Facet&
43597403Sobrien      use_facet(const locale&);
43697403Sobrien    template<typename _Facet>
43797403Sobrien      friend bool
43897403Sobrien      has_facet(const locale&) throw ();
43997403Sobrien
44097403Sobrien    // NB: There is no accessor for _M_index because it may be used
44197403Sobrien    // before the constructor is run; the effect of calling a member
44297403Sobrien    // function (even an inline) would be undefined.
44397403Sobrien    mutable size_t 		_M_index;
44497403Sobrien
44597403Sobrien    // Last id number assigned.
44697403Sobrien    static _Atomic_word 	_S_highwater;
44797403Sobrien
44897403Sobrien    void
44997403Sobrien    operator=(const id&);  // Not defined.
45097403Sobrien
45197403Sobrien    id(const id&);  // Not defined.
45297403Sobrien
45397403Sobrien  public:
45497403Sobrien    // NB: This class is always a static data member, and thus can be
45597403Sobrien    // counted on to be zero-initialized.
45697403Sobrien    id();
45797403Sobrien
45897403Sobrien    inline size_t
45997403Sobrien    _M_id() const
46097403Sobrien    {
46197403Sobrien      if (!_M_index)
46297403Sobrien	_M_index = 1 + __exchange_and_add(&_S_highwater, 1);
46397403Sobrien      return _M_index - 1;
46497403Sobrien    }
46597403Sobrien  };
46697403Sobrien
46797403Sobrien  template<typename _Facet>
46897403Sobrien    const _Facet&
46997403Sobrien    use_facet(const locale& __loc);
47097403Sobrien
47197403Sobrien  template<typename _Facet>
47297403Sobrien    bool
47397403Sobrien    has_facet(const locale& __loc) throw();
47497403Sobrien} // namespace std
47597403Sobrien
47697403Sobrien#endif
477