diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4203624bbb1..1bbe7bc3130 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2001-06-18 Benjamin Kosnik + + * include/bits/stl_raw_storage_iter.h: Format. Correct derivation. + * testsuite/20_util/raw_storage_iterator.cc: Same. + + * include/bits/stl_alloc.h (_S_chunk_alloc): Change malloc to + operator new. + (__mem_interface): New typedef for switching between malloc and new. + * testsuite/20_util/allocator_members.cc: New file. + + * testsuite/20_util/comparisons.cc: New file. + * testsuite/20_util/pairs.cc: New file. + 2001-06-15 Phil Edwards * docs/html/documentation.html: Point to new doxygen'ed collection. diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h index 9a0ef07e604..f8fa732fb4f 100644 --- a/libstdc++-v3/include/bits/stl_alloc.h +++ b/libstdc++-v3/include/bits/stl_alloc.h @@ -67,85 +67,106 @@ namespace std { - -// Malloc-based allocator. Typically slower than default alloc below. -// Typically thread-safe and more storage efficient. -template -class __malloc_alloc_template { - -private: - - static void* _S_oom_malloc(size_t); - static void* _S_oom_realloc(void*, size_t); - static void (* __malloc_alloc_oom_handler)(); - -public: - - static void* allocate(size_t __n) + // A new-based allocator, as required by the standard. + class __new_alloc { - void* __result = malloc(__n); - if (0 == __result) __result = _S_oom_malloc(__n); - return __result; - } + public: + static void* + allocate(size_t __n) + { return ::operator new(__n); } + + static void + deallocate(void* __p, size_t) + { ::operator delete(__p); } + }; + + // Malloc-based allocator. Typically slower than default alloc below. + // Typically thread-safe and more storage efficient. + template + class __malloc_alloc_template + { + private: + static void* _S_oom_malloc(size_t); + static void* _S_oom_realloc(void*, size_t); + static void (* __malloc_alloc_oom_handler)(); + + public: + static void* + allocate(size_t __n) + { + void* __result = malloc(__n); + if (0 == __result) __result = _S_oom_malloc(__n); + return __result; + } - static void deallocate(void* __p, size_t /* __n */) - { - free(__p); - } + static void + deallocate(void* __p, size_t /* __n */) + { free(__p); } - static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) - { - void* __result = realloc(__p, __new_sz); - if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); - return __result; - } + static void* + reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) + { + void* __result = realloc(__p, __new_sz); + if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); + return __result; + } + + static void (* __set_malloc_handler(void (*__f)()))() + { + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return(__old); + } + }; - static void (* __set_malloc_handler(void (*__f)()))() - { - void (* __old)() = __malloc_alloc_oom_handler; - __malloc_alloc_oom_handler = __f; - return(__old); - } + // malloc_alloc out-of-memory handling + template + void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; -}; - -// malloc_alloc out-of-memory handling - -template -void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; - -template -void* -__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) -{ - void (* __my_malloc_handler)(); - void* __result; - - for (;;) { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == __my_malloc_handler) { std::__throw_bad_alloc(); } - (*__my_malloc_handler)(); - __result = malloc(__n); - if (__result) return(__result); + template + void* + __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) + { + void (* __my_malloc_handler)(); + void* __result; + + for (;;) + { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) + std::__throw_bad_alloc(); + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) + return(__result); + } } -} - -template -void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) -{ - void (* __my_malloc_handler)(); - void* __result; - - for (;;) { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == __my_malloc_handler) { std::__throw_bad_alloc(); } - (*__my_malloc_handler)(); - __result = realloc(__p, __n); - if (__result) return(__result); + + template + void* + __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) + { + void (* __my_malloc_handler)(); + void* __result; + + for (;;) + { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) + std::__throw_bad_alloc(); + (*__my_malloc_handler)(); + __result = realloc(__p, __n); + if (__result) + return(__result); + } } -} -typedef __malloc_alloc_template<0> malloc_alloc; + // Determines the underlying allocator choice. +# ifdef __USE_MALLOC + typedef __malloc_alloc_template<0> __mem_interface; +#else + typedef __new_alloc __mem_interface; +#endif template class simple_alloc { @@ -295,28 +316,28 @@ public: { void* __ret = 0; - if (__n > (size_t) _MAX_BYTES) { - __ret = malloc_alloc::allocate(__n); - } - else { - _Obj* __STL_VOLATILE* __my_free_list - = _S_free_list + _S_freelist_index(__n); - // Acquire the lock here with a constructor call. - // This ensures that it is released in exit or during stack - // unwinding. + if (__n > (size_t) _MAX_BYTES) + __ret = __mem_interface::allocate(__n); + else + { + _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n); + // Acquire the lock here with a constructor call. + // This ensures that it is released in exit or during stack + // unwinding. # ifndef _NOTHREADS - /*REFERENCED*/ - _Lock __lock_instance; + /*REFERENCED*/ + _Lock __lock_instance; # endif - _Obj* __RESTRICT __result = *__my_free_list; - if (__result == 0) - __ret = _S_refill(_S_round_up(__n)); - else { - *__my_free_list = __result -> _M_free_list_link; - __ret = __result; + _Obj* __RESTRICT __result = *__my_free_list; + if (__result == 0) + __ret = _S_refill(_S_round_up(__n)); + else + { + *__my_free_list = __result -> _M_free_list_link; + __ret = __result; + } } - } - + return __ret; }; @@ -324,26 +345,26 @@ public: static void deallocate(void* __p, size_t __n) { if (__n > (size_t) _MAX_BYTES) - malloc_alloc::deallocate(__p, __n); - else { - _Obj* __STL_VOLATILE* __my_free_list + __mem_interface::deallocate(__p, __n); + else + { + _Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n); - _Obj* __q = (_Obj*)__p; - - // acquire lock + _Obj* __q = (_Obj*)__p; + + // acquire lock # ifndef _NOTHREADS - /*REFERENCED*/ - _Lock __lock_instance; + /*REFERENCED*/ + _Lock __lock_instance; # endif /* _NOTHREADS */ - __q -> _M_free_list_link = *__my_free_list; - *__my_free_list = __q; - // lock is released here - } + __q -> _M_free_list_link = *__my_free_list; + *__my_free_list = __q; + // lock is released here + } } - + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); - -} ; +}; typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; typedef __default_alloc_template single_client_alloc; @@ -377,59 +398,67 @@ __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, size_t __total_bytes = __size * __nobjs; size_t __bytes_left = _S_end_free - _S_start_free; - if (__bytes_left >= __total_bytes) { + if (__bytes_left >= __total_bytes) + { __result = _S_start_free; _S_start_free += __total_bytes; return(__result); - } else if (__bytes_left >= __size) { + } + else if (__bytes_left >= __size) + { __nobjs = (int)(__bytes_left/__size); __total_bytes = __size * __nobjs; __result = _S_start_free; _S_start_free += __total_bytes; return(__result); - } else { + } + else + { size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); // Try to make use of the left-over piece. - if (__bytes_left > 0) { - _Obj* __STL_VOLATILE* __my_free_list = - _S_free_list + _S_freelist_index(__bytes_left); - - ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; - *__my_free_list = (_Obj*)_S_start_free; - } - _S_start_free = (char*)malloc(__bytes_to_get); - if (0 == _S_start_free) { + if (__bytes_left > 0) + { + _Obj* __STL_VOLATILE* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); + + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; + } + _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get); + if (0 == _S_start_free) + { size_t __i; _Obj* __STL_VOLATILE* __my_free_list; _Obj* __p; - // Try to make do with what we have. That can't - // hurt. We do not try smaller requests, since that tends - // to result in disaster on multi-process machines. - for (__i = __size; - __i <= (size_t) _MAX_BYTES; - __i += (size_t) _ALIGN) { + // Try to make do with what we have. That can't hurt. We + // do not try smaller requests, since that tends to result + // in disaster on multi-process machines. + __i = __size; + for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) + { __my_free_list = _S_free_list + _S_freelist_index(__i); __p = *__my_free_list; - if (0 != __p) { - *__my_free_list = __p -> _M_free_list_link; - _S_start_free = (char*)__p; + if (0 != __p) + { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; _S_end_free = _S_start_free + __i; return(_S_chunk_alloc(__size, __nobjs)); // Any leftover piece will eventually make it to the // right free list. - } - } + } + } _S_end_free = 0; // In case of exception. - _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); + _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get); // This should either throw an // exception or remedy the situation. Thus we assume it // succeeded. - } + } _S_heap_size += __bytes_to_get; _S_end_free = _S_start_free + __bytes_to_get; return(_S_chunk_alloc(__size, __nobjs)); - } + } } diff --git a/libstdc++-v3/include/bits/stl_raw_storage_iter.h b/libstdc++-v3/include/bits/stl_raw_storage_iter.h index 22fec74bcb8..db810c2a787 100644 --- a/libstdc++-v3/include/bits/stl_raw_storage_iter.h +++ b/libstdc++-v3/include/bits/stl_raw_storage_iter.h @@ -33,39 +33,45 @@ namespace std { + template + class raw_storage_iterator + : public iterator + { + protected: + _ForwardIterator _M_iter; -template -class raw_storage_iterator { -protected: - _ForwardIterator _M_iter; -public: - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; + public: + explicit + raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} - explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} - raw_storage_iterator& operator*() { return *this; } - raw_storage_iterator& operator=(const _Tp& __element) { - construct(&*_M_iter, __element); - return *this; - } - raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { - ++_M_iter; - return *this; - } - raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { - raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; - ++_M_iter; - return __tmp; - } -}; + raw_storage_iterator& + operator*() { return *this; } + raw_storage_iterator& + operator=(const _Tp& __element) + { + construct(&*_M_iter, __element); + return *this; + } + raw_storage_iterator<_ForwardIterator, _Tp>& + operator++() + { + ++_M_iter; + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp> + operator++(int) + { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } + }; } // namespace std -#endif /* _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H */ +#endif // Local Variables: // mode:C++ diff --git a/libstdc++-v3/testsuite/20_util/allocator_members.cc b/libstdc++-v3/testsuite/20_util/allocator_members.cc new file mode 100644 index 00000000000..1ee1d97385e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/allocator_members.cc @@ -0,0 +1,60 @@ +// 2001-06-14 Benjamin Kosnik + +// Copyright (C) 2001 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. + +// 20.4.1.1 allocator members + +#include +#include +#include + +struct gnu { }; + +bool check_new = false; +bool check_delete = false; + +void* +operator new(std::size_t n) throw(std::bad_alloc) +{ + check_new = true; + return std::malloc(n); +} + +void operator delete(void *v) throw() +{ + check_delete = true; + return std::free(v); +} + +int main(void) +{ + bool test = true; + std::allocator obj; + + // XXX These should work for various size allocation and + // deallocations. Currently, they only work as expected for sizes > + // _MAX_BYTES as defined in stl_alloc.h, which happes to be 128. + gnu* pobj = obj.allocate(256); + VERIFY( check_new ); + + obj.deallocate(pobj, 256); + VERIFY( check_delete ); + + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/comparisons.cc b/libstdc++-v3/testsuite/20_util/comparisons.cc new file mode 100644 index 00000000000..fda0332fa07 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/comparisons.cc @@ -0,0 +1,53 @@ +// 2001-06-18 Benjamin Kosnik + +// Copyright (C) 2001 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. + +// 20.3.3 Comparisons + +#include + +class gnu_obj +{ + int i; +public: + gnu_obj(int arg = 0): i(arg) { } + bool operator==(const gnu_obj& rhs) const { return i == rhs.i; } + bool operator!=(const gnu_obj& rhs) const { return i != rhs.i; } + bool operator<(const gnu_obj& rhs) const { return i < rhs.i; } +}; + +template + struct gnu_t + { + bool b; + public: + gnu_t(bool arg = 0): b(arg) { } + bool operator==(const gnu_t& rhs) const { return b == rhs.b; } + bool operator!=(const gnu_t& rhs) const { return b != rhs.b; } + bool operator<(const gnu_t& rhs) const { return b == rhs.b; } + }; + +template struct std::not_equal_to; +template struct std::not_equal_to; +template struct std::not_equal_to >; + +int main() +{ + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/pairs.cc b/libstdc++-v3/testsuite/20_util/pairs.cc new file mode 100644 index 00000000000..7b4b62f96b9 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pairs.cc @@ -0,0 +1,140 @@ +// 2001-06-18 Benjamin Kosnik + +// Copyright (C) 2001 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. + +// 20.2.2 Pairs + +#include +#include + +class gnu_obj +{ + int i; +public: + gnu_obj(int arg = 0): i(arg) { } + bool operator==(const gnu_obj& rhs) const { return i == rhs.i; } + bool operator<(const gnu_obj& rhs) const { return i < rhs.i; } +}; + +template + struct gnu_t + { + bool b; + public: + gnu_t(bool arg = 0): b(arg) { } + bool operator==(const gnu_t& rhs) const { return b == rhs.b; } + bool operator<(const gnu_t& rhs) const { return int(b) < int(rhs.b); } + }; + + +// heterogeneous +void test01() +{ + bool test = true; + + std::pair p_bl_1(true, 433); + std::pair p_bl_2 = std::make_pair(true, 433); + VERIFY( p_bl_1 == p_bl_2 ); + VERIFY( !(p_bl_1 < p_bl_2) ); + + std::pair p_sf_1("total enlightenment", 433.00); + std::pair p_sf_2 = std::make_pair("total enlightenment", + 433.00); + VERIFY( p_sf_1 == p_sf_2 ); + VERIFY( !(p_sf_1 < p_sf_2) ); + + std::pair p_sg_1("enlightenment", gnu_obj(5)); + std::pair p_sg_2 = std::make_pair("enlightenment", + gnu_obj(5)); + VERIFY( p_sg_1 == p_sg_2 ); + VERIFY( !(p_sg_1 < p_sg_2) ); + + std::pair, gnu_obj> p_st_1(gnu_t(false), gnu_obj(5)); + std::pair, gnu_obj> p_st_2 = std::make_pair(gnu_t(false), + gnu_obj(5)); + VERIFY( p_st_1 == p_st_2 ); + VERIFY( !(p_st_1 < p_st_2) ); +} + +// homogeneous +void test02() +{ + bool test = true; + + std::pair p_bb_1(true, false); + std::pair p_bb_2 = std::make_pair(true, false); + VERIFY( p_bb_1 == p_bb_2 ); + VERIFY( !(p_bb_1 < p_bb_2) ); +} + + +// const +void test03() +{ + bool test = true; + + const std::pair p_bl_1(true, 433); + const std::pair p_bl_2 = std::make_pair(true, 433); + VERIFY( p_bl_1 == p_bl_2 ); + VERIFY( !(p_bl_1 < p_bl_2) ); + + const std::pair p_sf_1("total enlightenment", 433.00); + const std::pair p_sf_2 = + std::make_pair("total enlightenment", 433.00); + VERIFY( p_sf_1 == p_sf_2 ); + VERIFY( !(p_sf_1 < p_sf_2) ); + + const std::pair p_sg_1("enlightenment", gnu_obj(5)); + const std::pair p_sg_2 = + std::make_pair("enlightenment", gnu_obj(5)); + VERIFY( p_sg_1 == p_sg_2 ); + VERIFY( !(p_sg_1 < p_sg_2) ); + + const std::pair, gnu_obj> p_st_1(gnu_t(false), gnu_obj(5)); + const std::pair, gnu_obj> p_st_2 = + std::make_pair(gnu_t(false), gnu_obj(5)); + VERIFY( p_st_1 == p_st_2 ); + VERIFY( !(p_st_1 < p_st_2) ); +} + +// const& +void test04() +{ + bool test = true; + const gnu_obj& obj1 = gnu_obj(5); + const std::pair p_sg_1("enlightenment", obj1); + const std::pair p_sg_2 = + std::make_pair("enlightenment", obj1); + VERIFY( p_sg_1 == p_sg_2 ); + VERIFY( !(p_sg_1 < p_sg_2) ); + + const gnu_t& tmpl1 = gnu_t(false); + const std::pair, gnu_obj> p_st_1(tmpl1, obj1); + const std::pair, gnu_obj> p_st_2 = std::make_pair(tmpl1, obj1); + VERIFY( p_st_1 == p_st_2 ); + VERIFY( !(p_st_1 < p_st_2) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/20_util/raw_storage_iterator.cc b/libstdc++-v3/testsuite/20_util/raw_storage_iterator.cc new file mode 100644 index 00000000000..de1fe691e14 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/raw_storage_iterator.cc @@ -0,0 +1,47 @@ +// 2001-06-18 Benjamin Kosnik + +// Copyright (C) 2001 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. + +// 20.4.2 raw storage iterator + +#include + +void test01() +{ + using namespace std; + + // Check for required base class. + long l; + raw_storage_iterator rs_it(&l); + iterator* base = &rs_it; + + // Check for required typedefs + typedef raw_storage_iterator::value_type value_type; + typedef raw_storage_iterator::difference_type difference_type; + typedef raw_storage_iterator::pointer pointer; + typedef raw_storage_iterator::reference reference; + typedef raw_storage_iterator::iterator_category iteratory_category; + +} + +int main() +{ + test01(); + return 0; +}