From ca6500fcd0812d2b2da8a62d52b3613b4cbab12a Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Sun, 1 Sep 2002 20:39:13 +0000 Subject: Gcc 3.2.1-prerelease libf2c bits from the FSF anoncvs repo gcc-3_2-branch on 1-Sep-2002 00:00:01 EDT. --- contrib/libstdc++/include/std/std_bitset.h | 99 ++++++- contrib/libstdc++/include/std/std_fstream.h | 11 +- contrib/libstdc++/include/std/std_istream.h | 10 + contrib/libstdc++/include/std/std_memory.h | 373 +++++++++++++++++++------- contrib/libstdc++/include/std/std_streambuf.h | 39 +-- 5 files changed, 409 insertions(+), 123 deletions(-) (limited to 'contrib/libstdc++/include/std') diff --git a/contrib/libstdc++/include/std/std_bitset.h b/contrib/libstdc++/include/std/std_bitset.h index 0945c90f5fca6..fe60b01f347ce 100644 --- a/contrib/libstdc++/include/std/std_bitset.h +++ b/contrib/libstdc++/include/std/std_bitset.h @@ -61,7 +61,7 @@ #define _GLIBCPP_BITSET_BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long)) #define _GLIBCPP_BITSET_WORDS(__n) \ - ((__n) < 1 ? 1 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD) + ((__n) < 1 ? 0 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD) namespace std { @@ -463,6 +463,101 @@ namespace std _M_do_find_next(size_t __prev, size_t __not_found) const; }; + + /** + * @if maint + * Base class, specialization for no storage (zero-length %bitset). + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<0> + { + typedef unsigned long _WordT; + + _Base_bitset() {} + _Base_bitset(unsigned long) {} + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + // This would normally give access to the data. The bounds-checking + // in the bitset class will prevent the user from getting this far, + // but (1) it must still return an lvalue to compile, and (2) the + // user might call _Unchecked_set directly, in which case this /needs/ + // to fail. Let's not penalize zero-length users unless they actually + // make an unchecked call; all the memory ugliness is therefore + // localized to this single should-never-get-this-far function. + _WordT& + _M_getword(size_t) const + { __throw_out_of_range("bitset -- zero-length"); return *new _WordT; } + + _WordT + _M_hiword() const { return 0; } + + void + _M_do_and(const _Base_bitset<0>&) { } + + void + _M_do_or(const _Base_bitset<0>&) { } + + void + _M_do_xor(const _Base_bitset<0>&) { } + + void + _M_do_left_shift(size_t) { } + + void + _M_do_right_shift(size_t) { } + + void + _M_do_flip() { } + + void + _M_do_set() { } + + void + _M_do_reset() { } + + // Are all empty bitsets equal to each other? Are they equal to + // themselves? How to compare a thing which has no state? What is + // the sound of one zero-length bitset clapping? + bool + _M_is_equal(const _Base_bitset<0>&) const { return true; } + + bool + _M_is_any() const { return false; } + + size_t + _M_do_count() const { return 0; } + + unsigned long + _M_do_to_ulong() const { return 0; } + + // Normally "not found" is the size, but that could also be + // misinterpreted as an index in this corner case. Oh well. + size_t + _M_do_find_first(size_t) const { return 0; } + + size_t + _M_do_find_next(size_t, size_t) const { return 0; } + }; + + // Helper class to zero out the unused high-order bits in the highest word. template struct _Sanitize @@ -1115,7 +1210,7 @@ namespace std } } - if (__tmp.empty()) + if (__tmp.empty() && !_Nb) __is.setstate(ios_base::failbit); else __x._M_copy_from_string(__tmp, static_cast(0), _Nb); diff --git a/contrib/libstdc++/include/std/std_fstream.h b/contrib/libstdc++/include/std/std_fstream.h index fb95965a06af3..c3861051d40b8 100644 --- a/contrib/libstdc++/include/std/std_fstream.h +++ b/contrib/libstdc++/include/std/std_fstream.h @@ -286,7 +286,16 @@ namespace std } }; - + // Explicit specializations. + template<> + basic_filebuf::int_type + basic_filebuf::_M_underflow_common(bool __bump); + + #ifdef _GLIBCPP_USE_WCHAR_T + template<> + basic_filebuf::int_type + basic_filebuf::_M_underflow_common(bool __bump); + #endif // 27.8.1.5 Template class basic_ifstream /** diff --git a/contrib/libstdc++/include/std/std_istream.h b/contrib/libstdc++/include/std/std_istream.h index 40f4b67fb9f75..8aa9123ed5c56 100644 --- a/contrib/libstdc++/include/std/std_istream.h +++ b/contrib/libstdc++/include/std/std_istream.h @@ -261,6 +261,16 @@ namespace std public basic_ostream<_CharT, _Traits> { public: +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS +// 271. basic_iostream missing typedefs + // Types (inherited): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; +#endif + // Non-standard Types: typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; diff --git a/contrib/libstdc++/include/std/std_memory.h b/contrib/libstdc++/include/std/std_memory.h index b7feb37aa4576..5850eb2a00754 100644 --- a/contrib/libstdc++/include/std/std_memory.h +++ b/contrib/libstdc++/include/std/std_memory.h @@ -58,147 +58,314 @@ #include #include +// Since this entire file is within namespace std, there's no reason to +// waste two spaces along the left column. Thus the leading indentation is +// slightly violated from here on. namespace std { +/** + * @if maint + * This is a helper function. The unused second parameter exists to + * permit the real get_temporary_buffer to use template parameter deduction. + * + * XXX This should perhaps use the pool. + * @endif +*/ +template +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); - /** - * @if maint - * This is a helper function. The unused second parameter exists to - * permit the real get_temporary_buffer to use template parameter deduction. - * @endif - */ - template - pair<_Tp*, ptrdiff_t> - __get_temporary_buffer(ptrdiff_t __len, _Tp*) - { - if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) - __len = INT_MAX / sizeof(_Tp); - - while (__len > 0) { - _Tp* __tmp = (_Tp*) std::malloc((std::size_t)__len * sizeof(_Tp)); - if (__tmp != 0) - return pair<_Tp*, ptrdiff_t>(__tmp, __len); - __len /= 2; - } - - return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); + while (__len > 0) { + _Tp* __tmp = (_Tp*) std::malloc((std::size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; } - /** - * @brief This is a mostly-useless wrapper around malloc(). - * @param len The number of objects of type Tp. - * @return See full description. - * - * Reinventing the wheel, but this time with prettier spokes! - * - * This function tries to obtain storage for @c len adjacent Tp objects. - * The objects themselves are not constructed, of course. A pair<> is - * returned containing "the buffer s address and capacity (in the units of - * sizeof(Tp)), or a pair of 0 values if no storage can be obtained." - * Note that the capacity obtained may be less than that requested if the - * memory is unavailable; you should compare len with the .second return - * value. - */ - template - inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); +} + +/** + * @brief This is a mostly-useless wrapper around malloc(). + * @param len The number of objects of type Tp. + * @return See full description. + * + * Reinventing the wheel, but this time with prettier spokes! + * + * This function tries to obtain storage for @c len adjacent Tp objects. + * The objects themselves are not constructed, of course. A pair<> is + * returned containing "the buffer s address and capacity (in the units of + * sizeof(Tp)), or a pair of 0 values if no storage can be obtained." + * Note that the capacity obtained may be less than that requested if the + * memory is unavailable; you should compare len with the .second return + * value. +*/ +template + inline pair<_Tp*,ptrdiff_t> + get_temporary_buffer(ptrdiff_t __len) + { return __get_temporary_buffer(__len, (_Tp*) 0); } - /** - * @brief The companion to get_temporary_buffer(). - * @param p A buffer previously allocated by get_temporary_buffer. - * @return None. - * - * Frees the memory pointed to by p. - */ - template - void return_temporary_buffer(_Tp* __p) { +/** + * @brief The companion to get_temporary_buffer(). + * @param p A buffer previously allocated by get_temporary_buffer. + * @return None. + * + * Frees the memory pointed to by p. + */ +template + void + return_temporary_buffer(_Tp* __p) + { std::free(__p); } -template +/** + * A wrapper class to provide auto_ptr with reference semantics. For + * example, an auto_ptr can be assigned (or constructed from) the result of + * a function which returns an auto_ptr by value. + * + * All the auto_ptr_ref stuff should happen behind the scenes. +*/ +template struct auto_ptr_ref { _Tp1* _M_ptr; - auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} + + explicit + auto_ptr_ref(_Tp1* __p) + : _M_ptr(__p) {} }; + /** - * A simple smart pointer providing strict ownership semantics. (More later.) + * @brief A simple smart pointer providing strict ownership semantics. + * + * The Standard says: + *
+ *  An @c auto_ptr owns the object it holds a pointer to.  Copying an
+ *  @c auto_ptr copies the pointer and transfers ownership to the destination.
+ *  If more than one @c auto_ptr owns the same object at the same time the
+ *  behavior of the program is undefined.
+ *
+ *  The uses of @c auto_ptr include providing temporary exception-safety for
+ *  dynamically allocated memory, passing ownership of dynamically allocated
+ *  memory to a function, and returning dynamically allocated memory from a
+ *  function.  @c auto_ptr does not meet the CopyConstructible and Assignable
+ *  requirements for Standard Library container
+ *  elements and thus instantiating a Standard Library container with an
+ *  @c auto_ptr results in undefined behavior.
+ *  
+ * Quoted from [20.4.5]/3. + * + * Good examples of what can and cannot be done with auto_ptr can be found + * in the libstdc++ testsuite. + * + * @if maint + * _GLIBCPP_RESOLVE_LIB_DEFECTS + * 127. auto_ptr<> conversion issues + * These resolutions have all been incorporated. + * @endif */ -template +template class auto_ptr { private: _Tp* _M_ptr; public: + /// The pointed-to type. typedef _Tp element_type; - explicit auto_ptr(_Tp* __p = 0) throw() : _M_ptr(__p) {} - auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) {} + /** + * @brief An %auto_ptr is usually constructed from a raw pointer. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. + */ + explicit + auto_ptr(element_type* __p = 0) throw() + : _M_ptr(__p) { } - template auto_ptr(auto_ptr<_Tp1>& __a) throw() - : _M_ptr(__a.release()) {} + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, which has + * given up ownsership. + */ + auto_ptr(auto_ptr& __a) throw() + : _M_ptr(__a.release()) { } - auto_ptr& operator=(auto_ptr& __a) throw() { - reset(__a.release()); - return *this; - } + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, which has + * given up ownsership. + */ + template + auto_ptr(auto_ptr<_Tp1>& __a) throw() + : _M_ptr(__a.release()) { } - template - auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw() { - reset(__a.release()); - return *this; - } - - // Note: The C++ standard says there is supposed to be an empty throw - // specification here, but omitting it is standard conforming. Its - // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2) - // this is prohibited. + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, which has + * given up ownsership. The object that this one @e used to own and + * track has been deleted. + */ + auto_ptr& + operator=(auto_ptr& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, which has + * given up ownsership. The object that this one @e used to own and + * track has been deleted. + */ + template + auto_ptr& + operator=(auto_ptr<_Tp1>& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * When the %auto_ptr goes out of scope, the object it owns is deleted. + * If it no longer owns anything (i.e., @c get() is @c NULL), then this + * has no effect. + * + * @if maint + * The C++ standard says there is supposed to be an empty throw + * specification here, but omitting it is standard conforming. Its + * presence can be detected only if _Tp::~_Tp() throws, but this is + * prohibited. [17.4.3.6]/2 + * @end maint + */ ~auto_ptr() { delete _M_ptr; } - - _Tp& operator*() const throw() { - return *_M_ptr; - } - _Tp* operator->() const throw() { - return _M_ptr; - } - _Tp* get() const throw() { - return _M_ptr; - } - _Tp* release() throw() { - _Tp* __tmp = _M_ptr; - _M_ptr = 0; - return __tmp; - } - void reset(_Tp* __p = 0) throw() { - if (__p != _M_ptr) { - delete _M_ptr; - _M_ptr = __p; - } - } -public: - auto_ptr(auto_ptr_ref<_Tp> __ref) throw() + /** + * @brief Smart pointer dereferencing. + * + * If this %auto_ptr no longer owns anything, then this operation will + * crash. (For a smart pointer, "no longer owns anything" is the same as + * being a null pointer, and you know what happens when you dereference + * one of those...) + */ + element_type& + operator*() const throw() { return *_M_ptr; } + + /** + * @brief Smart pointer dereferencing. + * + * This returns the pointer itself, which the language then will + * automatically cause to be dereferenced. + */ + element_type* + operator->() const throw() { return _M_ptr; } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts a raw + * pointer. + * + * @note This %auto_ptr still owns the memory. + */ + element_type* + get() const throw() { return _M_ptr; } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts a raw + * pointer. + * + * @note This %auto_ptr no longer owns the memory. When this object + * goes out of scope, nothing will happen. + */ + element_type* + release() throw() + { + element_type* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + + /** + * @brief Forcibly deletes the managed object. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. The previous + * object has been deleted. + */ + void + reset(element_type* __p = 0) throw() + { + if (__p != _M_ptr) + { + delete _M_ptr; + _M_ptr = __p; + } + } + + /** @{ + * @brief Automatic conversions + * + * These operations convert an %auto_ptr into and from an auto_ptr_ref + * automatically as needed. This allows constructs such as + * @code + * auto_ptr func_returning_auto_ptr(.....); + * ... + * auto_ptr ptr = func_returning_auto_ptr(.....); + * @endcode + */ + auto_ptr(auto_ptr_ref __ref) throw() : _M_ptr(__ref._M_ptr) {} - auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) throw() { - if (__ref._M_ptr != this->get()) { - delete _M_ptr; - _M_ptr = __ref._M_ptr; + auto_ptr& + operator=(auto_ptr_ref __ref) throw() + { + if (__ref._M_ptr != this->get()) + { + delete _M_ptr; + _M_ptr = __ref._M_ptr; + } + return *this; } - return *this; - } - template operator auto_ptr_ref<_Tp1>() throw() - { return auto_ptr_ref<_Tp>(this->release()); } - template operator auto_ptr<_Tp1>() throw() - { return auto_ptr<_Tp1>(this->release()); } + template + operator auto_ptr_ref<_Tp1>() throw() + { return auto_ptr_ref<_Tp1>(this->release()); } + + template + operator auto_ptr<_Tp1>() throw() + { return auto_ptr<_Tp1>(this->release()); } + /** @} */ }; } // namespace std #endif /* _CPP_MEMORY */ - diff --git a/contrib/libstdc++/include/std/std_streambuf.h b/contrib/libstdc++/include/std/std_streambuf.h index 012bf4e6cf6bf..491570ec59314 100644 --- a/contrib/libstdc++/include/std/std_streambuf.h +++ b/contrib/libstdc++/include/std/std_streambuf.h @@ -71,6 +71,7 @@ namespace std // Non-standard Types: typedef ctype __ctype_type; typedef basic_streambuf __streambuf_type; + typedef typename traits_type::state_type __state_type; friend class basic_ios; friend class basic_istream; @@ -91,10 +92,10 @@ namespace std char_type* _M_buf; // Actual size of allocated internal buffer, in bytes. - int_type _M_buf_size; + size_t _M_buf_size; // Optimal or preferred size of internal buffer, in bytes. - int_type _M_buf_size_opt; + size_t _M_buf_size_opt; // True iff _M_in_* and _M_out_* buffers should always point to // the same place. True for fstreams, false for sstreams. @@ -126,12 +127,15 @@ namespace std // requirements. The only basic_streambuf member function that // needs access to these data members is in_avail... // NB: pbacks of over one character are not currently supported. - static const int_type _S_pback_size = 1; + static const size_t _S_pback_size = 1; char_type _M_pback[_S_pback_size]; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; + // Yet unused. + fpos<__state_type> _M_pos; + // Initializes pback buffers, and moves normal buffers to safety. // Assumptions: // _M_in_cur has already been moved back @@ -140,8 +144,8 @@ namespace std { if (!_M_pback_init) { - int_type __dist = _M_in_end - _M_in_cur; - int_type __len = min(_S_pback_size, __dist); + size_t __dist = _M_in_end - _M_in_cur; + size_t __len = min(_S_pback_size, __dist); traits_type::copy(_M_pback, _M_in_cur, __len); _M_pback_cur_save = _M_in_cur; _M_pback_end_save = _M_in_end; @@ -159,12 +163,12 @@ namespace std if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. - int_type __off_cur = _M_in_cur - _M_pback; + size_t __off_cur = _M_in_cur - _M_pback; // For in | out buffers, the end can be pushed back... - int_type __off_end = 0; - int_type __pback_len = _M_in_end - _M_pback; - int_type __save_len = _M_pback_end_save - _M_buf; + size_t __off_end = 0; + size_t __pback_len = _M_in_end - _M_pback; + size_t __save_len = _M_pback_end_save - _M_buf; if (__pback_len > __save_len) __off_end = __pback_len - __save_len; @@ -288,8 +292,8 @@ namespace std { if (_M_pback_init) { - int_type __save_len = _M_pback_end_save - _M_pback_cur_save; - int_type __pback_len = _M_in_cur - _M_pback; + size_t __save_len = _M_pback_end_save - _M_pback_cur_save; + size_t __pback_len = _M_in_cur - _M_pback; __ret = __save_len - __pback_len; } else @@ -304,7 +308,8 @@ namespace std snextc() { int_type __eof = traits_type::eof(); - return (this->sbumpc() == __eof ? __eof : this->sgetc()); + return (traits_type::eq_int_type(this->sbumpc(), __eof) + ? __eof : this->sgetc()); } int_type @@ -342,10 +347,10 @@ namespace std protected: basic_streambuf() - : _M_buf(NULL), _M_buf_size(0), - _M_buf_size_opt(static_cast(BUFSIZ)), _M_buf_unified(false), - _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), - _M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), + : _M_buf(NULL), _M_buf_size(0), _M_buf_size_opt(BUFSIZ), + _M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), _M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false) { } @@ -438,7 +443,7 @@ namespace std uflow() { int_type __ret = traits_type::eof(); - bool __testeof = this->underflow() == __ret; + bool __testeof = traits_type::eq_int_type(this->underflow(), __ret); bool __testpending = _M_in_cur && _M_in_cur < _M_in_end; if (!__testeof && __testpending) { -- cgit v1.3