localefwd.h revision 97403
1// Locale support -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31//
32// ISO C++ 14882: 22.1  Locales
33//
34
35/** @file localefwd.h
36 *  This is an internal header file, included by other library headers.
37 *  You should not attempt to use it directly.
38 */
39
40#ifndef _CPP_BITS_LOCCORE_H
41#define _CPP_BITS_LOCCORE_H	1
42
43#pragma GCC system_header
44
45#include <bits/c++config.h>
46#include <bits/c++locale.h>     // Defines __c_locale, config-specific includes
47#include <climits>		// For CHAR_BIT
48#include <cctype>		// For isspace, etc.
49#include <string> 		// For string.
50#include <bits/functexcept.h>
51#include <bits/atomicity.h>
52
53namespace std
54{
55  // 22.1.1 Locale
56  class locale;
57
58  // 22.1.3 Convenience interfaces
59  template<typename _CharT>
60    inline bool
61    isspace(_CharT, const locale&);
62
63  template<typename _CharT>
64    inline bool
65    isprint(_CharT, const locale&);
66
67  template<typename _CharT>
68    inline bool
69    iscntrl(_CharT, const locale&);
70
71  template<typename _CharT>
72    inline bool
73    isupper(_CharT, const locale&);
74
75  template<typename _CharT>
76    inline bool
77    islower(_CharT, const locale&);
78
79  template<typename _CharT>
80    inline bool
81    isalpha(_CharT, const locale&);
82
83  template<typename _CharT>
84    inline bool
85    isdigit(_CharT, const locale&);
86
87  template<typename _CharT>
88    inline bool
89    ispunct(_CharT, const locale&);
90
91  template<typename _CharT>
92    inline bool
93    isxdigit(_CharT, const locale&);
94
95  template<typename _CharT>
96    inline bool
97    isalnum(_CharT, const locale&);
98
99  template<typename _CharT>
100    inline bool
101    isgraph(_CharT, const locale&);
102
103  template<typename _CharT>
104    inline _CharT
105    toupper(_CharT, const locale&);
106
107  template<typename _CharT>
108    inline _CharT
109    tolower(_CharT, const locale&);
110
111
112  // 22.2.1 and 22.2.1.3 ctype
113  class ctype_base;
114  template<typename _CharT>
115    class ctype;
116  template<> class ctype<char>;
117#ifdef _GLIBCPP_USE_WCHAR_T
118  template<> class ctype<wchar_t>;
119#endif
120  template<typename _CharT>
121    class ctype_byname;
122  // NB: Specialized for char and wchar_t in locale_facets.h.
123
124  class codecvt_base;
125  class __enc_traits;
126  template<typename _InternT, typename _ExternT, typename _StateT>
127    class codecvt;
128  template<> class codecvt<char, char, mbstate_t>;
129#ifdef _GLIBCPP_USE_WCHAR_T
130  template<> class codecvt<wchar_t, char, mbstate_t>;
131#endif
132  template<typename _InternT, typename _ExternT, typename _StateT>
133    class codecvt_byname;
134
135  // 22.2.2 and 22.2.3 numeric
136  template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> >
137    class num_get;
138  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
139    class num_put;
140  template<typename _CharT> class numpunct;
141  template<typename _CharT> class numpunct_byname;
142
143  // 22.2.4 collation
144  template<typename _CharT>
145    class collate;
146  template<typename _CharT> class
147    collate_byname;
148
149  // 22.2.5 date and time
150  class time_base;
151  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
152    class time_get;
153  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
154    class time_get_byname;
155  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
156    class time_put;
157  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
158    class time_put_byname;
159
160  // 22.2.6 money
161  class money_base;
162  template<typename _CharT, typename _InIter =  istreambuf_iterator<_CharT> >
163    class money_get;
164  template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> >
165    class money_put;
166  template<typename _CharT, bool _Intl = false>
167    class moneypunct;
168  template<typename _CharT, bool _Intl = false>
169    class moneypunct_byname;
170
171  // 22.2.7 message retrieval
172  class messages_base;
173  template<typename _CharT>
174    class messages;
175  template<typename _CharT>
176    class messages_byname;
177
178  // 22.1.1 Class locale
179  class locale
180  {
181  public:
182    // Types:
183    typedef unsigned int 	category;
184
185    // Forward decls and friends:
186    class facet;
187    class id;
188    class _Impl;
189
190    friend class facet;
191    friend class _Impl;
192
193    template<typename _Facet>
194      friend const _Facet&
195      use_facet(const locale&);
196
197    template<typename _Facet>
198      friend bool
199      has_facet(const locale&) throw();
200
201    // Category values:
202    // NB: Order must match _S_facet_categories definition in locale.cc
203    static const category none		= 0;
204    static const category ctype 	= 1L << 0;
205    static const category numeric 	= 1L << 1;
206    static const category collate  	= 1L << 2;
207    static const category time 		= 1L << 3;
208    static const category monetary 	= 1L << 4;
209    static const category messages 	= 1L << 5;
210    static const category all 		= (collate | ctype | monetary |
211				 	   numeric | time  | messages);
212
213    // Construct/copy/destroy:
214    locale() throw();
215
216    locale(const locale& __other) throw();
217
218    explicit
219    locale(const char* __s);
220
221    locale(const locale& __base, const char* __s, category __cat);
222
223    locale(const locale& __base, const locale& __add, category __cat);
224
225    template<typename _Facet>
226      locale(const locale& __other, _Facet* __f);
227
228    ~locale() throw();
229
230    const locale&
231    operator=(const locale& __other) throw();
232
233    template<typename _Facet>
234      locale
235      combine(const locale& __other) const;
236
237    // Locale operations:
238    string
239    name() const;
240
241    bool
242    operator==(const locale& __other) const throw ();
243
244    inline bool
245    operator!=(const locale& __other) const throw ()
246    { return !(this->operator==(__other));  }
247
248    template<typename _Char, typename _Traits, typename _Alloc>
249      bool
250      operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
251		 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
252
253    // Global locale objects:
254    static locale
255    global(const locale&);
256
257    static const locale&
258    classic();
259
260  private:
261    // The (shared) implementation
262    _Impl* 		_M_impl;
263
264    // The "C" reference locale
265    static _Impl* 	_S_classic;
266
267    // Current global reference locale
268    static _Impl* 	_S_global;
269
270    static const size_t	_S_num_categories = 6;
271
272    explicit
273    locale(_Impl*) throw();
274
275    static inline void
276    _S_initialize()
277    {
278      if (!_S_classic)
279	classic();
280    }
281
282    static category
283    _S_normalize_category(category);
284
285    void
286    _M_coalesce(const locale& __base, const locale& __add, category __cat);
287  };
288
289
290  // Implementation object for locale
291  class locale::_Impl
292  {
293  public:
294    // Friends.
295    friend class locale;
296    friend class locale::facet;
297
298    template<typename _Facet>
299      friend const _Facet&
300      use_facet(const locale&);
301
302    template<typename _Facet>
303      friend bool
304      has_facet(const locale&) throw();
305
306  private:
307    // Data Members.
308    _Atomic_word			_M_references;
309    facet** 				_M_facets;
310    size_t 				_M_facets_size;
311    const char* 			_M_names[_S_num_categories];
312    static const locale::id* const 	_S_id_ctype[];
313    static const locale::id* const 	_S_id_numeric[];
314    static const locale::id* const 	_S_id_collate[];
315    static const locale::id* const 	_S_id_time[];
316    static const locale::id* const 	_S_id_monetary[];
317    static const locale::id* const 	_S_id_messages[];
318    static const locale::id* const* const _S_facet_categories[];
319
320    inline void
321    _M_add_reference() throw()
322    { __atomic_add(&_M_references, 1); }
323
324    inline void
325    _M_remove_reference() throw()
326    {
327      if (__exchange_and_add(&_M_references, -1) == 1)
328	{
329	  try
330	    { delete this; }
331	  catch(...)
332	    { }
333	}
334    }
335
336    _Impl(const _Impl&, size_t);
337    _Impl(const char*, size_t);
338    _Impl(facet**, size_t, bool);
339
340   ~_Impl() throw();
341
342    _Impl(const _Impl&);  // Not defined.
343
344    void
345    operator=(const _Impl&);  // Not defined.
346
347    inline bool
348    _M_check_same_name()
349    {
350      bool __ret = true;
351      for (size_t i = 0; __ret && i < _S_num_categories - 1; ++i)
352	__ret &= (strcmp(_M_names[i], _M_names[i + 1]) == 0);
353      return __ret;
354    }
355
356    void
357    _M_replace_categories(const _Impl*, category);
358
359    void
360    _M_replace_category(const _Impl*, const locale::id* const*);
361
362    void
363    _M_replace_facet(const _Impl*, const locale::id*);
364
365    void
366    _M_install_facet(const locale::id*, facet*);
367
368    template<typename _Facet>
369      inline void
370      _M_init_facet(_Facet* __facet)
371      { _M_install_facet(&_Facet::id, __facet);  }
372  };
373
374  template<typename _Facet>
375    locale::locale(const locale& __other, _Facet* __f)
376    {
377      _M_impl = new _Impl(*__other._M_impl, 1);
378      _M_impl->_M_install_facet(&_Facet::id, __f);
379      for (size_t __i = 0; __i < _S_num_categories; ++__i)
380	_M_impl->_M_names[__i] = "*";
381    }
382
383  // 22.1.1.1.2  Class locale::facet
384  class locale::facet
385  {
386  private:
387    friend class locale;
388    friend class locale::_Impl;
389
390    _Atomic_word _M_references;
391
392  protected:
393    // Contains data from the underlying "C" library for default "C"
394    // or "POSIX" locale.
395    static __c_locale		     _S_c_locale;
396
397    explicit
398    facet(size_t __refs = 0) throw();
399
400    virtual
401    ~facet();
402
403    static void
404    _S_create_c_locale(__c_locale& __cloc, const char* __s,
405		       __c_locale __old = 0);
406
407    static __c_locale
408    _S_clone_c_locale(__c_locale& __cloc);
409
410    static void
411    _S_destroy_c_locale(__c_locale& __cloc);
412
413  private:
414    void
415    _M_add_reference() throw();
416
417    void
418    _M_remove_reference() throw();
419
420    facet(const facet&);  // Not defined.
421
422    void
423    operator=(const facet&);  // Not defined.
424  };
425
426
427  // 22.1.1.1.3 Class locale::id
428  class locale::id
429  {
430  private:
431    friend class locale;
432    friend class locale::_Impl;
433    template<typename _Facet>
434      friend const _Facet&
435      use_facet(const locale&);
436    template<typename _Facet>
437      friend bool
438      has_facet(const locale&) throw ();
439
440    // NB: There is no accessor for _M_index because it may be used
441    // before the constructor is run; the effect of calling a member
442    // function (even an inline) would be undefined.
443    mutable size_t 		_M_index;
444
445    // Last id number assigned.
446    static _Atomic_word 	_S_highwater;
447
448    void
449    operator=(const id&);  // Not defined.
450
451    id(const id&);  // Not defined.
452
453  public:
454    // NB: This class is always a static data member, and thus can be
455    // counted on to be zero-initialized.
456    id();
457
458    inline size_t
459    _M_id() const
460    {
461      if (!_M_index)
462	_M_index = 1 + __exchange_and_add(&_S_highwater, 1);
463      return _M_index - 1;
464    }
465  };
466
467  template<typename _Facet>
468    const _Facet&
469    use_facet(const locale& __loc);
470
471  template<typename _Facet>
472    bool
473    has_facet(const locale& __loc) throw();
474} // namespace std
475
476#endif
477