| /*************************************************************************** |
| * |
| * _facet.h - definition of the std::locale::facet and locale::id classes |
| * |
| * This is an internal header file used to implement the C++ Standard |
| * Library. It should never be #included directly by a program. |
| * |
| * $Id$ |
| * |
| *************************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. See the License for the specific language governing |
| * permissions and limitations under the License. |
| * |
| * Copyright 1994-2006 Rogue Wave Software. |
| * |
| **************************************************************************/ |
| |
| #ifndef _RWSTD_LOC_FACET_H_INCLUDED |
| #define _RWSTD_LOC_FACET_H_INCLUDED |
| |
| |
| #include <rw/_mutex.h> |
| #include <rw/_defs.h> |
| |
| |
| _RWSTD_NAMESPACE (std) { |
| } // namespace std |
| |
| _RWSTD_NAMESPACE (_V3_LOCALE) { |
| |
| #ifndef _MSC_VER |
| // make _V3_LOCALE think it's std (if it isn't) to avoid |
| // having to qualify all references to standard names with _STD:: |
| _USING (namespace std); |
| |
| #endif |
| |
| struct _RWSTD_CLASS_EXPORT locale; |
| |
| } // namespace _V3_LOCALE |
| |
| |
| _RWSTD_NAMESPACE (__rw) { |
| |
| class _RWSTD_EXPORT __rw_locale; |
| |
| struct __rw_access; |
| |
| struct _RWSTD_EXPORT __rw_facet: __rw_synchronized |
| { |
| // the type of a "constructor" function used to create facet objects |
| // of standard types by the library |
| typedef __rw_facet* (_C_ctor_t)(_RWSTD_SIZE_T, const char*); |
| |
| _EXPLICIT __rw_facet (_RWSTD_SIZE_T = 0); |
| |
| virtual ~__rw_facet (); |
| |
| // types of standard facets; only globally managed facets (i.e., |
| // standard facets created internally) set this member, user-created |
| // facet objects of any types set their type to _C_unknown |
| |
| // NOTE: the values and order of all the enumerators below are important |
| // any changes may affect the binary compatibility of the library |
| |
| enum _C_facet_type { |
| /* -1 */ _C_invalid = -1, // marked e.g., when deleted |
| /* 0 */ _C_unknown = 0, // user-defined |
| |
| // narrow character specializations |
| |
| // classic versions // byname versions |
| // |
| /* id */ // <-- facet id, i.e. the value of Facet::id._C_val |
| |
| // collate category |
| /* 1 */ _C_collate, _C_collate_byname, |
| // ctype category |
| /* 3 */ _C_codecvt, _C_codecvt_byname, |
| /* 5 */ _C_ctype, _C_ctype_byname, |
| // monetary category |
| /* 7 */ _C_moneypunct, _C_moneypunct_byname, |
| /* 9 */ _C_moneypunct_intl, _C_moneypunct_intl_byname, |
| /* 11 */ _C_money_get, _C_nonexistent_0, |
| /* 13 */ _C_money_put, _C_nonexistent_1, |
| // numeric category |
| /* 15 */ _C_numpunct, _C_numpunct_byname, |
| /* 17 */ _C_num_get, _C_nonexistent_2, |
| /* 19 */ _C_num_put, _C_nonexistent_3, |
| // time category |
| /* 21 */ _C_time_get, _C_time_get_byname, |
| /* 23 */ _C_time_put, _C_time_put_byname, |
| // messages category |
| /* 25 */ _C_messages, _C_messages_byname, |
| |
| // wide character specializations |
| |
| // classic versions // byname versions |
| /* 27 */ _C_wcollate, _C_wcollate_byname, |
| /* 29 */ _C_wcodecvt, _C_wcodecvt_byname, |
| /* 31 */ _C_wctype, _C_wctype_byname, |
| /* 33 */ _C_wmoneypunct, _C_wmoneypunct_byname, |
| /* 35 */ _C_wmoneypunct_intl, _C_wmoneypunct_intl_byname, |
| /* 37 */ _C_wmoney_get, _C_nonexistent_4, |
| /* 39 */ _C_wmoney_put, _C_nonexistent_5, |
| /* 41 */ _C_wnumpunct, _C_wnumpunct_byname, |
| /* 43 */ _C_wnum_get, _C_nonexistent_6, |
| /* 45 */ _C_wnum_put, _C_nonexistent_7, |
| /* 47 */ _C_wtime_get, _C_wtime_get_byname, |
| /* 49 */ _C_wtime_put, _C_wtime_put_byname, |
| /* 51 */ _C_wmessages, _C_wmessages_byname, |
| |
| // the value of each standard facet's id is computed |
| // as (facet_type + 1) / 2; the value is stored in |
| // each facet's *__rw_facet::_C_pid member |
| |
| // the value of the first available (non-standard) |
| // facet's id is computed as (_C_last_type / 2 + 1) |
| |
| // note that this value determines the binary footprint of each facet |
| // changing it affects the binary compatibility of the localization |
| // library |
| /* 52 */ _C_last_type = _C_wmessages_byname |
| }; |
| |
| // unique fundamental type id |
| enum _C_type_id { |
| _C_signed = 0x100, _C_ptr = 0x200, _C_cont = 0x400, |
| _C_integral = 0x800, _C_floating = 0x1000, _C_typemask = 0x00ff, |
| _C_bool = 0, |
| _C_char = 1 | _C_integral, |
| _C_uchar = 2 | _C_integral, _C_schar = _C_uchar | _C_signed, |
| _C_ushort = 3 | _C_integral, _C_short = _C_ushort | _C_signed, |
| _C_uint = 4 | _C_integral, _C_int = _C_uint | _C_signed, |
| _C_ulong = 5 | _C_integral, _C_long = _C_ulong | _C_signed, |
| _C_ullong = 6 | _C_integral, _C_llong = _C_ullong | _C_signed, |
| _C_float = 7 | _C_floating, |
| _C_double = 8 | _C_floating, |
| _C_ldouble = 9 | _C_floating, |
| _C_void = 10, _C_pvoid = _C_void | _C_ptr, |
| _C_wchar_t = 11 |
| }; |
| |
| enum { |
| // SunOS prepends the separator charater to the beginning |
| // of locale names, e.g., "/en_US/de_DE/fr_FR/..." |
| _C_prepend_cat_sep = 0x01, |
| |
| // Linux uses the names of LC_XXX constants in combined |
| // locale names, |
| // e.g., "LC_CYPE=en_US;LC_COLLATE=de_DE;LC_MONETARY=fr_FR..." |
| _C_use_cat_names = 0x02, |
| |
| // HP-UX, for instance, keeps even trivial locale names |
| // fully expanded |
| // (e.g., setlocale ("C") will return "C C C C C C") |
| // and doesn't include category names in (combined or others) |
| // locale names |
| _C_condensed_name = 0x04, |
| |
| // bits to determine whether and when libc locale will be |
| // used as an implementation of C++ locale functionality |
| // |
| // libc libstd effect |
| // 0 0 use own implementation, fall back on libc if that fails |
| // 0 1 use own implementation only, never libc |
| // 1 0 use libc implementation only, never own |
| // 1 1 try libc implementation first, own if that fails |
| _C_use_libc = 0x08, |
| _C_use_libstd = 0x10 |
| }; |
| |
| // global options controlling the behavior of locale and facets |
| static int _C_opts; |
| |
| // returns a pointer to the facet's implementation data |
| // if it exists, 0 otherwise |
| const void* _C_data () const { |
| return _C_impsize ? _C_impdata |
| : _RWSTD_CONST_CAST (__rw_facet*, this)->_C_get_data (); |
| } |
| |
| const char* _C_get_name () const { |
| return _C_name ? _C_name : "C"; |
| } |
| |
| protected: |
| |
| typedef __rw_facet* (*_C_factory_f)(void*); |
| |
| // set facet locale name (will allocate if bufsize is too small) |
| void _C_set_name (const char*, char*, _RWSTD_SIZE_T); |
| |
| const char *_C_name; // name of locale associated with facet |
| char *_C_buf; // character buffer name may be stored in |
| const void *_C_impdata; // implementation data (e.g., punct) |
| _RWSTD_SIZE_T _C_impsize; // size of implementation data |
| |
| private: |
| |
| _C_facet_type _C_type; // facet type (see above) |
| _RWSTD_SIZE_T _C_ref; // reference count (> 0) |
| _RWSTD_SIZE_T *_C_pid; // pointer to the static Facet::id._C_id |
| |
| // standard facets' id's are computed as (_C_type + 1) / 2 |
| // standard facet's base type is computed as 2 * Facet::id._C_id - 1 |
| |
| __rw_facet (const __rw_facet&); // not defined |
| void operator= (const __rw_facet&); // not defined |
| |
| const void* _C_get_data (); |
| |
| static __rw_facet* |
| _C_manage (__rw_facet*, _C_facet_type, const char*, _C_ctor_t*); |
| |
| friend struct _V3_LOCALE::locale; |
| friend class __rw_locale; |
| friend struct __rw_facet_id; |
| friend struct __rw_access; |
| }; |
| |
| |
| struct _RWSTD_EXPORT __rw_facet_id |
| { |
| #ifdef _RWSTD_NO_SPECIALIZED_FACET_ID |
| |
| __rw_facet_id () { |
| // _C_id member zero-initialized (i.e., invalidated) by the system |
| // for __rw_facet_id objects with static storage duration, the only |
| // ones locale ever references |
| } |
| |
| #else // if !defined (_RWSTD_NO_SPECIALIZED_FACET_ID) |
| |
| enum _C_init_id { _C_Init }; |
| |
| __rw_facet_id (_C_init_id = _C_Init) { |
| // same as above except that Facet::id is explicitly specialized |
| // for all standard facet base classes in order to guarantee one |
| // instance of each in a program; the definition of the explicit |
| // specialization is distinguished from the declaration by the |
| // presence of an initializer |
| } |
| |
| #endif // _RWSTD_NO_SPECIALIZED_FACET_ID |
| |
| private: |
| |
| __rw_facet_id (const __rw_facet_id&); // not defined |
| void operator= (const __rw_facet_id&); // not defined |
| |
| // initialize id to the given value if within the valid range |
| // otherwise to the next value generated by the id generator |
| _RWSTD_SIZE_T _C_init () const; |
| |
| _MUTABLE _RWSTD_SIZE_T _C_id; // unique id > 0 |
| |
| friend class __rw_locale; |
| friend struct _V3_LOCALE::locale; |
| friend struct __rw_access; |
| }; |
| |
| |
| // does the necessary path calculations and mapping of locale databases |
| const void* |
| __rw_get_facet_data (int, _RWSTD_SIZE_T&, const char*, const char* = 0); |
| |
| // its counterpart - does the database unmapping |
| void __rw_release_facet_data (const void*, _RWSTD_SIZE_T); |
| |
| } // namespace __rw |
| |
| |
| #endif // _RWSTD_LOC_FACET_H_INCLUDED |