OSDN Git Service

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