diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-24 22:10:29 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-24 22:10:29 +0000 |
commit | 7da6f0f20ce2e6db82aa56a6c371e4f07dba2895 (patch) | |
tree | b845ecf5b8ab76dc1f846ef65bf26d476f028f0a /libstdc++-v3 | |
parent | 1d61c5cb58d9fdb2827850fc61568076cfa58d68 (diff) | |
download | gcc-7da6f0f20ce2e6db82aa56a6c371e4f07dba2895.tar.gz |
PR libstdc++/56170
* include/ext/debug_allocator.h (debug_allocator): Add missing members
to meet allocator requirements.
* testsuite/ext/debug_allocator/56170.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197023 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/debug_allocator.h | 105 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/ext/debug_allocator/56170.cc | 27 |
3 files changed, 119 insertions, 20 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2e1f141bac8..4c2c6d9c5f4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2013-03-24 Jonathan Wakely <jwakely.gcc@gmail.com> + + PR libstdc++/56170 + * include/ext/debug_allocator.h (debug_allocator): Add missing members + to meet allocator requirements. + * testsuite/ext/debug_allocator/56170.cc: New. + 2013-03-22 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/56678 diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h index 8190d2a89a7..9bb73f06161 100644 --- a/libstdc++-v3/include/ext/debug_allocator.h +++ b/libstdc++-v3/include/ext/debug_allocator.h @@ -43,6 +43,8 @@ #define _DEBUG_ALLOCATOR_H 1 #include <stdexcept> +#include <bits/functexcept.h> +#include <ext/alloc_traits.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { @@ -51,24 +53,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; /** - * @brief A meta-allocator with debugging bits, as per [20.4]. + * @brief A meta-allocator with debugging bits. * @ingroup allocators * - * This is precisely the allocator defined in the C++ Standard. - * - all allocation calls operator new - * - all deallocation calls operator delete + * This is precisely the allocator defined in the C++03 Standard. */ template<typename _Alloc> class debug_allocator { + template<typename> friend class debug_allocator; + + typedef __alloc_traits<_Alloc> _Traits; + public: - typedef typename _Alloc::size_type size_type; - typedef typename _Alloc::difference_type difference_type; - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::const_pointer const_pointer; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::const_reference const_reference; - typedef typename _Alloc::value_type value_type; + typedef typename _Traits::size_type size_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::pointer pointer; + typedef typename _Traits::const_pointer const_pointer; + typedef typename _Traits::reference reference; + typedef typename _Traits::const_reference const_reference; + typedef typename _Traits::value_type value_type; + + template<typename _Up> + class rebind + { + typedef typename _Traits::template rebind<_Up>::other __other; + + public: + typedef debug_allocator<__other> other; + }; private: // _M_extra is the number of objects that correspond to the @@ -77,13 +90,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Alloc _M_allocator; - public: - debug_allocator() + template<typename _Alloc2, + typename = typename _Alloc2::template rebind<value_type>::other> + struct __convertible + { }; + + template<typename _Alloc2> + struct __convertible<_Alloc2, _Alloc> + { + typedef void* __type; + }; + + size_type _S_extra() { const size_t __obj_size = sizeof(value_type); - _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; + return (sizeof(size_type) + __obj_size - 1) / __obj_size; } - + + public: + debug_allocator() : _M_extra(_S_extra()) { } + + template<typename _Alloc2> + debug_allocator(const debug_allocator<_Alloc2>& __a2, + typename __convertible<_Alloc2>::__type = 0) + : _M_allocator(__a2._M_allocator), _M_extra(_S_extra()) { } + + debug_allocator(const _Alloc& __a) + : _M_allocator(__a), _M_extra(_S_extra()) { } + pointer allocate(size_type __n) { @@ -105,21 +139,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void deallocate(pointer __p, size_type __n) { + using std::__throw_runtime_error; if (__p) { pointer __real_p = __p - _M_extra; if (*reinterpret_cast<size_type*>(__real_p) != __n) - { - throw std::runtime_error("debug_allocator::deallocate" - " wrong size"); - } + __throw_runtime_error("debug_allocator::deallocate wrong size"); _M_allocator.deallocate(__real_p, __n + _M_extra); } else - throw std::runtime_error("debug_allocator::deallocate null pointer"); + __throw_runtime_error("debug_allocator::deallocate null pointer"); } + + void + construct(pointer __p, const value_type& __val) + { _Traits::construct(_M_allocator, __p, __val); } + +#if __cplusplus >= 201103L + template<typename _Tp, typename... _Args> + void + construct(_Tp* __p, _Args&&... __args) + { + _Traits::construct(_M_allocator, __p, + std::forward<_Args>(__args)...); + } +#endif + + template<typename _Tp> + void + destroy(_Tp* __p) + { _Traits::destroy(_M_allocator, __p); } + + size_type + max_size() const throw() + { return _Traits::max_size(_M_allocator) - _M_extra; } + + friend bool + operator==(const debug_allocator& __lhs, const debug_allocator& __rhs) + { return __lhs._M_allocator == __rhs._M_allocator; } }; + template<typename _Alloc> + inline bool + operator!=(const debug_allocator<_Alloc>& __lhs, + const debug_allocator<_Alloc>& __rhs) + { return !(__lhs == __rhs); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/ext/debug_allocator/56170.cc b/libstdc++-v3/testsuite/ext/debug_allocator/56170.cc new file mode 100644 index 00000000000..217fc323baf --- /dev/null +++ b/libstdc++-v3/testsuite/ext/debug_allocator/56170.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2013 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do compile } + +#include <list> +#include <vector> +#include <ext/debug_allocator.h> + +using __gnu_cxx::debug_allocator; + +template class std::list<int, debug_allocator<std::allocator<int> > >; +template class std::vector<int, debug_allocator<std::allocator<int> > >; |