diff options
author | Paolo Carlini <pcarlini@suse.de> | 2006-04-12 16:12:00 +0000 |
---|---|---|
committer | Paolo Carlini <pcarlini@suse.de> | 2006-04-12 16:12:00 +0000 |
commit | d91d418efff36798b5e67090452c7bf18f94c2ec (patch) | |
tree | 4d6376429e41d8ba1efdf2f25cfa8f241763818a | |
parent | e1598fe99d825879716ad9a28cec99dbff50fc68 (diff) |
2006-04-12 Paolo Carlini <pcarlini@suse.de>
* include/std/std_stdexcept.h (class __exception_string): Add.
(class logic_error, class runtime_error): Use it.
* src/stdexcept.cc (_exception_string::_Rep::_M_destroy,
__exception_string::__exception_string(const string&),
__exception_string::operator=(const __exception_string&)): Define.
* config/abi/pre/gnu.ver: Update exports.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/libstdcxx_so_7-branch@112888 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libstdc++-v3/ChangeLog.libstdcxx_so_7-branch | 9 | ||||
-rw-r--r-- | libstdc++-v3/config/abi/pre/gnu.ver | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/std_stdexcept.h | 64 | ||||
-rw-r--r-- | libstdc++-v3/src/stdexcept.cc | 40 |
4 files changed, 111 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch index 3a4626ce3f0..b8d2f6be5ea 100644 --- a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch +++ b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch @@ -1,3 +1,12 @@ +2006-04-12 Paolo Carlini <pcarlini@suse.de> + + * include/std/std_stdexcept.h (class __exception_string): Add. + (class logic_error, class runtime_error): Use it. + * src/stdexcept.cc (_exception_string::_Rep::_M_destroy, + __exception_string::__exception_string(const string&), + __exception_string::operator=(const __exception_string&)): Define. + * config/abi/pre/gnu.ver: Update exports. + 2006-04-11 Paolo Carlini <pcarlini@suse.de> Merged to mainline at revision 112818. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index f6be5e96867..0dfa152c01e 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -614,6 +614,8 @@ GLIBCXX_4.2 { _ZNK9__gnu_cxx12__sso_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*; _ZZN9__gnu_cxx12__sso_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*; + _ZNSt18__exception_string*; + # DO NOT DELETE THIS LINE. Port-specific symbols, if any, will be here. local: diff --git a/libstdc++-v3/include/std/std_stdexcept.h b/libstdc++-v3/include/std/std_stdexcept.h index 0104e54464e..a9e49cb16d5 100644 --- a/libstdc++-v3/include/std/std_stdexcept.h +++ b/libstdc++-v3/include/std/std_stdexcept.h @@ -1,6 +1,7 @@ // Standard exception classes -*- C++ -*- -// Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// 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 @@ -42,9 +43,66 @@ #include <exception> #include <string> +#include <bits/atomicity.h> _GLIBCXX_BEGIN_NAMESPACE(std) + /** Reference-counted "mini-string" for internal use in the std exception + * classes, needed due to the no-throw requirements for copy-constructor + * and assignment operator, not fulfilled by sso_string. */ + class __exception_string + { + struct _Rep + { + size_t _M_size; + _Atomic_word _M_refcount; + + void + _M_destroy() throw(); + + void + _M_dispose() throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) <= 0) + _M_destroy(); + } + + char* + _M_refdata() throw() + { return reinterpret_cast<char*>(this + 1); } + + char* + _M_refcopy() throw() + { + __gnu_cxx::__atomic_add(&_M_refcount, 1); + return _M_refdata(); + } + }; + + char* _M_data; + + _Rep* + _M_rep() const throw() + { return &((reinterpret_cast<_Rep*>(_M_data))[-1]); } + + public: + __exception_string(const __exception_string& __ex_str) + : _M_data(__ex_str._M_rep()->_M_refcopy()) { } + + __exception_string(const string& __str); + + ~__exception_string() + { _M_rep()->_M_dispose(); } + + __exception_string& + operator=(const __exception_string& __ex_str); + + const char* + c_str() const + { return _M_data; } + }; + + /** Logic errors represent problems in the internal logic of a program; * in theory, these are preventable, and even detectable before the * program runs (e.g., violations of class invariants). @@ -52,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ class logic_error : public exception { - string _M_msg; + __exception_string _M_msg; public: /** Takes a character string describing the error. */ @@ -106,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ class runtime_error : public exception { - string _M_msg; + __exception_string _M_msg; public: /** Takes a character string describing the error. */ diff --git a/libstdc++-v3/src/stdexcept.cc b/libstdc++-v3/src/stdexcept.cc index 19ac5779eb5..51449ede7e1 100644 --- a/libstdc++-v3/src/stdexcept.cc +++ b/libstdc++-v3/src/stdexcept.cc @@ -1,6 +1,7 @@ // Methods for Exception Support for -*- C++ -*- -// Copyright (C) 1997, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +// 2005, 2006 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 @@ -36,6 +37,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std) + void + __exception_string::_Rep:: + _M_destroy() throw() + { + allocator<char>().deallocate(reinterpret_cast<char*>(this), + sizeof(_Rep) + _M_size); + } + + __exception_string:: + __exception_string(const string& __str) + { + const size_t __size = __str.size() + 1; + + void* __place = allocator<char>().allocate(sizeof(_Rep) + __size); + _Rep* __r = new (__place) _Rep; + + memcpy(__r->_M_refdata(), __str.c_str(), __size); + __r->_M_size = __size; + __r->_M_refcount = 0; + + _M_data = __r->_M_refdata(); + } + + __exception_string& + __exception_string:: + operator=(const __exception_string& __ex_str) + { + if (_M_rep() != __ex_str._M_rep()) + { + char* __tmp = __ex_str._M_rep()->_M_refcopy(); + _M_rep()->_M_dispose(); + _M_data = __tmp; + } + return *this; + } + + logic_error::logic_error(const string& __arg) : exception(), _M_msg(__arg) { } |