+2003-10-17 Benjamin Kosnik <bkoz@redhat.com>
+
+ * src/Makefile.am: Add new files.
+ * src/Makefile.in: Regenerate.
+ * src/globals.cc: Split into..
+ * src/globals_io.cc: New.
+ * src/globals_locale.cc: New.
+ * src/ios.cc: Split into...
+ * src/ios_init.cc: New.
+ * src/ios_locale.cc: New.
+ * src/locale-inst.cc: Split into..
+ * src/wlocale-inst.cc: New.
+ * src/locale-misc-inst.cc: New.
+ * src/locale.cc, src/localename: Split into...
+ * src/locale_facets.cc: New.
+ * src/locale_init.cc: New.
+ * src/wstring-inst.cc: Add copyright info.
+
2003-10-16 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/11450
# Sources present in the src directory.
sources = \
- allocator-inst.cc \
codecvt.cc \
complex_io.cc \
- concept-inst.cc \
ctype.cc \
demangle.cc \
- ext-inst.cc \
- fstream-inst.cc \
functexcept.cc \
- globals.cc \
- io-inst.cc \
+ globals_locale.cc \
+ globals_io.cc \
ios.cc \
ios_failure.cc \
- istream-inst.cc \
+ ios_init.cc \
+ ios_locale.cc \
limits.cc \
locale.cc \
- locale-inst.cc \
+ locale_init.cc \
+ locale_facets.cc \
localename.cc \
+ stdexcept.cc \
+ stl_tree.cc \
+ strstream.cc \
+ allocator-inst.cc \
+ concept-inst.cc \
+ fstream-inst.cc \
+ ext-inst.cc \
+ io-inst.cc \
+ istream-inst.cc \
+ locale-inst.cc \
+ locale-misc-inst.cc \
misc-inst.cc \
ostream-inst.cc \
sstream-inst.cc \
- stdexcept.cc \
- stl_tree.cc \
streambuf-inst.cc \
string-inst.cc \
- strstream.cc \
valarray-inst.cc \
+ wlocale-inst.cc \
wstring-inst.cc \
${host_sources} \
${host_sources_extra}
-# Makefile.in generated by automake 1.7.6 from Makefile.am.
+# Makefile.in generated by automake 1.7.8 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
-FPOS_H = @FPOS_H@
-FPOS_INC_SRCDIR = @FPOS_INC_SRCDIR@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
# Sources present in the src directory.
sources = \
- allocator-inst.cc \
codecvt.cc \
complex_io.cc \
- concept-inst.cc \
ctype.cc \
demangle.cc \
- ext-inst.cc \
- fstream-inst.cc \
functexcept.cc \
- globals.cc \
- io-inst.cc \
+ globals_locale.cc \
+ globals_io.cc \
ios.cc \
ios_failure.cc \
- istream-inst.cc \
+ ios_init.cc \
+ ios_locale.cc \
limits.cc \
locale.cc \
- locale-inst.cc \
+ locale_init.cc \
+ locale_facets.cc \
localename.cc \
+ stdexcept.cc \
+ stl_tree.cc \
+ strstream.cc \
+ allocator-inst.cc \
+ concept-inst.cc \
+ fstream-inst.cc \
+ ext-inst.cc \
+ io-inst.cc \
+ istream-inst.cc \
+ locale-inst.cc \
+ locale-misc-inst.cc \
misc-inst.cc \
ostream-inst.cc \
sstream-inst.cc \
- stdexcept.cc \
- stl_tree.cc \
streambuf-inst.cc \
string-inst.cc \
- strstream.cc \
valarray-inst.cc \
+ wlocale-inst.cc \
wstring-inst.cc \
${host_sources} \
${host_sources_extra}
messages_members.lo monetary_members.lo numeric_members.lo \
time_members.lo
am__objects_2 = basic_file.lo c++locale.lo
-am__objects_3 = allocator-inst.lo codecvt.lo complex_io.lo \
- concept-inst.lo ctype.lo demangle.lo ext-inst.lo \
- fstream-inst.lo functexcept.lo globals.lo io-inst.lo ios.lo \
- ios_failure.lo istream-inst.lo limits.lo locale.lo locale-inst.lo \
- localename.lo misc-inst.lo ostream-inst.lo sstream-inst.lo \
- stdexcept.lo stl_tree.lo streambuf-inst.lo string-inst.lo \
- strstream.lo valarray-inst.lo wstring-inst.lo $(am__objects_1) \
- $(am__objects_2)
+am__objects_3 = codecvt.lo complex_io.lo ctype.lo demangle.lo \
+ functexcept.lo globals_locale.lo globals_io.lo ios.lo \
+ ios_failure.lo ios_init.lo ios_locale.lo limits.lo locale.lo \
+ locale_init.lo locale_facets.lo localename.lo stdexcept.lo \
+ stl_tree.lo strstream.lo allocator-inst.lo concept-inst.lo \
+ fstream-inst.lo ext-inst.lo io-inst.lo istream-inst.lo \
+ locale-inst.lo locale-misc-inst.lo misc-inst.lo ostream-inst.lo \
+ sstream-inst.lo streambuf-inst.lo string-inst.lo \
+ valarray-inst.lo wlocale-inst.lo wstring-inst.lo \
+ $(am__objects_1) $(am__objects_2)
am_libstdc___la_OBJECTS = $(am__objects_3)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
DIST_SOURCES = $(libstdc___la_SOURCES)
-DIST_COMMON = $(top_srcdir)/fragment.am Makefile.am Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/fragment.am \
+ Makefile.am
SOURCES = $(libstdc___la_SOURCES)
all: all-am
clean-generic:
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
mostlyclean-am
distclean: distclean-am
-
+ -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
installcheck-am:
maintainer-clean: maintainer-clean-am
-
+ -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
--- /dev/null
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include "bits/c++config.h"
+#include "bits/gthr.h"
+#include <fstream>
+#include <istream>
+#include <ostream>
+#include <ext/stdio_filebuf.h>
+#include <ext/stdio_sync_filebuf.h>
+
+// On AIX, and perhaps other systems, library initialization order is
+// not guaranteed. For example, the static initializers for the main
+// program might run before the static initializers for this library.
+// That means that we cannot rely on static initialization in the
+// library; there is no guarantee that things will get initialized in
+// time. This file contains definitions of all global variables that
+// require initialization as arrays of characters.
+
+// NB: asm directives can rename these non-exported, namespace
+// __gnu_cxx symbols into exported, namespace std symbols with the
+// appropriate symbol version name.
+// The rename syntax is
+// asm (".symver currentname,oldname@@GLIBCXX_3.2")
+// In macro form:
+// _GLIBCXX_ASM_SYMVER(currentname, oldname, GLIBCXX_3.2)
+
+namespace std
+{
+ // Standard stream objects.
+ // NB: Iff <iostream> is included, these definitions become wonky.
+ typedef char fake_istream[sizeof(istream)]
+ __attribute__ ((aligned(__alignof__(istream))));
+ typedef char fake_ostream[sizeof(ostream)]
+ __attribute__ ((aligned(__alignof__(ostream))));
+ fake_istream cin;
+ fake_ostream cout;
+ fake_ostream cerr;
+ fake_ostream clog;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef char fake_wistream[sizeof(wistream)]
+ __attribute__ ((aligned(__alignof__(wistream))));
+ typedef char fake_wostream[sizeof(wostream)]
+ __attribute__ ((aligned(__alignof__(wostream))));
+ fake_wistream wcin;
+ fake_wostream wcout;
+ fake_wostream wcerr;
+ fake_wostream wclog;
+#endif
+} // namespace std
+
+namespace __gnu_cxx
+{
+ using namespace std;
+
+ // We use different stream buffer types depending on whether
+ // ios_base::sync_with_stdio(false) has been called.
+ typedef char fake_stdiobuf[sizeof(stdio_sync_filebuf<char>)]
+ __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<char>))));
+ fake_stdiobuf buf_cout_sync;
+ fake_stdiobuf buf_cin_sync;
+ fake_stdiobuf buf_cerr_sync;
+
+ typedef char fake_filebuf[sizeof(stdio_filebuf<char>)]
+ __attribute__ ((aligned(__alignof__(stdio_filebuf<char>))));
+ fake_filebuf buf_cout;
+ fake_filebuf buf_cin;
+ fake_filebuf buf_cerr;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef char fake_wstdiobuf[sizeof(stdio_sync_filebuf<wchar_t>)]
+ __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<wchar_t>))));
+ fake_wstdiobuf buf_wcout_sync;
+ fake_wstdiobuf buf_wcin_sync;
+ fake_wstdiobuf buf_wcerr_sync;
+
+ typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)]
+ __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>))));
+ fake_wfilebuf buf_wcout;
+ fake_wfilebuf buf_wcin;
+ fake_wfilebuf buf_wcerr;
+#endif
+
+ // Globals for once-only runtime initialization of mutex objects. This
+ // allows static initialization of these objects on systems that need a
+ // function call to initialize a mutex. For example, see stl_threads.h.
+#ifdef __GTHREAD_MUTEX_INIT
+#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
+ __gthread_once_t _GLIBCXX_once = __GTHREAD_ONCE_INIT;
+ __gthread_mutex_t _GLIBCXX_mutex;
+ __gthread_mutex_t *_GLIBCXX_mutex_address;
+
+ // Once-only initializer function for _GLIBCXX_mutex.
+ void
+ _GLIBCXX_mutex_init ()
+ { __GTHREAD_MUTEX_INIT_FUNCTION (&_GLIBCXX_mutex); }
+
+ // Once-only initializer function for _GLIBCXX_mutex_address.
+ void
+ _GLIBCXX_mutex_address_init ()
+ { __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCXX_mutex_address); }
+#endif
+} // namespace __gnu_cxx
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-#include "bits/c++config.h"
-#include "bits/gthr.h"
-#include <fstream>
-#include <istream>
-#include <ostream>
#include <locale>
-#include <ext/stdio_filebuf.h>
-#include <ext/stdio_sync_filebuf.h>
// On AIX, and perhaps other systems, library initialization order is
// not guaranteed. For example, the static initializers for the main
// In macro form:
// _GLIBCXX_ASM_SYMVER(currentname, oldname, GLIBCXX_3.2)
-namespace std
-{
- // Standard stream objects.
- // NB: Iff <iostream> is included, these definitions become wonky.
- typedef char fake_istream[sizeof(istream)]
- __attribute__ ((aligned(__alignof__(istream))));
- typedef char fake_ostream[sizeof(ostream)]
- __attribute__ ((aligned(__alignof__(ostream))));
- fake_istream cin;
- fake_ostream cout;
- fake_ostream cerr;
- fake_ostream clog;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef char fake_wistream[sizeof(wistream)]
- __attribute__ ((aligned(__alignof__(wistream))));
- typedef char fake_wostream[sizeof(wostream)]
- __attribute__ ((aligned(__alignof__(wostream))));
- fake_wistream wcin;
- fake_wostream wcout;
- fake_wostream wcerr;
- fake_wostream wclog;
-#endif
-} // namespace std
-
namespace __gnu_cxx
{
using namespace std;
- // We use different stream buffer types depending on whether
- // ios_base::sync_with_stdio(false) has been called.
- typedef char fake_stdiobuf[sizeof(stdio_sync_filebuf<char>)]
- __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<char>))));
- fake_stdiobuf buf_cout_sync;
- fake_stdiobuf buf_cin_sync;
- fake_stdiobuf buf_cerr_sync;
-
- typedef char fake_filebuf[sizeof(stdio_filebuf<char>)]
- __attribute__ ((aligned(__alignof__(stdio_filebuf<char>))));
- fake_filebuf buf_cout;
- fake_filebuf buf_cin;
- fake_filebuf buf_cerr;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef char fake_wstdiobuf[sizeof(stdio_sync_filebuf<wchar_t>)]
- __attribute__ ((aligned(__alignof__(stdio_sync_filebuf<wchar_t>))));
- fake_wstdiobuf buf_wcout_sync;
- fake_wstdiobuf buf_wcin_sync;
- fake_wstdiobuf buf_wcerr_sync;
-
- typedef char fake_wfilebuf[sizeof(stdio_filebuf<wchar_t>)]
- __attribute__ ((aligned(__alignof__(stdio_filebuf<wchar_t>))));
- fake_wfilebuf buf_wcout;
- fake_wfilebuf buf_wcin;
- fake_wfilebuf buf_wcerr;
-#endif
-
typedef char fake_locale_Impl[sizeof(locale::_Impl)]
__attribute__ ((aligned(__alignof__(locale::_Impl))));
fake_locale_Impl c_locale_impl;
__attribute__ ((aligned(__alignof__(std::__timepunct_cache<wchar_t>))));
fake_time_cache_w timepunct_cache_w;
#endif
-
- // Globals for once-only runtime initialization of mutex objects. This
- // allows static initialization of these objects on systems that need a
- // function call to initialize a mutex. For example, see stl_threads.h.
-#ifdef __GTHREAD_MUTEX_INIT
-#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
- __gthread_once_t _GLIBCXX_once = __GTHREAD_ONCE_INIT;
- __gthread_mutex_t _GLIBCXX_mutex;
- __gthread_mutex_t *_GLIBCXX_mutex_address;
-
- // Once-only initializer function for _GLIBCXX_mutex.
- void
- _GLIBCXX_mutex_init ()
- { __GTHREAD_MUTEX_INIT_FUNCTION (&_GLIBCXX_mutex); }
-
- // Once-only initializer function for _GLIBCXX_mutex_address.
- void
- _GLIBCXX_mutex_address_init ()
- { __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCXX_mutex_address); }
-#endif
} // namespace __gnu_cxx
//
#include <ios>
-#include <ostream>
-#include <istream>
-#include <fstream>
+#include <limits>
#include <bits/atomicity.h>
-#include <ext/stdio_filebuf.h>
-#include <ext/stdio_sync_filebuf.h>
-
-namespace __gnu_cxx
-{
- // Extern declarations for global objects in src/globals.cc.
- extern stdio_sync_filebuf<char> buf_cout_sync;
- extern stdio_sync_filebuf<char> buf_cin_sync;
- extern stdio_sync_filebuf<char> buf_cerr_sync;
-
- extern stdio_filebuf<char> buf_cout;
- extern stdio_filebuf<char> buf_cin;
- extern stdio_filebuf<char> buf_cerr;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- extern stdio_sync_filebuf<wchar_t> buf_wcout_sync;
- extern stdio_sync_filebuf<wchar_t> buf_wcin_sync;
- extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync;
-
- extern stdio_filebuf<wchar_t> buf_wcout;
- extern stdio_filebuf<wchar_t> buf_wcin;
- extern stdio_filebuf<wchar_t> buf_wcerr;
-#endif
-} // namespace __gnu_cxx
namespace std
{
- using namespace __gnu_cxx;
-
- extern istream cin;
- extern ostream cout;
- extern ostream cerr;
- extern ostream clog;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- extern wistream wcin;
- extern wostream wcout;
- extern wostream wcerr;
- extern wostream wclog;
-#endif
-
// Definitions for static const data members of __ios_flags.
const __ios_flags::__int_type __ios_flags::_S_boolalpha;
const __ios_flags::__int_type __ios_flags::_S_dec;
const ios_base::seekdir ios_base::end;
const int ios_base::_S_local_word_size;
+
int ios_base::Init::_S_ios_base_init = 0;
+
bool ios_base::Init::_S_synced_with_stdio = true;
- ios_base::Init::Init()
+ ios_base::ios_base()
+ : _M_callbacks(0), _M_word_size(_S_local_word_size), _M_word(_M_local_word)
{
- if (_S_ios_base_init == 0)
- {
- // Standard streams default to synced with "C" operations.
- _S_synced_with_stdio = true;
-
- new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout);
- new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin);
- new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr);
-
- // The standard streams are constructed once only and never
- // destroyed.
- new (&cout) ostream(&buf_cout_sync);
- new (&cin) istream(&buf_cin_sync);
- new (&cerr) ostream(&buf_cerr_sync);
- new (&clog) ostream(&buf_cerr_sync);
- cin.tie(&cout);
- cerr.flags(ios_base::unitbuf);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout);
- new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin);
- new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr);
-
- new (&wcout) wostream(&buf_wcout_sync);
- new (&wcin) wistream(&buf_wcin_sync);
- new (&wcerr) wostream(&buf_wcerr_sync);
- new (&wclog) wostream(&buf_wcerr_sync);
- wcin.tie(&wcout);
- wcerr.flags(ios_base::unitbuf);
-#endif
-
- _S_ios_base_init = 1;
- }
- ++_S_ios_base_init;
+ // Do nothing: basic_ios::init() does it.
+ // NB: _M_callbacks and _M_word must be zero for non-initialized
+ // ios_base to go through ~ios_base gracefully.
}
-
- ios_base::Init::~Init()
+
+ // 27.4.2.7 ios_base constructors/destructors
+ ios_base::~ios_base()
{
- if (--_S_ios_base_init == 1)
+ _M_call_callbacks(erase_event);
+ _M_dispose_callbacks();
+ if (_M_word != _M_local_word)
{
- // Catch any exceptions thrown by basic_ostream::flush()
- try
- {
- // Flush standard output streams as required by 27.4.2.1.6
- cout.flush();
- cerr.flush();
- clog.flush();
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- wcout.flush();
- wcerr.flush();
- wclog.flush();
-#endif
- }
- catch (...)
- { }
+ delete [] _M_word;
+ _M_word = 0;
}
- }
+ }
// 27.4.2.5 ios_base storage functions
int
return __exchange_and_add(&_S_top, 1) + 4;
}
+ void
+ ios_base::register_callback(event_callback __fn, int __index)
+ { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
+
// 27.4.2.5 iword/pword storage
ios_base::_Words&
ios_base::_M_grow_words(int ix)
_M_word_size = newsize;
return _M_word[ix];
}
-
- // Called only by basic_ios<>::init.
- void
- ios_base::_M_init()
- {
- // NB: May be called more than once
- _M_precision = 6;
- _M_width = 0;
- _M_flags = skipws | dec;
- _M_ios_locale = locale();
- }
-
- // 27.4.2.3 ios_base locale functions
- locale
- ios_base::imbue(const locale& __loc)
- {
- locale __old = _M_ios_locale;
- _M_ios_locale = __loc;
- _M_call_callbacks(imbue_event);
- return __old;
- }
-
- ios_base::ios_base()
- : _M_callbacks(0), _M_word_size(_S_local_word_size), _M_word(_M_local_word)
- {
- // Do nothing: basic_ios::init() does it.
- // NB: _M_callbacks and _M_word must be zero for non-initialized
- // ios_base to go through ~ios_base gracefully.
- }
-
- // 27.4.2.7 ios_base constructors/destructors
- ios_base::~ios_base()
- {
- _M_call_callbacks(erase_event);
- _M_dispose_callbacks();
- if (_M_word != _M_local_word)
- {
- delete [] _M_word;
- _M_word = 0;
- }
- }
-
- void
- ios_base::register_callback(event_callback __fn, int __index)
- { _M_callbacks = new _Callback_list(__fn, __index, _M_callbacks); }
void
ios_base::_M_call_callbacks(event __e) throw()
}
_M_callbacks = 0;
}
-
- bool
- ios_base::sync_with_stdio(bool __sync)
- {
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 49. Underspecification of ios_base::sync_with_stdio
- bool __ret = ios_base::Init::_S_synced_with_stdio;
-
- // Turn off sync with C FILE* for cin, cout, cerr, clog iff
- // currently synchronized.
- if (!__sync && __ret)
- {
- ios_base::Init::_S_synced_with_stdio = __sync;
-
- // Explicitly call dtors to free any memory that is
- // dynamically allocated by filebuf ctor or member functions,
- // but don't deallocate all memory by calling operator delete.
- buf_cout_sync.~stdio_sync_filebuf<char>();
- buf_cin_sync.~stdio_sync_filebuf<char>();
- buf_cerr_sync.~stdio_sync_filebuf<char>();
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
- buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
- buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
-#endif
-
- // Create stream buffers for the standard streams and use
- // those buffers without destroying and recreating the
- // streams.
- new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
- new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
- new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
- cout.rdbuf(&buf_cout);
- cin.rdbuf(&buf_cin);
- cerr.rdbuf(&buf_cerr);
- clog.rdbuf(&buf_cerr);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
- new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
- new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
- wcout.rdbuf(&buf_wcout);
- wcin.rdbuf(&buf_wcin);
- wcerr.rdbuf(&buf_wcerr);
- wclog.rdbuf(&buf_wcerr);
-#endif
- }
- return __ret;
- }
} // namespace std
--- /dev/null
+// Iostreams base classes -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.4 Iostreams base classes
+//
+
+#include <ios>
+#include <ostream>
+#include <istream>
+#include <fstream>
+#include <bits/atomicity.h>
+#include <ext/stdio_filebuf.h>
+#include <ext/stdio_sync_filebuf.h>
+
+namespace __gnu_cxx
+{
+ // Extern declarations for global objects in src/globals.cc.
+ extern stdio_sync_filebuf<char> buf_cout_sync;
+ extern stdio_sync_filebuf<char> buf_cin_sync;
+ extern stdio_sync_filebuf<char> buf_cerr_sync;
+
+ extern stdio_filebuf<char> buf_cout;
+ extern stdio_filebuf<char> buf_cin;
+ extern stdio_filebuf<char> buf_cerr;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ extern stdio_sync_filebuf<wchar_t> buf_wcout_sync;
+ extern stdio_sync_filebuf<wchar_t> buf_wcin_sync;
+ extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync;
+
+ extern stdio_filebuf<wchar_t> buf_wcout;
+ extern stdio_filebuf<wchar_t> buf_wcin;
+ extern stdio_filebuf<wchar_t> buf_wcerr;
+#endif
+} // namespace __gnu_cxx
+
+namespace std
+{
+ using namespace __gnu_cxx;
+
+ extern istream cin;
+ extern ostream cout;
+ extern ostream cerr;
+ extern ostream clog;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ extern wistream wcin;
+ extern wostream wcout;
+ extern wostream wcerr;
+ extern wostream wclog;
+#endif
+
+ ios_base::Init::Init()
+ {
+ if (_S_ios_base_init == 0)
+ {
+ // Standard streams default to synced with "C" operations.
+ _S_synced_with_stdio = true;
+
+ new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout);
+ new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin);
+ new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr);
+
+ // The standard streams are constructed once only and never
+ // destroyed.
+ new (&cout) ostream(&buf_cout_sync);
+ new (&cin) istream(&buf_cin_sync);
+ new (&cerr) ostream(&buf_cerr_sync);
+ new (&clog) ostream(&buf_cerr_sync);
+ cin.tie(&cout);
+ cerr.flags(ios_base::unitbuf);
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout);
+ new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin);
+ new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr);
+
+ new (&wcout) wostream(&buf_wcout_sync);
+ new (&wcin) wistream(&buf_wcin_sync);
+ new (&wcerr) wostream(&buf_wcerr_sync);
+ new (&wclog) wostream(&buf_wcerr_sync);
+ wcin.tie(&wcout);
+ wcerr.flags(ios_base::unitbuf);
+#endif
+
+ _S_ios_base_init = 1;
+ }
+ ++_S_ios_base_init;
+ }
+
+ ios_base::Init::~Init()
+ {
+ if (--_S_ios_base_init == 1)
+ {
+ // Catch any exceptions thrown by basic_ostream::flush()
+ try
+ {
+ // Flush standard output streams as required by 27.4.2.1.6
+ cout.flush();
+ cerr.flush();
+ clog.flush();
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ wcout.flush();
+ wcerr.flush();
+ wclog.flush();
+#endif
+ }
+ catch (...)
+ { }
+ }
+ }
+
+ bool
+ ios_base::sync_with_stdio(bool __sync)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 49. Underspecification of ios_base::sync_with_stdio
+ bool __ret = ios_base::Init::_S_synced_with_stdio;
+
+ // Turn off sync with C FILE* for cin, cout, cerr, clog iff
+ // currently synchronized.
+ if (!__sync && __ret)
+ {
+ ios_base::Init::_S_synced_with_stdio = __sync;
+
+ // Explicitly call dtors to free any memory that is
+ // dynamically allocated by filebuf ctor or member functions,
+ // but don't deallocate all memory by calling operator delete.
+ buf_cout_sync.~stdio_sync_filebuf<char>();
+ buf_cin_sync.~stdio_sync_filebuf<char>();
+ buf_cerr_sync.~stdio_sync_filebuf<char>();
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ buf_wcout_sync.~stdio_sync_filebuf<wchar_t>();
+ buf_wcin_sync.~stdio_sync_filebuf<wchar_t>();
+ buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>();
+#endif
+
+ // Create stream buffers for the standard streams and use
+ // those buffers without destroying and recreating the
+ // streams.
+ new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out);
+ new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in);
+ new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out);
+ cout.rdbuf(&buf_cout);
+ cin.rdbuf(&buf_cin);
+ cerr.rdbuf(&buf_cerr);
+ clog.rdbuf(&buf_cerr);
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out);
+ new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in);
+ new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out);
+ wcout.rdbuf(&buf_wcout);
+ wcin.rdbuf(&buf_wcin);
+ wcerr.rdbuf(&buf_wcerr);
+ wclog.rdbuf(&buf_wcerr);
+#endif
+ }
+ return __ret;
+ }
+} // namespace std
--- /dev/null
+// Iostreams base classes -*- C++ -*-
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 27.4 Iostreams base classes
+//
+
+#include <ios>
+#include <locale>
+
+namespace std
+{
+ // Called only by basic_ios<>::init.
+ void
+ ios_base::_M_init()
+ {
+ // NB: May be called more than once
+ _M_precision = 6;
+ _M_width = 0;
+ _M_flags = skipws | dec;
+ _M_ios_locale = locale();
+ }
+
+ // 27.4.2.3 ios_base locale functions
+ locale
+ ios_base::imbue(const locale& __loc)
+ {
+ locale __old = _M_ios_locale;
+ _M_ios_locale = __loc;
+ _M_call_callbacks(imbue_event);
+ return __old;
+ }
+} // namespace std
// ISO C++ 14882: 22.1 Locales
//
-#include <cstdlib>
-#include <clocale>
-#include <cstring>
#include <locale>
+// Instantiation configuration.
+#ifndef C
+# define C char
+#endif
+
namespace std
{
// moneypunct, money_get, and money_put
- template class moneypunct<char, false>;
- template class moneypunct<char, true>;
- template struct __moneypunct_cache<char>;
- template class moneypunct_byname<char, false>;
- template class moneypunct_byname<char, true>;
- template class money_get<char, istreambuf_iterator<char> >;
- template class money_put<char, ostreambuf_iterator<char> >;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template class moneypunct<wchar_t, false>;
- template class moneypunct<wchar_t, true>;
- template struct __moneypunct_cache<wchar_t>;
- template class moneypunct_byname<wchar_t, false>;
- template class moneypunct_byname<wchar_t, true>;
- template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
- template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
-#endif
+ template class moneypunct<C, false>;
+ template class moneypunct<C, true>;
+ template struct __moneypunct_cache<C>;
+ template class moneypunct_byname<C, false>;
+ template class moneypunct_byname<C, true>;
+ template class money_get<C, istreambuf_iterator<C> >;
+ template class money_put<C, ostreambuf_iterator<C> >;
// numpunct, numpunct_byname, num_get, and num_put
- template class numpunct<char>;
- template struct __numpunct_cache<char>;
- template class numpunct_byname<char>;
- template class num_get<char, istreambuf_iterator<char> >;
- template class num_put<char, ostreambuf_iterator<char> >;
- template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_int(ostreambuf_iterator<char>, ios_base&, char,
+ template class numpunct<C>;
+ template struct __numpunct_cache<C>;
+ template class numpunct_byname<C>;
+ template class num_get<C, istreambuf_iterator<C> >;
+ template class num_put<C, ostreambuf_iterator<C> >;
+ template
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
long) const;
template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_int(ostreambuf_iterator<char>, ios_base&, char,
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
unsigned long) const;
#ifdef _GLIBCXX_USE_LONG_LONG
template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_int(ostreambuf_iterator<char>, ios_base&, char,
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
long long) const;
template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_int(ostreambuf_iterator<char>, ios_base&, char,
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_int(ostreambuf_iterator<C>, ios_base&, C,
unsigned long long) const;
#endif
template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_float(ostreambuf_iterator<char>, ios_base&, char, char,
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
double) const;
template
- ostreambuf_iterator<char>
- num_put<char, ostreambuf_iterator<char> >::
- _M_insert_float(ostreambuf_iterator<char>, ios_base&, char, char,
+ ostreambuf_iterator<C>
+ num_put<C, ostreambuf_iterator<C> >::
+ _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char,
long double) const;
-#ifdef _GLIBCXX_USE_WCHAR_T
- template class numpunct<wchar_t>;
- template struct __numpunct_cache<wchar_t>;
- template class numpunct_byname<wchar_t>;
- template class num_get<wchar_t, istreambuf_iterator<wchar_t> >;
- template class num_put<wchar_t, ostreambuf_iterator<wchar_t> >;
-
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
- long) const;
-
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
- unsigned long) const;
-
-#ifdef _GLIBCXX_USE_LONG_LONG
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
- long long) const;
-
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_int(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
- unsigned long long) const;
-#endif
-
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, char,
- double) const;
-
- template
- ostreambuf_iterator<wchar_t>
- num_put<wchar_t, ostreambuf_iterator<wchar_t> >::
- _M_insert_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t, char,
- long double) const;
-#endif
-
// time_get and time_put
- template class __timepunct<char>;
- template struct __timepunct_cache<char>;
- template class time_put<char, ostreambuf_iterator<char> >;
- template class time_put_byname<char, ostreambuf_iterator<char> >;
- template class time_get<char, istreambuf_iterator<char> >;
- template class time_get_byname<char, istreambuf_iterator<char> >;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template class __timepunct<wchar_t>;
- template struct __timepunct_cache<wchar_t>;
- template class time_put<wchar_t, ostreambuf_iterator<wchar_t> >;
- template class time_put_byname<wchar_t, ostreambuf_iterator<wchar_t> >;
- template class time_get<wchar_t, istreambuf_iterator<wchar_t> >;
- template class time_get_byname<wchar_t, istreambuf_iterator<wchar_t> >;
-#endif
+ template class __timepunct<C>;
+ template struct __timepunct_cache<C>;
+ template class time_put<C, ostreambuf_iterator<C> >;
+ template class time_put_byname<C, ostreambuf_iterator<C> >;
+ template class time_get<C, istreambuf_iterator<C> >;
+ template class time_get_byname<C, istreambuf_iterator<C> >;
// messages
- template class messages<char>;
- template class messages_byname<char>;
-#ifdef _GLIBCXX_USE_WCHAR_T
- template class messages<wchar_t>;
- template class messages_byname<wchar_t>;
-#endif
+ template class messages<C>;
+ template class messages_byname<C>;
// ctype
- inline template class __ctype_abstract_base<char>;
- template class ctype_byname<char>;
-#ifdef _GLIBCXX_USE_WCHAR_T
- inline template class __ctype_abstract_base<wchar_t>;
- template class ctype_byname<wchar_t>;
-#endif
+ inline template class __ctype_abstract_base<C>;
+ template class ctype_byname<C>;
// codecvt
- inline template class __codecvt_abstract_base<char, char, mbstate_t>;
- template class codecvt_byname<char, char, mbstate_t>;
-#ifdef _GLIBCXX_USE_WCHAR_T
- inline template class __codecvt_abstract_base<wchar_t, char, mbstate_t>;
- template class codecvt_byname<wchar_t, char, mbstate_t>;
-#endif
+ inline template class __codecvt_abstract_base<C, char, mbstate_t>;
+ template class codecvt_byname<C, char, mbstate_t>;
// collate
- template class collate<char>;
- template class collate_byname<char>;
-#ifdef _GLIBCXX_USE_WCHAR_T
- template class collate<wchar_t>;
- template class collate_byname<wchar_t>;
-#endif
+ template class collate<C>;
+ template class collate_byname<C>;
// use_facet
// NB: use_facet<ctype> is specialized
template
- const codecvt<char, char, mbstate_t>&
- use_facet<codecvt<char, char, mbstate_t> >(const locale&);
+ const codecvt<C, char, mbstate_t>&
+ use_facet<codecvt<C, char, mbstate_t> >(const locale&);
template
- const collate<char>&
- use_facet<collate<char> >(const locale&);
+ const collate<C>&
+ use_facet<collate<C> >(const locale&);
template
- const numpunct<char>&
- use_facet<numpunct<char> >(const locale&);
+ const numpunct<C>&
+ use_facet<numpunct<C> >(const locale&);
template
- const num_put<char>&
- use_facet<num_put<char> >(const locale&);
+ const num_put<C>&
+ use_facet<num_put<C> >(const locale&);
template
- const num_get<char>&
- use_facet<num_get<char> >(const locale&);
+ const num_get<C>&
+ use_facet<num_get<C> >(const locale&);
template
- const moneypunct<char, true>&
- use_facet<moneypunct<char, true> >(const locale&);
+ const moneypunct<C, true>&
+ use_facet<moneypunct<C, true> >(const locale&);
template
- const moneypunct<char, false>&
- use_facet<moneypunct<char, false> >(const locale&);
+ const moneypunct<C, false>&
+ use_facet<moneypunct<C, false> >(const locale&);
template
- const money_put<char>&
- use_facet<money_put<char> >(const locale&);
+ const money_put<C>&
+ use_facet<money_put<C> >(const locale&);
template
- const money_get<char>&
- use_facet<money_get<char> >(const locale&);
+ const money_get<C>&
+ use_facet<money_get<C> >(const locale&);
template
- const __timepunct<char>&
- use_facet<__timepunct<char> >(const locale&);
+ const __timepunct<C>&
+ use_facet<__timepunct<C> >(const locale&);
template
- const time_put<char>&
- use_facet<time_put<char> >(const locale&);
+ const time_put<C>&
+ use_facet<time_put<C> >(const locale&);
template
- const time_get<char>&
- use_facet<time_get<char> >(const locale&);
+ const time_get<C>&
+ use_facet<time_get<C> >(const locale&);
template
- const messages<char>&
- use_facet<messages<char> >(const locale&);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template
- const codecvt<wchar_t, char, mbstate_t>&
- use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
-
- template
- const collate<wchar_t>&
- use_facet<collate<wchar_t> >(const locale&);
-
- template
- const numpunct<wchar_t>&
- use_facet<numpunct<wchar_t> >(const locale&);
-
- template
- const num_put<wchar_t>&
- use_facet<num_put<wchar_t> >(const locale&);
-
- template
- const num_get<wchar_t>&
- use_facet<num_get<wchar_t> >(const locale&);
-
- template
- const moneypunct<wchar_t, true>&
- use_facet<moneypunct<wchar_t, true> >(const locale&);
-
- template
- const moneypunct<wchar_t, false>&
- use_facet<moneypunct<wchar_t, false> >(const locale&);
-
- template
- const money_put<wchar_t>&
- use_facet<money_put<wchar_t> >(const locale&);
-
- template
- const money_get<wchar_t>&
- use_facet<money_get<wchar_t> >(const locale&);
-
- template
- const __timepunct<wchar_t>&
- use_facet<__timepunct<wchar_t> >(const locale&);
-
- template
- const time_put<wchar_t>&
- use_facet<time_put<wchar_t> >(const locale&);
-
- template
- const time_get<wchar_t>&
- use_facet<time_get<wchar_t> >(const locale&);
-
- template
- const messages<wchar_t>&
- use_facet<messages<wchar_t> >(const locale&);
-#endif
+ const messages<C>&
+ use_facet<messages<C> >(const locale&);
// has_facet
template
bool
- has_facet<ctype<char> >(const locale&);
-
- template
- bool
- has_facet<codecvt<char, char, mbstate_t> >(const locale&);
-
- template
- bool
- has_facet<collate<char> >(const locale&);
-
- template
- bool
- has_facet<numpunct<char> >(const locale&);
+ has_facet<ctype<C> >(const locale&);
template
bool
- has_facet<num_put<char> >(const locale&);
+ has_facet<codecvt<C, char, mbstate_t> >(const locale&);
template
bool
- has_facet<num_get<char> >(const locale&);
+ has_facet<collate<C> >(const locale&);
template
bool
- has_facet<moneypunct<char> >(const locale&);
+ has_facet<numpunct<C> >(const locale&);
template
bool
- has_facet<money_put<char> >(const locale&);
+ has_facet<num_put<C> >(const locale&);
template
bool
- has_facet<money_get<char> >(const locale&);
+ has_facet<num_get<C> >(const locale&);
template
bool
- has_facet<__timepunct<char> >(const locale&);
+ has_facet<moneypunct<C> >(const locale&);
template
bool
- has_facet<time_put<char> >(const locale&);
-
- template
- bool
- has_facet<time_get<char> >(const locale&);
-
- template
- bool
- has_facet<messages<char> >(const locale&);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template
- bool
- has_facet<ctype<wchar_t> >(const locale&);
+ has_facet<money_put<C> >(const locale&);
template
bool
- has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
+ has_facet<money_get<C> >(const locale&);
template
bool
- has_facet<collate<wchar_t> >(const locale&);
+ has_facet<__timepunct<C> >(const locale&);
template
bool
- has_facet<numpunct<wchar_t> >(const locale&);
+ has_facet<time_put<C> >(const locale&);
template
bool
- has_facet<num_put<wchar_t> >(const locale&);
+ has_facet<time_get<C> >(const locale&);
template
bool
- has_facet<num_get<wchar_t> >(const locale&);
+ has_facet<messages<C> >(const locale&);
- template
- bool
- has_facet<moneypunct<wchar_t> >(const locale&);
-
- template
- bool
- has_facet<money_put<wchar_t> >(const locale&);
-
- template
- bool
- has_facet<money_get<wchar_t> >(const locale&);
- template
- bool
- has_facet<__timepunct<wchar_t> >(const locale&);
-
- template
- bool
- has_facet<time_put<wchar_t> >(const locale&);
-
- template
- bool
- has_facet<time_get<wchar_t> >(const locale&);
-
- template
- bool
- has_facet<messages<wchar_t> >(const locale&);
-#endif
-
- // locale
+ // locale functions.
template
- char*
- __add_grouping<char>(char*, char, char const*, char const*,
- char const*, char const*);
+ C*
+ __add_grouping<C>(C*, C, char const*, char const*,
+ C const*, C const*);
template
bool
- __verify_grouping<char>(const basic_string<char>&, basic_string<char>&);
+ __verify_grouping<C>(const basic_string<C>&, basic_string<C>&);
- template class __pad<char, char_traits<char> >;
+ template class __pad<C, char_traits<C> >;
-#ifdef _GLIBCXX_USE_WCHAR_T
- template
- wchar_t*
- __add_grouping<wchar_t>(wchar_t*, wchar_t, char const*, char const*,
- wchar_t const*, wchar_t const*);
- template
- bool
- __verify_grouping<wchar_t>(const basic_string<wchar_t>&,
- basic_string<wchar_t>&);
-
- template class __pad<wchar_t, char_traits<wchar_t> >;
-#endif
-
- template
- int
- __convert_from_v(char*, const int, const char*, double,
- const __c_locale&, int);
-
- template
- int
- __convert_from_v(char*, const int, const char*, long double,
- const __c_locale&, int);
-
- template
- int
- __convert_from_v(char*, const int, const char*, long,
- const __c_locale&, int);
-
- template
- int
- __convert_from_v(char*, const int, const char*, unsigned long,
- const __c_locale&, int);
-
-#ifdef _GLIBCXX_USE_LONG_LONG
- template
- int
- __convert_from_v(char*, const int, const char*, long long,
- const __c_locale&, int);
-
- template
- int
- __convert_from_v(char*, const int, const char*, unsigned long long,
- const __c_locale&, int);
-#endif
-
- template
- int
- __int_to_char(char*, const int, unsigned long, const char*,
- ios_base::fmtflags, bool);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
template
int
- __int_to_char(wchar_t*, const int, unsigned long, const wchar_t*,
+ __int_to_char(C*, const int, unsigned long, const C*,
ios_base::fmtflags, bool);
-#endif
#ifdef _GLIBCXX_USE_LONG_LONG
template
int
- __int_to_char(char*, const int, unsigned long long, const char*,
- ios_base::fmtflags, bool);
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template
- int
- __int_to_char(wchar_t*, const int, unsigned long long, const wchar_t*,
+ __int_to_char(C*, const int, unsigned long long, const C*,
ios_base::fmtflags, bool);
#endif
-#endif
} // namespace std
--- /dev/null
+// Locale support -*- C++ -*-
+
+// Copyright (C) 1999, 2000, 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+#include <locale>
+
+namespace std
+{
+ template
+ int
+ __convert_from_v(char*, const int, const char*, double,
+ const __c_locale&, int);
+
+ template
+ int
+ __convert_from_v(char*, const int, const char*, long double,
+ const __c_locale&, int);
+
+ template
+ int
+ __convert_from_v(char*, const int, const char*, long,
+ const __c_locale&, int);
+
+ template
+ int
+ __convert_from_v(char*, const int, const char*, unsigned long,
+ const __c_locale&, int);
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ template
+ int
+ __convert_from_v(char*, const int, const char*, long long,
+ const __c_locale&, int);
+
+ template
+ int
+ __convert_from_v(char*, const int, const char*, unsigned long long,
+ const __c_locale&, int);
+#endif
+} // namespace std
#include <locale>
#include <bits/atomicity.h>
-namespace __gnu_cxx
-{
- // Defined in globals.cc.
- extern std::locale c_locale;
- extern std::locale::_Impl c_locale_impl;
-} // namespace __gnu_cxx
-
namespace std
{
- using namespace __gnu_cxx;
-
// Definitions for static const data members of locale.
const locale::category locale::none;
const locale::category locale::ctype;
const locale::category locale::messages;
const locale::category locale::all;
- // In the future, GLIBCXX_ABI > 5 should remove all uses of
- // _GLIBCXX_ASM_SYMVER in this file, and remove exports of any
- // static data members of locale.
-
// These are no longer exported.
locale::_Impl* locale::_S_classic;
locale::_Impl* locale::_S_global;
__gthread_once_t locale::_S_once = __GTHREAD_ONCE_INIT;
#endif
- size_t
- locale::id::_M_id() const
- {
- if (!_M_index)
- _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
- return _M_index - 1;
- }
-
- // Definitions for static const data members of locale::id
- _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker
-
- // Definitions for static const data members of locale::_Impl
- const locale::id* const
- locale::_Impl::_S_id_ctype[] =
- {
- &std::ctype<char>::id,
- &codecvt<char, char, mbstate_t>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &std::ctype<wchar_t>::id,
- &codecvt<wchar_t, char, mbstate_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_numeric[] =
- {
- &num_get<char>::id,
- &num_put<char>::id,
- &numpunct<char>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &num_get<wchar_t>::id,
- &num_put<wchar_t>::id,
- &numpunct<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_collate[] =
- {
- &std::collate<char>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &std::collate<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_time[] =
- {
- &__timepunct<char>::id,
- &time_get<char>::id,
- &time_put<char>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &__timepunct<wchar_t>::id,
- &time_get<wchar_t>::id,
- &time_put<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_monetary[] =
- {
- &money_get<char>::id,
- &money_put<char>::id,
- &moneypunct<char, false>::id,
- &moneypunct<char, true >::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &money_get<wchar_t>::id,
- &money_put<wchar_t>::id,
- &moneypunct<wchar_t, false>::id,
- &moneypunct<wchar_t, true >::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_messages[] =
- {
- &std::messages<char>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
- &std::messages<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const* const
- locale::_Impl::_S_facet_categories[] =
- {
- // Order must match the decl order in class locale.
- locale::_Impl::_S_id_ctype,
- locale::_Impl::_S_id_numeric,
- locale::_Impl::_S_id_collate,
- locale::_Impl::_S_id_time,
- locale::_Impl::_S_id_monetary,
- locale::_Impl::_S_id_messages,
- 0
- };
-
- locale::locale() throw()
- {
- _S_initialize();
- (_M_impl = _S_global)->_M_add_reference();
- }
locale::locale(const locale& __other) throw()
{ (_M_impl = __other._M_impl)->_M_add_reference(); }
locale::locale(_Impl* __ip) throw() : _M_impl(__ip)
{ }
- locale::locale(const char* __s)
- {
- if (__s)
- {
- _S_initialize();
- if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
- (_M_impl = _S_classic)->_M_add_reference();
- else if (std::strcmp(__s, "") != 0)
- _M_impl = new _Impl(__s, 1);
- else
- {
- // Get it from the environment.
- char* __env = std::getenv("LC_ALL");
- // If LC_ALL is set we are done.
- if (__env && std::strcmp(__env, "") != 0)
- {
- if (std::strcmp(__env, "C") == 0
- || std::strcmp(__env, "POSIX") == 0)
- (_M_impl = _S_classic)->_M_add_reference();
- else
- _M_impl = new _Impl(__env, 1);
- }
- else
- {
- string __res;
- // LANG may set a default different from "C".
- char* __env = std::getenv("LANG");
- if (!__env || std::strcmp(__env, "") == 0
- || std::strcmp(__env, "C") == 0
- || std::strcmp(__env, "POSIX") == 0)
- __res = "C";
- else
- __res = __env;
-
- // Scan the categories looking for the first one
- // different from LANG.
- size_t __i = 0;
- if (__res == "C")
- for (; __i < _S_categories_size; ++__i)
- {
- __env = std::getenv(_S_categories[__i]);
- if (__env && std::strcmp(__env, "") != 0
- && std::strcmp(__env, "C") != 0
- && std::strcmp(__env, "POSIX") != 0)
- break;
- }
- else
- for (; __i < _S_categories_size; ++__i)
- {
- __env = std::getenv(_S_categories[__i]);
- if (__env && std::strcmp(__env, "") != 0
- && __res != __env)
- break;
- }
-
- // If one is found, build the complete string of
- // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
- if (__i < _S_categories_size)
- {
- string __str;
- for (size_t __j = 0; __j < __i; ++__j)
- {
- __str += _S_categories[__j];
- __str += '=';
- __str += __res;
- __str += ';';
- }
- __str += _S_categories[__i];
- __str += '=';
- __str += __env;
- __str += ';';
- __i++;
- for (; __i < _S_categories_size; ++__i)
- {
- __env = std::getenv(_S_categories[__i]);
- if (!__env || std::strcmp(__env, "") == 0)
- {
- __str += _S_categories[__i];
- __str += '=';
- __str += __res;
- __str += ';';
- }
- else if (std::strcmp(__env, "C") == 0
- || std::strcmp(__env, "POSIX") == 0)
- {
- __str += _S_categories[__i];
- __str += "=C;";
- }
- else
- {
- __str += _S_categories[__i];
- __str += '=';
- __str += __env;
- __str += ';';
- }
- }
- __str.erase(__str.end() - 1);
- _M_impl = new _Impl(__str.c_str(), 1);
- }
- // ... otherwise either an additional instance of
- // the "C" locale or LANG.
- else if (__res == "C")
- (_M_impl = _S_classic)->_M_add_reference();
- else
- _M_impl = new _Impl(__res.c_str(), 1);
- }
- }
- }
- else
- __throw_runtime_error("locale::locale NULL not valid");
- }
-
- locale::locale(const locale& __base, const char* __s, category __cat)
- {
- // NB: There are complicated, yet more efficient ways to do
- // this. Building up locales on a per-category way is tedious, so
- // let's do it this way until people complain.
- locale __add(__s);
- _M_coalesce(__base, __add, __cat);
- }
-
- locale::locale(const locale& __base, const locale& __add, category __cat)
- { _M_coalesce(__base, __add, __cat); }
-
locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }
return *this;
}
- locale
- locale::global(const locale& __other)
- {
- _S_initialize();
-
- // XXX MT
- _Impl* __old = _S_global;
- __other._M_impl->_M_add_reference();
- _S_global = __other._M_impl;
- if (_S_global->_M_check_same_name()
- && (std::strcmp(_S_global->_M_names[0], "*") != 0))
- setlocale(LC_ALL, __other.name().c_str());
-
- // Reference count sanity check: one reference removed for the
- // subsition of __other locale, one added by return-by-value. Net
- // difference: zero. When the returned locale object's destrutor
- // is called, then the reference count is decremented and possibly
- // destroyed.
- return locale(__old);
- }
-
string
locale::name() const
{
return __ret;
}
- const locale&
- locale::classic()
- {
- _S_initialize();
- return c_locale;
- }
-
- void
- locale::_S_initialize_once()
- {
- // 2 references.
- // One reference for _S_classic, one for _S_global
- _S_classic = new (&c_locale_impl) _Impl(2);
- _S_global = _S_classic;
- new (&c_locale) locale(_S_classic);
- }
-
- void
- locale::_S_initialize()
- {
-#ifdef __GTHREADS
- if (__gthread_active_p())
- __gthread_once(&_S_once, _S_initialize_once);
-#endif
- if (!_S_classic)
- _S_initialize_once();
- }
-
- void
- locale::_M_coalesce(const locale& __base, const locale& __add,
- category __cat)
- {
- __cat = _S_normalize_category(__cat);
- _M_impl = new _Impl(*__base._M_impl, 1);
-
- try
- { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
- catch (...)
- {
- _M_impl->_M_remove_reference();
- __throw_exception_again;
- }
- }
-
locale::category
locale::_S_normalize_category(category __cat)
{
return __ret;
}
+ // locale::facet
__c_locale locale::facet::_S_c_locale;
const char locale::facet::_S_c_name[2] = "C";
__gthread_once_t locale::facet::_S_once = __GTHREAD_ONCE_INIT;
#endif
- locale::facet::
- ~facet() { }
-
void
locale::facet::_S_initialize_once()
{
locale::facet::_S_get_c_name()
{ return _S_c_name; }
- // Definitions for static const data members of time_base.
- template<>
- const char*
- __timepunct_cache<char>::_S_timezones[14] =
- {
- "GMT", "HST", "AKST", "PST", "MST", "CST", "EST", "AST", "NST", "CET",
- "IST", "EET", "CST", "JST"
- };
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- template<>
- const wchar_t*
- __timepunct_cache<wchar_t>::_S_timezones[14] =
- {
- L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST",
- L"NST", L"CET", L"IST", L"EET", L"CST", L"JST"
- };
-#endif
+ locale::facet::
+ ~facet() { }
- // Definitions for static const data members of money_base.
- const money_base::pattern
- money_base::_S_default_pattern = { {symbol, sign, none, value} };
+ // locale::_Impl
+ locale::_Impl::
+ ~_Impl() throw()
+ {
+ if (_M_facets)
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ if (_M_facets[__i])
+ _M_facets[__i]->_M_remove_reference();
+ delete [] _M_facets;
+
+ if (_M_caches)
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ if (_M_caches[__i])
+ _M_caches[__i]->_M_remove_reference();
+ delete [] _M_caches;
+
+ if (_M_names)
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ delete [] _M_names[__i];
+ delete [] _M_names;
+ }
- const char* __num_base::_S_atoms_in = "-+xX0123456789eEabcdfABCDF";
- const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
+ // Clone existing _Impl object.
+ locale::_Impl::
+ _Impl(const _Impl& __imp, size_t __refs)
+ : _M_references(__refs), _M_facets_size(__imp._M_facets_size)
+ {
+ _M_facets = _M_caches = 0;
+ _M_names = 0;
+ try
+ {
+ _M_facets = new const facet*[_M_facets_size];
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ {
+ _M_facets[__i] = __imp._M_facets[__i];
+ if (_M_facets[__i])
+ _M_facets[__i]->_M_add_reference();
+ }
+ _M_caches = new const facet*[_M_facets_size];
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ {
+ _M_caches[__i] = __imp._M_caches[__i];
+ if (_M_caches[__i])
+ _M_caches[__i]->_M_add_reference();
+ }
+ _M_names = new char*[_S_categories_size];
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ _M_names[__i] = 0;
+
+ // Name all the categories.
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ char* __new = new char[std::strlen(__imp._M_names[__i]) + 1];
+ std::strcpy(__new, __imp._M_names[__i]);
+ _M_names[__i] = __new;
+ }
+ }
+ catch(...)
+ {
+ this->~_Impl();
+ __throw_exception_again;
+ }
+ }
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // According to the resolution of DR 231, about 22.2.2.2.2, p11,
- // "str.precision() is specified in the conversion specification".
void
- __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod)
+ locale::_Impl::
+ _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
{
- ios_base::fmtflags __flags = __io.flags();
- *__fptr++ = '%';
- // [22.2.2.2.2] Table 60
- if (__flags & ios_base::showpos)
- *__fptr++ = '+';
- if (__flags & ios_base::showpoint)
- *__fptr++ = '#';
-
- // As per DR 231: _always_, not only when
- // __flags & ios_base::fixed || __prec > 0
- *__fptr++ = '.';
- *__fptr++ = '*';
-
- if (__mod)
- *__fptr++ = __mod;
- ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
- // [22.2.2.2.2] Table 58
- if (__fltfield == ios_base::fixed)
- *__fptr++ = 'f';
- else if (__fltfield == ios_base::scientific)
- *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
- else
- *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
- *__fptr = '\0';
+ for (; *__idpp; ++__idpp)
+ _M_replace_facet(__imp, *__idpp);
+ }
+
+ void
+ locale::_Impl::
+ _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
+ {
+ size_t __index = __idp->_M_id();
+ if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index])
+ __throw_runtime_error("locale::_Impl::_M_replace_facet");
+ _M_install_facet(__idp, __imp->_M_facets[__index]);
+ }
+
+ void
+ locale::_Impl::
+ _M_install_facet(const locale::id* __idp, const facet* __fp)
+ {
+ if (__fp)
+ {
+ size_t __index = __idp->_M_id();
+
+ // Check size of facet vector to ensure adequate room.
+ if (__index > _M_facets_size - 1)
+ {
+ const size_t __new_size = __index + 4;
+
+ // New facet array.
+ const facet** __oldf = _M_facets;
+ const facet** __newf;
+ __newf = new const facet*[__new_size];
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ __newf[__i] = _M_facets[__i];
+ for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
+ __newf[__i2] = 0;
+
+ // New cache array.
+ const facet** __oldc = _M_caches;
+ const facet** __newc;
+ try
+ {
+ __newc = new const facet*[__new_size];
+ }
+ catch(...)
+ {
+ delete [] __newf;
+ __throw_exception_again;
+ }
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ __newc[__i] = _M_caches[__i];
+ for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
+ __newc[__i2] = 0;
+
+ _M_facets_size = __new_size;
+ _M_facets = __newf;
+ _M_caches = __newc;
+ delete [] __oldf;
+ delete [] __oldc;
+ }
+
+ __fp->_M_add_reference();
+ const facet*& __fpr = _M_facets[__index];
+ if (__fpr)
+ {
+ // Replacing an existing facet. Order matters.
+ __fpr->_M_remove_reference();
+ __fpr = __fp;
+ }
+ else
+ {
+ // Installing a newly created facet into an empty
+ // _M_facets container, say a newly-constructed,
+ // swanky-fresh _Impl.
+ _M_facets[__index] = __fp;
+ }
+
+ // Ideally, it would be nice to only remove the caches that
+ // are now incorrect. However, some of the caches depend on
+ // multiple facets, and we only know about one facet
+ // here. It's no great loss: the first use of the new facet
+ // will create a new, correctly cached facet anyway.
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ {
+ const facet* __cpr = _M_caches[__i];
+ if (__cpr)
+ {
+ __cpr->_M_remove_reference();
+ _M_caches[__i] = 0;
+ }
+ }
+ }
+ }
+
+
+ // locale::id
+ // Definitions for static const data members of locale::id
+ _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker
+
+ size_t
+ locale::id::_M_id() const
+ {
+ if (!_M_index)
+ _M_index = 1 + __exchange_and_add(&_S_highwater, 1);
+ return _M_index - 1;
}
} // namespace std
+
--- /dev/null
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <locale>
+
+namespace std
+{
+ // Definitions for static const data members of time_base.
+ template<>
+ const char*
+ __timepunct_cache<char>::_S_timezones[14] =
+ {
+ "GMT", "HST", "AKST", "PST", "MST", "CST", "EST", "AST", "NST", "CET",
+ "IST", "EET", "CST", "JST"
+ };
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ template<>
+ const wchar_t*
+ __timepunct_cache<wchar_t>::_S_timezones[14] =
+ {
+ L"GMT", L"HST", L"AKST", L"PST", L"MST", L"CST", L"EST", L"AST",
+ L"NST", L"CET", L"IST", L"EET", L"CST", L"JST"
+ };
+#endif
+
+ // Definitions for static const data members of money_base.
+ const money_base::pattern
+ money_base::_S_default_pattern = { {symbol, sign, none, value} };
+
+ const char* __num_base::_S_atoms_in = "-+xX0123456789eEabcdfABCDF";
+ const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF";
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // According to the resolution of DR 231, about 22.2.2.2.2, p11,
+ // "str.precision() is specified in the conversion specification".
+ void
+ __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod)
+ {
+ ios_base::fmtflags __flags = __io.flags();
+ *__fptr++ = '%';
+ // [22.2.2.2.2] Table 60
+ if (__flags & ios_base::showpos)
+ *__fptr++ = '+';
+ if (__flags & ios_base::showpoint)
+ *__fptr++ = '#';
+
+ // As per DR 231: _always_, not only when
+ // __flags & ios_base::fixed || __prec > 0
+ *__fptr++ = '.';
+ *__fptr++ = '*';
+
+ if (__mod)
+ *__fptr++ = __mod;
+ ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
+ // [22.2.2.2.2] Table 58
+ if (__fltfield == ios_base::fixed)
+ *__fptr++ = 'f';
+ else if (__fltfield == ios_base::scientific)
+ *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e';
+ else
+ *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
+ *__fptr = '\0';
+ }
+} // namespace std
+
--- /dev/null
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <clocale>
+#include <cstring>
+#include <cstdlib> // For getenv, free.
+#include <cctype>
+#include <cwctype> // For towupper, etc.
+#include <locale>
+#include <bits/atomicity.h>
+
+namespace __gnu_cxx
+{
+ // Defined in globals.cc.
+ extern std::locale c_locale;
+ extern std::locale::_Impl c_locale_impl;
+
+ extern std::locale::facet* facet_vec[_GLIBCXX_NUM_FACETS];
+ extern char* name_vec[6 + _GLIBCXX_NUM_CATEGORIES];
+ extern char name_c[6 + _GLIBCXX_NUM_CATEGORIES][2];
+
+ extern std::ctype<char> ctype_c;
+ extern std::collate<char> collate_c;
+ extern std::numpunct<char> numpunct_c;
+ extern std::num_get<char> num_get_c;
+ extern std::num_put<char> num_put_c;
+ extern std::codecvt<char, char, mbstate_t> codecvt_c;
+ extern std::moneypunct<char, false> moneypunct_cf;
+ extern std::moneypunct<char, true> moneypunct_ct;
+ extern std::money_get<char> money_get_c;
+ extern std::money_put<char> money_put_c;
+ extern std::__timepunct<char> timepunct_c;
+ extern std::time_get<char> time_get_c;
+ extern std::time_put<char> time_put_c;
+ extern std::messages<char> messages_c;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ extern std::ctype<wchar_t> ctype_w;
+ extern std::collate<wchar_t> collate_w;
+ extern std::numpunct<wchar_t> numpunct_w;
+ extern std::num_get<wchar_t> num_get_w;
+ extern std::num_put<wchar_t> num_put_w;
+ extern std::codecvt<wchar_t, char, mbstate_t> codecvt_w;
+ extern std::moneypunct<wchar_t, false> moneypunct_wf;
+ extern std::moneypunct<wchar_t, true> moneypunct_wt;
+ extern std::money_get<wchar_t> money_get_w;
+ extern std::money_put<wchar_t> money_put_w;
+ extern std::__timepunct<wchar_t> timepunct_w;
+ extern std::time_get<wchar_t> time_get_w;
+ extern std::time_put<wchar_t> time_put_w;
+ extern std::messages<wchar_t> messages_w;
+#endif
+
+ // And the caches....
+ extern std::locale::facet* cache_vec[_GLIBCXX_NUM_FACETS];
+ extern std::__numpunct_cache<char> numpunct_cache_c;
+ extern std::__moneypunct_cache<char> moneypunct_cache_cf;
+ extern std::__moneypunct_cache<char> moneypunct_cache_ct;
+ extern std::__timepunct_cache<char> timepunct_cache_c;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ extern std::__numpunct_cache<wchar_t> numpunct_cache_w;
+ extern std::__moneypunct_cache<wchar_t> moneypunct_cache_wf;
+ extern std::__moneypunct_cache<wchar_t> moneypunct_cache_wt;
+ extern std::__timepunct_cache<wchar_t> timepunct_cache_w;
+#endif
+} // namespace __gnu_cxx
+
+namespace std
+{
+ using namespace __gnu_cxx;
+
+ locale::locale() throw()
+ {
+ _S_initialize();
+ (_M_impl = _S_global)->_M_add_reference();
+ }
+
+ locale
+ locale::global(const locale& __other)
+ {
+ _S_initialize();
+
+ // XXX MT
+ _Impl* __old = _S_global;
+ __other._M_impl->_M_add_reference();
+ _S_global = __other._M_impl;
+ if (_S_global->_M_check_same_name()
+ && (std::strcmp(_S_global->_M_names[0], "*") != 0))
+ setlocale(LC_ALL, __other.name().c_str());
+
+ // Reference count sanity check: one reference removed for the
+ // subsition of __other locale, one added by return-by-value. Net
+ // difference: zero. When the returned locale object's destrutor
+ // is called, then the reference count is decremented and possibly
+ // destroyed.
+ return locale(__old);
+ }
+
+ const locale&
+ locale::classic()
+ {
+ _S_initialize();
+ return c_locale;
+ }
+
+ void
+ locale::_S_initialize_once()
+ {
+ // 2 references.
+ // One reference for _S_classic, one for _S_global
+ _S_classic = new (&c_locale_impl) _Impl(2);
+ _S_global = _S_classic;
+ new (&c_locale) locale(_S_classic);
+ }
+
+ void
+ locale::_S_initialize()
+ {
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ __gthread_once(&_S_once, _S_initialize_once);
+ else
+#endif
+ {
+ if (!_S_classic)
+ _S_initialize_once();
+ }
+ }
+
+ // Definitions for static const data members of locale::_Impl
+ const locale::id* const
+ locale::_Impl::_S_id_ctype[] =
+ {
+ &std::ctype<char>::id,
+ &codecvt<char, char, mbstate_t>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &std::ctype<wchar_t>::id,
+ &codecvt<wchar_t, char, mbstate_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_numeric[] =
+ {
+ &num_get<char>::id,
+ &num_put<char>::id,
+ &numpunct<char>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &num_get<wchar_t>::id,
+ &num_put<wchar_t>::id,
+ &numpunct<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_collate[] =
+ {
+ &std::collate<char>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &std::collate<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_time[] =
+ {
+ &__timepunct<char>::id,
+ &time_get<char>::id,
+ &time_put<char>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &__timepunct<wchar_t>::id,
+ &time_get<wchar_t>::id,
+ &time_put<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_monetary[] =
+ {
+ &money_get<char>::id,
+ &money_put<char>::id,
+ &moneypunct<char, false>::id,
+ &moneypunct<char, true >::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &money_get<wchar_t>::id,
+ &money_put<wchar_t>::id,
+ &moneypunct<wchar_t, false>::id,
+ &moneypunct<wchar_t, true >::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_messages[] =
+ {
+ &std::messages<char>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+ &std::messages<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const* const
+ locale::_Impl::_S_facet_categories[] =
+ {
+ // Order must match the decl order in class locale.
+ locale::_Impl::_S_id_ctype,
+ locale::_Impl::_S_id_numeric,
+ locale::_Impl::_S_id_collate,
+ locale::_Impl::_S_id_time,
+ locale::_Impl::_S_id_monetary,
+ locale::_Impl::_S_id_messages,
+ 0
+ };
+
+ // Construct "C" _Impl.
+ locale::_Impl::
+ _Impl(size_t __refs) throw()
+ : _M_references(__refs), _M_facets_size(_GLIBCXX_NUM_FACETS)
+ {
+ _M_facets = new (&facet_vec) const facet*[_M_facets_size];
+ _M_caches = new (&cache_vec) const facet*[_M_facets_size];
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ _M_facets[__i] = _M_caches[__i] = 0;
+
+ // Name all the categories.
+ _M_names = new (&name_vec) char*[_S_categories_size];
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ _M_names[__i] = new (&name_c[__i]) char[2];
+ std::strcpy(_M_names[__i], locale::facet::_S_get_c_name());
+ }
+
+ // This is needed as presently the C++ version of "C" locales
+ // != data in the underlying locale model for __timepunct,
+ // numpunct, and moneypunct. Also, the "C" locales must be
+ // constructed in a way such that they are pre-allocated.
+ // NB: Set locale::facets(ref) count to one so that each individual
+ // facet is not destroyed when the locale (and thus locale::_Impl) is
+ // destroyed.
+ _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
+ _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
+
+ typedef __numpunct_cache<char> num_cache_c;
+ num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
+ _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
+
+ _M_init_facet(new (&num_get_c) num_get<char>(1));
+ _M_init_facet(new (&num_put_c) num_put<char>(1));
+ _M_init_facet(new (&collate_c) std::collate<char>(1));
+
+ typedef __moneypunct_cache<char> money_cache_c;
+ money_cache_c* __mpcf = new (&moneypunct_cache_cf) money_cache_c(2);
+ _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1));
+ money_cache_c* __mpct = new (&moneypunct_cache_ct) money_cache_c(2);
+ _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1));
+
+ _M_init_facet(new (&money_get_c) money_get<char>(1));
+ _M_init_facet(new (&money_put_c) money_put<char>(1));
+
+ typedef __timepunct_cache<char> time_cache_c;
+ time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2);
+ _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1));
+
+ _M_init_facet(new (&time_get_c) time_get<char>(1));
+ _M_init_facet(new (&time_put_c) time_put<char>(1));
+ _M_init_facet(new (&messages_c) std::messages<char>(1));
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+ _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
+ _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
+
+ typedef __numpunct_cache<wchar_t> num_cache_w;
+ num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
+ _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
+
+ _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
+ _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
+ _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
+
+ typedef __moneypunct_cache<wchar_t> money_cache_w;
+ money_cache_w* __mpwf = new (&moneypunct_cache_wf) money_cache_w(2);
+ _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1));
+ money_cache_w* __mpwt = new (&moneypunct_cache_wt) money_cache_w(2);
+ _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1));
+
+ _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
+ _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
+
+ typedef __timepunct_cache<wchar_t> time_cache_w;
+ time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2);
+ _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1));
+
+ _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
+ _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
+ _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
+#endif
+
+ // This locale is safe to pre-cache, after all the facets have
+ // been created and installed.
+ _M_caches[numpunct<char>::id._M_id()] = __npc;
+ _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
+ _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
+ _M_caches[__timepunct<char>::id._M_id()] = __tpc;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ _M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
+ _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf;
+ _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt;
+ _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw;
+#endif
+ }
+} // namespace std
#include <cstring>
#include <locale>
-namespace __gnu_cxx
-{
- using namespace std;
-
- // Defined in globals.cc.
- extern locale::facet* facet_vec[_GLIBCXX_NUM_FACETS];
- extern char* name_vec[6 + _GLIBCXX_NUM_CATEGORIES];
- extern char name_c[6 + _GLIBCXX_NUM_CATEGORIES][2];
-
- extern std::ctype<char> ctype_c;
- extern std::collate<char> collate_c;
- extern numpunct<char> numpunct_c;
- extern num_get<char> num_get_c;
- extern num_put<char> num_put_c;
- extern codecvt<char, char, mbstate_t> codecvt_c;
- extern moneypunct<char, false> moneypunct_cf;
- extern moneypunct<char, true> moneypunct_ct;
- extern money_get<char> money_get_c;
- extern money_put<char> money_put_c;
- extern __timepunct<char> timepunct_c;
- extern time_get<char> time_get_c;
- extern time_put<char> time_put_c;
- extern std::messages<char> messages_c;
-#ifdef _GLIBCXX_USE_WCHAR_T
- extern std::ctype<wchar_t> ctype_w;
- extern std::collate<wchar_t> collate_w;
- extern numpunct<wchar_t> numpunct_w;
- extern num_get<wchar_t> num_get_w;
- extern num_put<wchar_t> num_put_w;
- extern codecvt<wchar_t, char, mbstate_t> codecvt_w;
- extern moneypunct<wchar_t, false> moneypunct_wf;
- extern moneypunct<wchar_t, true> moneypunct_wt;
- extern money_get<wchar_t> money_get_w;
- extern money_put<wchar_t> money_put_w;
- extern __timepunct<wchar_t> timepunct_w;
- extern time_get<wchar_t> time_get_w;
- extern time_put<wchar_t> time_put_w;
- extern std::messages<wchar_t> messages_w;
-#endif
-
- // And the caches....
- extern locale::facet* cache_vec[_GLIBCXX_NUM_FACETS];
- extern __numpunct_cache<char> numpunct_cache_c;
- extern __moneypunct_cache<char> moneypunct_cache_cf;
- extern __moneypunct_cache<char> moneypunct_cache_ct;
- extern __timepunct_cache<char> timepunct_cache_c;
-#ifdef _GLIBCXX_USE_WCHAR_T
- extern __numpunct_cache<wchar_t> numpunct_cache_w;
- extern __moneypunct_cache<wchar_t> moneypunct_cache_wf;
- extern __moneypunct_cache<wchar_t> moneypunct_cache_wt;
- extern __timepunct_cache<wchar_t> timepunct_cache_w;
-#endif
-} // namespace __gnu_cxx
-
namespace std
{
using namespace __gnu_cxx;
- locale::_Impl::
- ~_Impl() throw()
- {
- if (_M_facets)
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- if (_M_facets[__i])
- _M_facets[__i]->_M_remove_reference();
- delete [] _M_facets;
-
- if (_M_caches)
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- if (_M_caches[__i])
- _M_caches[__i]->_M_remove_reference();
- delete [] _M_caches;
-
- if (_M_names)
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- delete [] _M_names[__i];
- delete [] _M_names;
- }
-
- // Clone existing _Impl object.
- locale::_Impl::
- _Impl(const _Impl& __imp, size_t __refs)
- : _M_references(__refs), _M_facets_size(__imp._M_facets_size)
+
+ locale::locale(const char* __s)
{
- _M_facets = _M_caches = 0;
- _M_names = 0;
- try
+ if (__s)
{
- _M_facets = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- {
- _M_facets[__i] = __imp._M_facets[__i];
- if (_M_facets[__i])
- _M_facets[__i]->_M_add_reference();
- }
- _M_caches = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- {
- _M_caches[__i] = __imp._M_caches[__i];
- if (_M_caches[__i])
- _M_caches[__i]->_M_add_reference();
- }
- _M_names = new char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- _M_names[__i] = 0;
-
- // Name all the categories.
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ _S_initialize();
+ if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
+ (_M_impl = _S_classic)->_M_add_reference();
+ else if (std::strcmp(__s, "") != 0)
+ _M_impl = new _Impl(__s, 1);
+ else
{
- char* __new = new char[std::strlen(__imp._M_names[__i]) + 1];
- std::strcpy(__new, __imp._M_names[__i]);
- _M_names[__i] = __new;
+ // Get it from the environment.
+ char* __env = std::getenv("LC_ALL");
+ // If LC_ALL is set we are done.
+ if (__env && std::strcmp(__env, "") != 0)
+ {
+ if (std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ (_M_impl = _S_classic)->_M_add_reference();
+ else
+ _M_impl = new _Impl(__env, 1);
+ }
+ else
+ {
+ string __res;
+ // LANG may set a default different from "C".
+ char* __env = std::getenv("LANG");
+ if (!__env || std::strcmp(__env, "") == 0
+ || std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ __res = "C";
+ else
+ __res = __env;
+
+ // Scan the categories looking for the first one
+ // different from LANG.
+ size_t __i = 0;
+ if (__res == "C")
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ if (__env && std::strcmp(__env, "") != 0
+ && std::strcmp(__env, "C") != 0
+ && std::strcmp(__env, "POSIX") != 0)
+ break;
+ }
+ else
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ if (__env && std::strcmp(__env, "") != 0
+ && __res != __env)
+ break;
+ }
+
+ // If one is found, build the complete string of
+ // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
+ if (__i < _S_categories_size)
+ {
+ string __str;
+ for (size_t __j = 0; __j < __i; ++__j)
+ {
+ __str += _S_categories[__j];
+ __str += '=';
+ __str += __res;
+ __str += ';';
+ }
+ __str += _S_categories[__i];
+ __str += '=';
+ __str += __env;
+ __str += ';';
+ __i++;
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ if (!__env || std::strcmp(__env, "") == 0)
+ {
+ __str += _S_categories[__i];
+ __str += '=';
+ __str += __res;
+ __str += ';';
+ }
+ else if (std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ {
+ __str += _S_categories[__i];
+ __str += "=C;";
+ }
+ else
+ {
+ __str += _S_categories[__i];
+ __str += '=';
+ __str += __env;
+ __str += ';';
+ }
+ }
+ __str.erase(__str.end() - 1);
+ _M_impl = new _Impl(__str.c_str(), 1);
+ }
+ // ... otherwise either an additional instance of
+ // the "C" locale or LANG.
+ else if (__res == "C")
+ (_M_impl = _S_classic)->_M_add_reference();
+ else
+ _M_impl = new _Impl(__res.c_str(), 1);
+ }
}
}
- catch(...)
- {
- this->~_Impl();
+ else
+ __throw_runtime_error("locale::locale NULL not valid");
+ }
+
+ locale::locale(const locale& __base, const char* __s, category __cat)
+ {
+ // NB: There are complicated, yet more efficient ways to do
+ // this. Building up locales on a per-category way is tedious, so
+ // let's do it this way until people complain.
+ locale __add(__s);
+ _M_coalesce(__base, __add, __cat);
+ }
+
+ locale::locale(const locale& __base, const locale& __add, category __cat)
+ { _M_coalesce(__base, __add, __cat); }
+
+ void
+ locale::_M_coalesce(const locale& __base, const locale& __add,
+ category __cat)
+ {
+ __cat = _S_normalize_category(__cat);
+ _M_impl = new _Impl(*__base._M_impl, 1);
+
+ try
+ { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
+ catch (...)
+ {
+ _M_impl->_M_remove_reference();
__throw_exception_again;
}
}
}
}
- // Construct "C" _Impl.
- locale::_Impl::
- _Impl(size_t __refs) throw()
- : _M_references(__refs), _M_facets_size(_GLIBCXX_NUM_FACETS)
- {
- _M_facets = new (&facet_vec) const facet*[_M_facets_size];
- _M_caches = new (&cache_vec) const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = _M_caches[__i] = 0;
-
- // Name all the categories.
- _M_names = new (&name_vec) char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- _M_names[__i] = new (&name_c[__i]) char[2];
- std::strcpy(_M_names[__i], locale::facet::_S_get_c_name());
- }
-
- // This is needed as presently the C++ version of "C" locales
- // != data in the underlying locale model for __timepunct,
- // numpunct, and moneypunct. Also, the "C" locales must be
- // constructed in a way such that they are pre-allocated.
- // NB: Set locale::facets(ref) count to one so that each individual
- // facet is not destroyed when the locale (and thus locale::_Impl) is
- // destroyed.
- _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
- _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
-
- typedef __numpunct_cache<char> num_cache_c;
- num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
- _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
-
- _M_init_facet(new (&num_get_c) num_get<char>(1));
- _M_init_facet(new (&num_put_c) num_put<char>(1));
- _M_init_facet(new (&collate_c) std::collate<char>(1));
-
- typedef __moneypunct_cache<char> money_cache_c;
- money_cache_c* __mpcf = new (&moneypunct_cache_cf) money_cache_c(2);
- _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1));
- money_cache_c* __mpct = new (&moneypunct_cache_ct) money_cache_c(2);
- _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1));
-
- _M_init_facet(new (&money_get_c) money_get<char>(1));
- _M_init_facet(new (&money_put_c) money_put<char>(1));
-
- typedef __timepunct_cache<char> time_cache_c;
- time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2);
- _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1));
-
- _M_init_facet(new (&time_get_c) time_get<char>(1));
- _M_init_facet(new (&time_put_c) time_put<char>(1));
- _M_init_facet(new (&messages_c) std::messages<char>(1));
-
-#ifdef _GLIBCXX_USE_WCHAR_T
- _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
- _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
-
- typedef __numpunct_cache<wchar_t> num_cache_w;
- num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
- _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
-
- _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
- _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
- _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
-
- typedef __moneypunct_cache<wchar_t> money_cache_w;
- money_cache_w* __mpwf = new (&moneypunct_cache_wf) money_cache_w(2);
- _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1));
- money_cache_w* __mpwt = new (&moneypunct_cache_wt) money_cache_w(2);
- _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1));
-
- _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
- _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
-
- typedef __timepunct_cache<wchar_t> time_cache_w;
- time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2);
- _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1));
-
- _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
- _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
- _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
-#endif
-
- // This locale is safe to pre-cache, after all the facets have
- // been created and installed.
- _M_caches[numpunct<char>::id._M_id()] = __npc;
- _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
- _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
- _M_caches[__timepunct<char>::id._M_id()] = __tpc;
-#ifdef _GLIBCXX_USE_WCHAR_T
- _M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
- _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf;
- _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt;
- _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw;
-#endif
- }
-
void
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
}
}
}
-
- void
- locale::_Impl::
- _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
- {
- for (; *__idpp; ++__idpp)
- _M_replace_facet(__imp, *__idpp);
- }
-
- void
- locale::_Impl::
- _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
- {
- const size_t __index = __idp->_M_id();
- if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index])
- __throw_runtime_error("locale::_Impl::_M_replace_facet");
- _M_install_facet(__idp, __imp->_M_facets[__index]);
- }
-
- void
- locale::_Impl::
- _M_install_facet(const locale::id* __idp, const facet* __fp)
- {
- if (__fp)
- {
- size_t __index = __idp->_M_id();
-
- // Check size of facet vector to ensure adequate room.
- if (__index > _M_facets_size - 1)
- {
- const size_t __new_size = __index + 4;
-
- // New facet array.
- const facet** __oldf = _M_facets;
- const facet** __newf;
- __newf = new const facet*[__new_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- __newf[__i] = _M_facets[__i];
- for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
- __newf[__i2] = 0;
-
- // New cache array.
- const facet** __oldc = _M_caches;
- const facet** __newc;
- try
- {
- __newc = new const facet*[__new_size];
- }
- catch(...)
- {
- delete [] __newf;
- __throw_exception_again;
- }
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- __newc[__i] = _M_caches[__i];
- for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
- __newc[__i2] = 0;
-
- _M_facets_size = __new_size;
- _M_facets = __newf;
- _M_caches = __newc;
- delete [] __oldf;
- delete [] __oldc;
- }
-
- __fp->_M_add_reference();
- const facet*& __fpr = _M_facets[__index];
- if (__fpr)
- {
- // Replacing an existing facet. Order matters.
- __fpr->_M_remove_reference();
- __fpr = __fp;
- }
- else
- {
- // Installing a newly created facet into an empty
- // _M_facets container, say a newly-constructed,
- // swanky-fresh _Impl.
- _M_facets[__index] = __fp;
- }
-
- // Ideally, it would be nice to only remove the caches that
- // are now incorrect. However, some of the caches depend on
- // multiple facets, and we only know about one facet
- // here. It's no great loss: the first use of the new facet
- // will create a new, correctly cached facet anyway.
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- {
- const facet* __cpr = _M_caches[__i];
- if (__cpr)
- {
- __cpr->_M_remove_reference();
- _M_caches[__i] = 0;
- }
- }
- }
- }
} // namespace std
--- /dev/null
+// Locale support -*- C++ -*-
+
+// Copyright (C) 1999, 2000, 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 22.1 Locales
+//
+
+#include <bits/c++config.h>
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+#define C wchar_t
+#include "locale-inst.cc"
+#endif
+// wide string support -*- C++ -*-
+
+// Copyright (C) 1999, 2000, 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882: 21 Strings library
+//
+
#include <bits/c++config.h>
#ifdef _GLIBCXX_USE_WCHAR_T