// Locale support -*- C++ -*-
-// Copyright (C) 1997-2000 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// ISO C++ 14882: 22.1 Locales
//
+/** @file localefwd.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
#ifndef _CPP_BITS_LOCCORE_H
#define _CPP_BITS_LOCCORE_H 1
+#pragma GCC system_header
+
#include <bits/c++config.h>
-#include <bits/std_climits.h> // For CHAR_BIT
-#include <bits/std_string.h> // For string
-#include <bits/std_cctype.h> // For isspace, etc.
+#include <bits/c++locale.h> // Defines __c_locale, config-specific includes
+#include <climits> // For CHAR_BIT
+#include <cctype> // For isspace, etc.
+#include <string> // For string
+#include <bits/functexcept.h>
+
+#include <bits/atomicity.h>
namespace std
{
-
- // _Count_ones: compile-time computation of number of 1-bits in a value N
- // This takes only 5 (or 6) instantiations, doing recursive descent
- // in parallel -- ncm
- template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
- unsigned int _Mask = (~0u >> _Shift) >
- struct _Count_ones;
-
- // It is preferable to use enumerators instead of integral static data
- // members to avoid emission of superflous variables -- gdr.
- template<unsigned int _Num, unsigned int _Mask>
- struct _Count_ones<_Num, 0, _Mask>
- {
- enum
- {
- _S_count = _Num
- };
- };
-
- template<unsigned int _Num, int _Shift, unsigned int _Mask>
- struct _Count_ones
- {
- enum
- {
- _S_halfcount = _Count_ones<_Num, _Shift/2,
- (_Mask^((~_Mask)>>(_Shift/2))) >::_S_count,
- _S_count = (_S_halfcount&_Mask) + ((_S_halfcount>>_Shift)&_Mask)
- };
- };
+ // NB: Don't instantiate required wchar_t facets if no wchar_t support.
+#ifdef _GLIBCPP_USE_WCHAR_T
+# define _GLIBCPP_NUM_FACETS 28
+#else
+# define _GLIBCPP_NUM_FACETS 14
+#endif
// 22.1.1 Locale
- template<typename _Tp> class allocator;
- template<typename _Tp, typename _Alloc> class vector;
+ template<typename _Tp, typename _Alloc>
+ class vector;
class locale;
// 22.1.3 Convenience interfaces
#ifdef _GLIBCPP_USE_WCHAR_T
template<> class ctype<wchar_t>;
#endif
-
template<typename _CharT>
class ctype_byname;
// NB: Specialized for char and wchar_t in locale_facets.h.
class codecvt_base;
+ class __enc_traits;
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt;
template<> class codecvt<char, char, mbstate_t>;
#ifdef _GLIBCPP_USE_WCHAR_T
template<> class codecvt<wchar_t, char, mbstate_t>;
#endif
-
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt_byname;
// 22.2.4 collation
template<typename _CharT>
class collate;
- template<> class collate<char>;
-#ifdef _GLIBCPP_USE_WCHAR_T
- template<> class collate<wchar_t>;
-#endif
template<typename _CharT> class
collate_byname;
template<typename _CharT>
class messages_byname;
-
// 22.1.1 Class locale
class locale
{
public:
// Types:
- typedef int category;
+ typedef unsigned int category;
// Forward decls and friends:
class facet;
class id;
class _Impl;
+ friend class facet;
friend class _Impl;
template<typename _Facet>
has_facet(const locale&) throw();
// Category values:
- // NB much depends on the order in which these appear:
+ // NB: Order must match _S_facet_categories definition in locale.cc
static const category none = 0;
- static const category collate = 0x0100;
- static const category ctype = 0x0200;
- static const category monetary = 0x0400;
- static const category numeric = 0x0800;
- static const category time = 0x1000;
- static const category messages = 0x2000;
+ static const category ctype = 1L << 0;
+ static const category numeric = 1L << 1;
+ static const category collate = 1L << 2;
+ static const category time = 1L << 3;
+ static const category monetary = 1L << 4;
+ static const category messages = 1L << 5;
static const category all = (collate | ctype | monetary |
numeric | time | messages);
// Construct/copy/destroy:
- inline
locale() throw();
- inline
locale(const locale& __other) throw();
explicit
locale(const char* __std_name);
- locale(const locale& __other, const char* __std_name, category __cat);
+ locale(const locale& __base, const char* __s, category __cat);
- locale(const locale& __other, const locale& __one, category __cat);
+ locale(const locale& __base, const locale& __add, category __cat);
template<typename _Facet>
locale(const locale& __other, _Facet* __f);
- inline
~locale() throw();
const locale&
template<typename _Facet>
locale
- combine(const locale& __other);
+ combine(const locale& __other) const;
// Locale operations:
string
inline bool
operator!=(const locale& __other) const throw ()
- { return !(operator==(__other)); }
+ { return !(this->operator==(__other)); }
template<typename _Char, typename _Traits, typename _Alloc>
bool
// Current global reference locale
static _Impl* _S_global;
- static const int _S_categories_num = _Count_ones<all>::_S_count;
- static const int _S_facets_num = 26;
+ static const size_t _S_num_categories = 6;
+ static const size_t _S_num_facets = _GLIBCPP_NUM_FACETS;
explicit
locale(_Impl*) throw();
static inline void
_S_initialize()
- { if (!_S_classic) classic(); }
+ {
+ if (!_S_classic)
+ classic();
+ }
- static int
- _S_normalize_category(int);
+ static category
+ _S_normalize_category(category);
+
+ void
+ _M_coalesce(const locale& __base, const locale& __add, category __cat);
};
- // locale implementation object
+ // Implementation object for locale
class locale::_Impl
{
public:
// Types.
- typedef vector<facet*, allocator<facet*> > __vec_facet;
- typedef vector<string, allocator<string> > __vec_string;
+ typedef vector<facet*, allocator<facet*> > __vec_facet;
// Friends.
friend class locale;
private:
// Data Members.
- size_t _M_references;
+ _Atomic_word _M_references;
__vec_facet* _M_facets;
- __vec_string* _M_category_names;
- bool _M_has_name;
- string _M_name;
- static const locale::id* const _S_id_collate[];
+ string _M_names[_S_num_categories];
static const locale::id* const _S_id_ctype[];
- static const locale::id* const _S_id_monetary[];
static const locale::id* const _S_id_numeric[];
+ static const locale::id* const _S_id_collate[];
static const locale::id* const _S_id_time[];
+ static const locale::id* const _S_id_monetary[];
static const locale::id* const _S_id_messages[];
static const locale::id* const* const _S_facet_categories[];
inline void
_M_add_reference() throw()
- { ++_M_references; } // XXX MT
+ { __atomic_add(&_M_references, 1); }
inline void
_M_remove_reference() throw()
{
- if (_M_references-- == 0) // XXX MT
+ if (__exchange_and_add(&_M_references, -1) == 1)
{
- try {
- delete this;
- }
- catch(...) {
- }
+ try
+ { delete this; }
+ catch(...)
+ { }
}
}
- _Impl(const _Impl&, size_t __refs);
- _Impl(const _Impl&, const string&, category, size_t __refs);
- _Impl(size_t __facets, size_t __refs, bool __has_name,
- string __name = "*");
+ _Impl(const _Impl&, size_t);
+ _Impl(string __name, size_t);
~_Impl() throw();
+ inline bool
+ _M_check_same_name()
+ {
+ bool __ret = true;
+ for (size_t i = 0; i < _S_num_categories - 1; ++i)
+ __ret &= _M_names[i] == _M_names[i + 1];
+ return __ret;
+ }
+
void
_M_replace_categories(const _Impl*, category);
template<typename _Facet>
inline void
- _M_facet_init(_Facet* __facet)
+ _M_init_facet(_Facet* __facet)
{ _M_install_facet(&_Facet::id, __facet); }
-
- void
- _M_construct_collate(const char*);
-
- void
- _M_construct_ctype(const char*);
-
- void
- _M_construct_monetary(const char*);
-
- void
- _M_construct_numeric(const char*);
-
- void
- _M_construct_time(const char*);
-
- void
- _M_construct_messages(const char*);
-
- category
- _M_normalize_category_names(const string&, category __cat);
};
- // class locale inlines, that need declaration of locale::_Imp
- locale::locale() throw()
- {
- _S_initialize();
- (_M_impl = _S_global)->_M_add_reference();
- } // XXX MT
-
- locale::locale(const locale& __other) throw()
- { (_M_impl = __other._M_impl)->_M_add_reference(); }
-
template<typename _Facet>
locale::locale(const locale& __other, _Facet* __f)
{
_M_impl = new _Impl(*__other._M_impl, 1);
_M_impl->_M_install_facet(&_Facet::id, __f);
- _M_impl->_M_has_name = false;
- _M_impl->_M_name = "*";
+ for (size_t __i = 0; __i < _S_num_categories; ++__i)
+ _M_impl->_M_names[__i] = "*";
}
- locale::~locale() throw()
- { _M_impl->_M_remove_reference(); }
-
// 22.1.1.1.2 Class locale::facet
class locale::facet
{
friend class locale;
friend class locale::_Impl;
+ friend class __enc_traits;
+
+ private:
+ _Atomic_word _M_references;
protected:
+ // Contains data from the underlying "C" library for default "C"
+ // or "POSIX" locale.
+ static __c_locale _S_c_locale;
+
explicit
facet(size_t __refs = 0) throw();
virtual
- ~facet() { };
+ ~facet();
- private:
- size_t _M_references;
+ static void
+ _S_create_c_locale(__c_locale& __cloc, const char* __s);
+ static __c_locale
+ _S_clone_c_locale(__c_locale& __cloc);
+
+ static void
+ _S_destroy_c_locale(__c_locale& __cloc);
+
+ private:
void
_M_add_reference() throw();
void
_M_remove_reference() throw();
- facet(const facet&); // not defined
+ facet(const facet&); // Not defined.
void
- operator=(const facet&); // not defined
+ operator=(const facet&); // Not defined.
};
// 22.1.1.1.3 Class locale::id
class locale::id
{
+ private:
friend class locale;
friend class locale::_Impl;
template<typename _Facet>
template<typename _Facet>
friend bool
has_facet(const locale&) throw ();
- public:
- id() {};
- private:
+
// NB: There is no accessor for _M_index because it may be used
// before the constructor is run; the effect of calling a member
// function (even an inline) would be undefined.
mutable size_t _M_index;
// Last id number assigned
- static size_t _S_highwater;
+ static _Atomic_word _S_highwater;
void
operator=(const id&); // not defined
id(const id&); // not defined
+
+ public:
+ // NB: This class is always a static data member, and thus can be
+ // counted on to be zero-initialized.
+ id();
};
template<typename _Facet>
template<typename _Facet>
bool
has_facet(const locale& __loc) throw();
-
} // namespace std
-#endif /* _CPP_BITS_LOCCORE_H */
-
-// Local Variables:
-// mode:c++
-// End:
-
+#endif