localefwd.h revision 110614
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 		= (ctype | numeric | collate |
211				 	   time  | monetary | 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 locale
268    static _Impl* 	_S_global;
269
270    // Number of standard categories. For C++, these categories are
271    // collate, ctype, monetary, numeric, time, and messages. These
272    // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
273    // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
274    // 1003.1-2001) specifies LC_MESSAGES.
275    static const size_t	_S_categories_size = 6;
276
277    // In addition to the standard categories, the underlying
278    // operating system is allowed to define extra LC_*
279    // macros. For GNU systems, the following are also valid:
280    // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
281    // and LC_IDENTIFICATION.
282    static const size_t	_S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES;
283
284    // Names of underlying locale categories.
285    // NB: locale::global() has to know how to modify all the
286    // underlying categories, not just the ones required by the C++
287    // standard.
288    static const char* 	_S_categories[_S_categories_size
289				      + _S_extra_categories_size];
290
291    explicit
292    locale(_Impl*) throw();
293
294    static inline void
295    _S_initialize()
296    {
297      if (!_S_classic)
298	classic();
299    }
300
301    static category
302    _S_normalize_category(category);
303
304    void
305    _M_coalesce(const locale& __base, const locale& __add, category __cat);
306  };
307
308
309  // Implementation object for locale
310  class locale::_Impl
311  {
312  public:
313    // Friends.
314    friend class locale;
315    friend class locale::facet;
316
317    template<typename _Facet>
318      friend const _Facet&
319      use_facet(const locale&);
320
321    template<typename _Facet>
322      friend bool
323      has_facet(const locale&) throw();
324
325  private:
326    // Data Members.
327    _Atomic_word			_M_references;
328    facet** 				_M_facets;
329    size_t 				_M_facets_size;
330
331    char* 				_M_names[_S_categories_size
332						 + _S_extra_categories_size];
333    static const locale::id* const 	_S_id_ctype[];
334    static const locale::id* const 	_S_id_numeric[];
335    static const locale::id* const 	_S_id_collate[];
336    static const locale::id* const 	_S_id_time[];
337    static const locale::id* const 	_S_id_monetary[];
338    static const locale::id* const 	_S_id_messages[];
339    static const locale::id* const* const _S_facet_categories[];
340
341    inline void
342    _M_add_reference() throw()
343    { __atomic_add(&_M_references, 1); }
344
345    inline void
346    _M_remove_reference() throw()
347    {
348      if (__exchange_and_add(&_M_references, -1) == 1)
349	{
350	  try
351	    { delete this; }
352	  catch(...)
353	    { }
354	}
355    }
356
357    _Impl(const _Impl&, size_t);
358    _Impl(const char*, size_t);
359    _Impl(facet**, size_t, bool);
360
361   ~_Impl() throw();
362
363    _Impl(const _Impl&);  // Not defined.
364
365    void
366    operator=(const _Impl&);  // Not defined.
367
368    inline bool
369    _M_check_same_name()
370    {
371      bool __ret = true;
372      for (size_t __i = 0;
373	   __ret && __i < _S_categories_size + _S_extra_categories_size - 1;
374	   ++__i)
375	__ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0);
376      return __ret;
377    }
378
379    void
380    _M_replace_categories(const _Impl*, category);
381
382    void
383    _M_replace_category(const _Impl*, const locale::id* const*);
384
385    void
386    _M_replace_facet(const _Impl*, const locale::id*);
387
388    void
389    _M_install_facet(const locale::id*, facet*);
390
391    template<typename _Facet>
392      inline void
393      _M_init_facet(_Facet* __facet)
394      { _M_install_facet(&_Facet::id, __facet);  }
395  };
396
397  template<typename _Facet>
398    locale::locale(const locale& __other, _Facet* __f)
399    {
400      _M_impl = new _Impl(*__other._M_impl, 1);
401      _M_impl->_M_install_facet(&_Facet::id, __f);
402      for (size_t __i = 0;
403	   __i < _S_categories_size + _S_extra_categories_size; ++__i)
404	{
405	  delete [] _M_impl->_M_names[__i];
406	  char* __new = new char[2];
407	  strcpy(__new, "*");
408	  _M_impl->_M_names[__i] = __new;
409	}
410    }
411
412  // 22.1.1.1.2  Class locale::facet
413  class locale::facet
414  {
415  private:
416    friend class locale;
417    friend class locale::_Impl;
418
419    _Atomic_word _M_references;
420
421  protected:
422    // Contains data from the underlying "C" library for for the
423    // classic locale.
424    static __c_locale	      		_S_c_locale;
425
426    // String literal for the name of the classic locale.
427    static char                        	_S_c_name[2];
428
429    explicit
430    facet(size_t __refs = 0) throw();
431
432    virtual
433    ~facet();
434
435    static void
436    _S_create_c_locale(__c_locale& __cloc, const char* __s,
437		       __c_locale __old = 0);
438
439    static __c_locale
440    _S_clone_c_locale(__c_locale& __cloc);
441
442    static void
443    _S_destroy_c_locale(__c_locale& __cloc);
444
445  private:
446    void
447    _M_add_reference() throw();
448
449    void
450    _M_remove_reference() throw();
451
452    facet(const facet&);  // Not defined.
453
454    void
455    operator=(const facet&);  // Not defined.
456  };
457
458
459  // 22.1.1.1.3 Class locale::id
460  class locale::id
461  {
462  private:
463    friend class locale;
464    friend class locale::_Impl;
465    template<typename _Facet>
466      friend const _Facet&
467      use_facet(const locale&);
468    template<typename _Facet>
469      friend bool
470      has_facet(const locale&) throw ();
471
472    // NB: There is no accessor for _M_index because it may be used
473    // before the constructor is run; the effect of calling a member
474    // function (even an inline) would be undefined.
475    mutable size_t 		_M_index;
476
477    // Last id number assigned.
478    static _Atomic_word 	_S_highwater;
479
480    void
481    operator=(const id&);  // Not defined.
482
483    id(const id&);  // Not defined.
484
485  public:
486    // NB: This class is always a static data member, and thus can be
487    // counted on to be zero-initialized.
488    id();
489
490    inline size_t
491    _M_id() const
492    {
493      if (!_M_index)
494	_M_index = 1 + __exchange_and_add(&_S_highwater, 1);
495      return _M_index - 1;
496    }
497  };
498
499  template<typename _Facet>
500    const _Facet&
501    use_facet(const locale& __loc);
502
503  template<typename _Facet>
504    bool
505    has_facet(const locale& __loc) throw();
506} // namespace std
507
508#endif
509