Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 174358) +++ include/Makefile.am (working copy) @@ -119,6 +119,7 @@ ${bits_srcdir}/ostream.tcc \ ${bits_srcdir}/ostream_insert.h \ ${bits_srcdir}/postypes.h \ + ${bits_srcdir}/ptr_traits.h \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ ${bits_srcdir}/range_access.h \ Index: include/bits/ptr_traits.h =================================================================== --- include/bits/ptr_traits.h (revision 0) +++ include/bits/ptr_traits.h (revision 0) @@ -0,0 +1,222 @@ +// Pointer Traits -*- C++ -*- + +// Copyright (C) 2011 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file bits/ptr_traits.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#ifndef _PTR_TRAITS_H +#define _PTR_TRAITS_H 1 + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + +#include // For _GLIBCXX_HAS_NESTED_TYPE + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +_GLIBCXX_HAS_NESTED_TYPE(element_type) +_GLIBCXX_HAS_NESTED_TYPE(difference_type) + + template::value> + struct __ptrtr_elt_type; + + template + struct __ptrtr_elt_type<_Tp, true> + { + typedef typename _Tp::element_type __type; + }; + + template class _SomePtr, typename _Tp, + typename... _Args> + struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false> + { + typedef _Tp __type; + }; + + template::value> + struct __ptrtr_diff_type + { + typedef typename _Tp::difference_type __type; + }; + + template + struct __ptrtr_diff_type<_Tp, false> + { + typedef ptrdiff_t __type; + }; + + template + class __ptrtr_rebind_helper + { + template + static constexpr bool + _S_chk(typename _Ptr2::template rebind<_Up2>*) + { return true; } + + template + static constexpr bool + _S_chk(...) + { return false; } + + public: + static const bool __value = _S_chk<_Ptr, _Up>(nullptr); + }; + + // hack to use _Tp::__rebind<_Up>::__type instead if that exists + template + class __ptrtr_rebind_helper2 + { + template + static constexpr bool + _S_chk(typename _Ptr2::template __rebind<_Up2>::__type*) + { return true; } + + template + static constexpr bool + _S_chk(...) + { return false; } + + public: + static const bool __value = _S_chk<_Ptr, _Up>(nullptr); + }; + + /* TODO: remove second bool when alias templates are supported */ + template::value, + bool = __ptrtr_rebind_helper2<_Tp, _Up>::value> + struct __ptrtr_rebind; + + template + struct __ptrtr_rebind<_Tp, _Up, true, _B2> + { + typedef typename _Tp::template rebind<_Up> __type; + }; + + /* TODO: remove this when alias templates are supported */ + template + struct __ptrtr_rebind<_Tp, _Up, false, true> + { + typedef typename _Tp::template __rebind<_Up>::__type __type; + }; + + template class _SomePtr, typename _Up, + typename _Tp, typename... _Args> + struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false, false> + { + typedef _SomePtr<_Up, _Args...> __type; + }; + + template::type> + struct __ptrtr_not_void + { + typedef _Tp __type; + }; + + template + struct __ptrtr_not_void<_Tp, void> + { + struct __type { }; + }; + + template + class __ptrtr_pointer_to + { + typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type; + typedef typename __ptrtr_not_void<__orig_type>::__type __element_type; + + public: + static _Ptr pointer_to(__element_type& __e) + { return _Ptr::pointer_to(__e); } + }; + + /** + * @brief Uniform interface to all pointer-like types + * @ingroup pointer_abstractions + */ + template + struct pointer_traits : __ptrtr_pointer_to<_Ptr> + { + /// The pointer type + typedef _Ptr pointer; + /// The type pointed to + typedef typename __ptrtr_elt_type<_Ptr>::__type element_type; + /// Type used to represent the difference between two pointers + typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type; + + private: + /* TODO: replace __rebind with alias template rebind */ + /* + template + using rebind<_Up> = typename __ptrtr_rebind<_Ptr, _Up>::__type; + */ + template + struct __rebind + { typedef typename __ptrtr_rebind<_Ptr, _Up>::__type __type; }; + + // allocator_traits needs to use __rebind + template struct allocator_traits; + template class __ptrtr_rebind_helper2; + }; + + /** + * @brief Partial specialization for built-in pointers. + * @ingroup pointer_abstractions + */ + template + struct pointer_traits<_Tp*> + { + /// The pointer type + typedef _Tp* pointer; + /// The type pointed to + typedef _Tp element_type; + /// Type used to represent the difference between two pointers + typedef ptrdiff_t difference_type; + + /* TODO: replace __rebind with alias template rebind */ + /* + template + using rebind<_Up> = U*; + */ + template + struct __rebind { typedef U* __type; }; + + /** + * @brief Obtain a pointer to an object + * @param r A reference to an object of type @c element_type + * @return @c addressof(r) + */ + static pointer + pointer_to(typename __ptrtr_not_void::__type& __r) + { return std::addressof(__r); } + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif + +#endif Index: include/bits/allocator.h =================================================================== --- include/bits/allocator.h (revision 174358) +++ include/bits/allocator.h (working copy) @@ -48,7 +48,9 @@ #include #ifdef __GXX_EXPERIMENTAL_CXX0X__ +#include #include // For _GLIBCXX_HAS_NESTED_TYPE +#include #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -85,8 +87,8 @@ * @brief The @a standard allocator, as per [20.4]. * @ingroup allocators * - * Further details: - * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html + * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html + * for further details. */ template class allocator: public __glibcxx_base_allocator<_Tp> @@ -185,7 +187,7 @@ // A very basic implementation for now. In general we have to wait for // the availability of the infrastructure described in N2983: we should // try when either T has a move constructor which cannot throw or T is - // CopyContructible. + // CopyConstructible. // NB: This code doesn't properly belong here, we should find a more // suited place common to std::vector and std::deque. template::value> { }; + template + class __alloctr_rebind_helper + { + template + static constexpr bool + _S_chk(typename _Alloc2::template rebind<_Tp2>::other*) + { return true; } + + template + static constexpr bool + _S_chk(...) + { return false; } + + public: + static const bool __value = _S_chk<_Alloc, _Tp>(nullptr); + }; + + template::__value> + struct __alloctr_rebind; + + template + struct __alloctr_rebind<_Alloc, _Tp, true> + { + typedef typename _Alloc::template rebind<_Tp>::other __type; + }; + + template class _Alloc, typename _Tp, + typename _Up, typename... _Args> + struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false> + { + typedef _Alloc<_Tp, _Args...> __type; + }; + + /** + * @brief Uniform interface to all allocator types. + * @ingroup allocators + */ + template + struct allocator_traits + { + /// The allocator type + typedef _Alloc allocator_type; + /// The allocated type + typedef typename _Alloc::value_type value_type; + +#define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \ + private: \ + template \ + static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \ + static _ALT _S_##_NTYPE##_helper(...); \ + typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \ + public: + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*) + + /** + * @brief The allocator's pointer type. + * + * @c Alloc::pointer if that type exists, otherwise @c value_type* + */ + typedef __pointer pointer; + +// TODO: Use pointer_traits::rebind alias template. + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer, + typename pointer_traits::template __rebind::__type) + + /** + * @brief The allocator's const pointer type. + * + * @c Alloc::const_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __const_pointer const_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer, + typename pointer_traits::template __rebind::__type) + + /** + * @brief The allocator's void pointer type. + * + * @c Alloc::void_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __void_pointer void_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer, + typename pointer_traits::template __rebind::__type) + + /** + * @brief The allocator's const void pointer type. + * + * @c Alloc::const_void_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __const_void_pointer const_void_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type, + typename pointer_traits::difference_type) + + /** + * @brief The allocator's difference type + * + * @c Alloc::difference_type if that type exists, otherwise + * pointer_traits::difference_type + */ + typedef __difference_type difference_type; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type, + typename make_unsigned::type) + + /** + * @brief The allocator's size type + * + * @c Alloc::size_type if that type exists, otherwise + * make_unsigned::type + */ + typedef __size_type size_type; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment, + false_type) + + /** + * @brief How the allocator is propagated on copy assignment + * + * @c Alloc::propagate_on_container_copy_assignment if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_copy_assignment + propagate_on_container_copy_assignment; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment, + false_type) + + /** + * @brief How the allocator is propagated on move assignment + * + * @c Alloc::propagate_on_container_move_assignment if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_move_assignment + propagate_on_container_move_assignment; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, + false_type) + + /** + * @brief How the allocator is propagated on swap + * + * @c Alloc::propagate_on_container_swap if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_swap propagate_on_container_swap; + +#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE + + /* TODO: use template alias + template + using rebind_alloc = __alloctr_rebind<_Alloc, _Tp>::__type; + template + using rebind_traits = allocator_traits>; + */ + template + struct __rebind_alloc + { + typedef typename __alloctr_rebind<_Alloc, _Tp>::__type __type; + }; + + template + struct __rebind_traits + { + typedef allocator_traits::__type> __type; + }; + + private: + template + struct __allocate_helper + { + template()->allocate( + std::declval(), + std::declval()))> + static true_type __test(int); + + template + static false_type __test(...); + + typedef decltype(__test<_Alloc>(0)) type; + static const bool value = type::value; + }; + + template + static typename + enable_if<__allocate_helper<_Alloc2>::value, pointer>::type + _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint) + { return __a.allocate(__n, __hint); } + + template + static typename + enable_if::value, pointer>::type + _S_allocate(_Alloc2& __a, size_type __n, ...) + { return __a.allocate(__n); } + + template + struct __construct_helper + { + template()->construct( + std::declval<_Tp*>(), std::declval<_Args>()...))> + static true_type __test(int); + + template + static false_type __test(...); + + typedef decltype(__test<_Alloc>(0)) type; + static const bool value = type::value; + }; + + template + static typename + enable_if<__construct_helper<_Tp, _Args...>::value, void>::type + _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + { __a.construct(__p, std::forward<_Args>(__args)...); } + + template + static typename + enable_if::value, void>::type + _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) + { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } + + template + struct __destroy_helper + { + template()->destroy( + std::declval<_Tp*>()))> + static true_type __test(int); + + template + static false_type __test(...); + + typedef decltype(__test<_Alloc>(0)) type; + static const bool value = type::value; + }; + + template + static typename enable_if<__destroy_helper<_Tp>::value, void>::type + _S_destroy(_Alloc& __a, _Tp* __p) + { __a.destroy(__p); } + + template + static typename enable_if::value, void>::type + _S_destroy(_Alloc&, _Tp* __p) + { __p->~_Tp(); } + + template + struct __maxsize_helper + { + template()->max_size())> + static true_type __test(int); + + template + static false_type __test(...); + + typedef decltype(__test<_Alloc2>(0)) type; + static const bool value = type::value; + }; + + template + static typename + enable_if<__maxsize_helper<_Alloc2>::value, size_type>::type + _S_max_size(_Alloc2& __a) + { return __a.max_size(); } + + template + static typename + enable_if::value, size_type>::type + _S_max_size(_Alloc2&) + { return numeric_limits::max(); } + + template + struct __select_helper + { + template() + ->select_on_container_copy_construction())> + static true_type __test(int); + + template + static false_type __test(...); + + typedef decltype(__test<_Alloc2>(0)) type; + static const bool value = type::value; + }; + template + static typename + enable_if<__select_helper<_Alloc2>::value, _Alloc2>::type + _S_select(_Alloc2& __a) + { return __a.select_on_container_copy_construction(); } + + template + static typename + enable_if::value, _Alloc2>::type + _S_select(_Alloc2& __a) + { return __a; } + + public: + + /** + * @brief Allocate memory. + * @param a An allocator. + * @param n The number of objects to allocate space for. + * + * Calls @c a.allocate(n) + */ + static pointer + allocate(_Alloc& __a, size_type __n) + { return __a.allocate(__n); } + + /** + * @brief Allocate memory. + * @param a An allocator. + * @param n The number of objects to allocate space for. + * @param hint Aid to locality. + * @return Memory of suitable size and alignment for @a n objects + * of type @c value_type + * + * Returns a.allocate(n, hint) if that expression is + * well-formed, otherwise returns @c a.allocate(n) + */ + static pointer + allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) + { return _S_allocate(__a, __n, __hint); } + + /** + * @brief Deallocate memory. + * @param a An allocator. + * @param p Pointer to the memory to deallocate. + * @param n The number of objects space was allocated for. + * + * Calls a.deallocate(p, n) + */ + static void deallocate(_Alloc& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + /** + * @brief Construct an object of type @a Tp + * @param a An allocator. + * @param p Pointer to memory of suitable size and alignment for Tp + * @param args Constructor arguments. + * + * Calls a.construct(p, std::forward(args)...) + * if that expression is well-formed, otherwise uses placement-new + * to construct an object of type @a Tp at location @a p from the + * arguments @a args... + */ + template + static void construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + { _S_construct(__a, __p, std::forward<_Args>(__args)...); } + + /** + * @brief Destroy an object of type @a Tp + * @param a An allocator. + * @param p Pointer to the object to destroy + * + * Calls @c a.destroy(p) if that expression is well-formed, + * otherwise calls @c p->~Tp() + */ + template + static void destroy(_Alloc& __a, _Tp* __p) + { _S_destroy(__a, __p); } + + /** + * @brief The maximum supported allocation size + * @param a An allocator. + * @return @c a.max_size() or @c %numeric_limits::max() + * + * Returns @c a.max_size() if that expression is well-formed, + * otherwise returns @c %numeric_limits::max() + */ + static size_type max_size(const _Alloc& __a) + { return _S_max_size(__a); } + + /** + * @brief Obtain an allocator to use when copying a container. + * @param rhs An allocator. + * @return @c rhs.select_on_container_copy_construction() or @a rhs + * + * Returns @c rhs.select_on_container_copy_construction() if that + * expression is well-formed, otherwise returns @a rhs + */ + static _Alloc + select_on_container_copy_construction(const _Alloc& __rhs) + { return _S_select(__rhs); } + }; + #endif _GLIBCXX_END_NAMESPACE_VERSION Index: include/ext/array_allocator.h =================================================================== --- include/ext/array_allocator.h (revision 174358) +++ include/ext/array_allocator.h (working copy) @@ -72,21 +72,25 @@ max_size() const throw() { return size_t(-1) / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) value_type(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif }; /** Index: include/ext/bitmap_allocator.h =================================================================== --- include/ext/bitmap_allocator.h (revision 174358) +++ include/ext/bitmap_allocator.h (working copy) @@ -1053,20 +1053,25 @@ max_size() const throw() { return size_type(-1) / sizeof(value_type); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) + { __p->~_Up(); } +#else void construct(pointer __p, const_reference __data) { ::new((void *)__p) value_type(__data); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~value_type(); } +#endif }; template Index: include/ext/extptr_allocator.h =================================================================== --- include/ext/extptr_allocator.h (revision 174358) +++ include/ext/extptr_allocator.h (working copy) @@ -100,18 +100,23 @@ size_type max_size() const throw() { return std::numeric_limits::max() / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) + { __p->~_Up(); } +#else void construct(pointer __p, const _Tp& __val) { ::new(__p.get()) _Tp(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new(__p.get()) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif template inline bool Index: include/ext/malloc_allocator.h =================================================================== --- include/ext/malloc_allocator.h (revision 174358) +++ include/ext/malloc_allocator.h (working copy) @@ -104,21 +104,25 @@ max_size() const throw() { return size_t(-1) / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) value_type(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif }; template Index: include/ext/mt_allocator.h =================================================================== --- include/ext/mt_allocator.h (revision 174358) +++ include/ext/mt_allocator.h (working copy) @@ -588,21 +588,25 @@ max_size() const throw() { return size_t(-1) / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif }; #ifdef __GTHREADS Index: include/ext/new_allocator.h =================================================================== --- include/ext/new_allocator.h (revision 174358) +++ include/ext/new_allocator.h (working copy) @@ -101,21 +101,25 @@ max_size() const throw() { return size_t(-1) / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif }; template Index: include/ext/pool_allocator.h =================================================================== --- include/ext/pool_allocator.h (revision 174358) +++ include/ext/pool_allocator.h (working copy) @@ -158,21 +158,25 @@ max_size() const throw() { return size_t(-1) / sizeof(_Tp); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { __p->~_Tp(); } +#endif pointer allocate(size_type __n, const void* = 0); Index: include/ext/throw_allocator.h =================================================================== --- include/ext/throw_allocator.h (revision 174358) +++ include/ext/throw_allocator.h (working copy) @@ -639,20 +639,25 @@ return a; } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + void + construct(_Up* __p, _Args&&... __args) + { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) + { _M_allocator.destroy(__p); } +#else void construct(pointer __p, const value_type& val) { return _M_allocator.construct(__p, val); } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - template - void - construct(pointer __p, _Args&&... __args) - { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); } -#endif - void destroy(pointer __p) { _M_allocator.destroy(__p); } +#endif void deallocate(pointer __p, size_type __n) Index: testsuite/20_util/allocator_traits/requirements/typedefs.cc =================================================================== --- testsuite/20_util/allocator_traits/requirements/typedefs.cc (revision 0) +++ testsuite/20_util/allocator_traits/requirements/typedefs.cc (revision 0) @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++0x" } +// +// Copyright (C) 2011 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 +// . + +// +// NB: This file is for testing memory with NO OTHER INCLUDES. + +#include + +// { dg-do compile } + +template +void test01() +{ + // Check for required typedefs + typedef std::allocator_traits test_type; + typedef typename test_type::pointer pointer; + typedef typename test_type::const_pointer const_pointer; + typedef typename test_type::void_pointer void_pointer; + typedef typename test_type::const_void_pointer const_void_pointer; + typedef typename test_type::difference_type difference_type; + typedef typename test_type::size_type size_type; + typedef typename test_type::propagate_on_container_copy_assignment + propagate_on_container_copy_assignment; + typedef typename test_type::propagate_on_container_move_assignment + propagate_on_container_move_assignment; + typedef typename test_type::propagate_on_container_swap + propagate_on_container_swap; +} + +struct S { }; + +int main() +{ + test01>(); + test01>(); +} Index: testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc =================================================================== --- testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc (revision 0) +++ testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc (revision 0) @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 +// . + +// NB: This file is for testing memory with NO OTHER INCLUDES. + +#include + +namespace std +{ + typedef short test_type; + template struct allocator_traits>; +} Index: testsuite/20_util/allocator_traits/members/max_size.cc =================================================================== --- testsuite/20_util/allocator_traits/members/max_size.cc (revision 0) +++ testsuite/20_util/allocator_traits/members/max_size.cc (revision 0) @@ -0,0 +1,67 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 +// . + +#include +#include +#include +#include + +struct X { }; + +template +struct maxsize_allocator +{ + typedef T value_type; + typedef unsigned size_type; + + size_type max_size() const { return 100; } +}; + +template +struct unsized_allocator +{ + typedef T value_type; +}; + + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + auto size = a.max_size(); + VERIFY( traits_type::max_size(a) == size ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + auto size = std::numeric_limits::max(); + VERIFY( traits_type::max_size(a) == size ); +} + +int main() +{ + test01(); + test02(); +} Index: testsuite/20_util/allocator_traits/members/select.cc =================================================================== --- testsuite/20_util/allocator_traits/members/select.cc (revision 0) +++ testsuite/20_util/allocator_traits/members/select.cc (revision 0) @@ -0,0 +1,68 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 +// . + +#include +#include + +struct X { }; + +template +struct alloc1 +{ + typedef T value_type; + + int id; +}; + +template +struct alloc2 +{ + typedef T value_type; + + int id; + + alloc2 select_on_container_copy_construction() const + { return alloc2{id+1}; } +}; + + +void test01() +{ + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a{1}; + const traits_type::allocator_type& a2 + = traits_type::select_on_container_copy_construction(a); + VERIFY( a2.id == a.id ); +} + +void test02() +{ + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a{1}; + const traits_type::allocator_type& a2 + = traits_type::select_on_container_copy_construction(a); + VERIFY( a2.id != a.id ); +} + +int main() +{ + test01(); + test02(); +} Index: testsuite/20_util/allocator_traits/members/construct.cc =================================================================== --- testsuite/20_util/allocator_traits/members/construct.cc (revision 0) +++ testsuite/20_util/allocator_traits/members/construct.cc (revision 0) @@ -0,0 +1,79 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 +// . + +#include +#include +#include + +struct X +{ + static int counter; + X() { } + X(const X&) { ++counter; } + explicit X(int) { ++counter; } + X(int, int) { ++counter; } + X(int, int, int) { ++counter; } +}; + +int X::counter = 0; + +template +struct fake_allocator +{ + typedef T value_type; + + fake_allocator() : counter() {} + + int counter; + + T* allocate(std::size_t n) { return (T*)new char[n*sizeof(T)]; } + void deallocate(T* p, std::size_t) { delete[] (char*)p; } + + // don't actually construct anything when these are called + void construct(T* p) { ++counter; } + void construct(T* p, int, int) { ++counter; } +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + X* p = traits_type::allocate(a, 1); + traits_type::construct(a, p); + VERIFY( a.counter == 1 ); + traits_type::construct(a, p, 1); + VERIFY( a.counter == 1 ); + VERIFY( X::counter == 1 ); + traits_type::destroy(a, p); + traits_type::construct(a, p, 1, 1); + VERIFY( a.counter == 2 ); + VERIFY( X::counter == 1 ); + traits_type::construct(a, p, 1, 1, 1); + VERIFY( a.counter == 2 ); + VERIFY( X::counter == 2 ); + traits_type::destroy(a, p); + traits_type::deallocate(a, p, 1); +} + +int main() +{ + test01(); +} Index: testsuite/20_util/allocator_traits/members/allocate_hint.cc =================================================================== --- testsuite/20_util/allocator_traits/members/allocate_hint.cc (revision 0) +++ testsuite/20_util/allocator_traits/members/allocate_hint.cc (revision 0) @@ -0,0 +1,90 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 +// . + +#include +#include +#include + +struct X { }; + +template +struct hintable_allocator +{ + typedef T value_type; + struct const_void_pointer { }; + typedef unsigned size_type; + + hintable_allocator() : called(false) { } + + bool called; + + // this is the overload that should get called: + T* allocate(size_type n, const_void_pointer) { called = true; return 0; } + + // none of these should get called: + T* allocate(size_type n); + T* allocate(size_type n, void*); + T* allocate(size_type n, const void*); + T* allocate(size_type n, const_void_pointer) const; +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + traits_type::const_void_pointer v; + X* p = traits_type::allocate(a, 1, v); + VERIFY( a.called ); +} + +template +struct unhintable_allocator +{ + typedef T value_type; + typedef unsigned size_type; + + unhintable_allocator() : called(false) { } + + bool called; + + // this is the overload that should get called: + T* allocate(size_type n) { called = true; return 0; } + + // this should not get called: + T* allocate(size_type n, void*); +}; + +void test02() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + traits_type::const_void_pointer v; + X* p = traits_type::allocate(a, 1, v); + VERIFY( a.called ); +} + +int main() +{ + test01(); + test02(); +} Index: testsuite/20_util/allocator_traits/members/destroy.cc =================================================================== --- testsuite/20_util/allocator_traits/members/destroy.cc (revision 0) +++ testsuite/20_util/allocator_traits/members/destroy.cc (revision 0) @@ -0,0 +1,84 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 +// . + +#include +#include +#include + +struct X +{ + static int counter; + ~X() { ++counter; } +}; + +int X::counter = 0; + +template +struct allocator_with_destroy +{ + typedef T value_type; + + allocator_with_destroy() : called() { } + + void destroy(T* p) { called = true; } + + int called; +}; + +template +struct allocator_without_destroy +{ + typedef T value_type; + + allocator_without_destroy() : called() { } + + int called; +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + X* p = 0; + traits_type::destroy(a, p); + VERIFY( a.called ); + VERIFY( X::counter == 0 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + typedef std::allocator_traits> traits_type; + traits_type::allocator_type a; + char buf[sizeof(X)]; + X* p = ::new (static_cast(buf)) X(); + traits_type::destroy(a, p); + VERIFY( !a.called ); + VERIFY( X::counter == 1 ); +} + +int main() +{ + test01(); + test02(); +} Index: testsuite/20_util/pointer_traits/requirements/typedefs.cc =================================================================== --- testsuite/20_util/pointer_traits/requirements/typedefs.cc (revision 0) +++ testsuite/20_util/pointer_traits/requirements/typedefs.cc (revision 0) @@ -0,0 +1,45 @@ +// { dg-options "-std=gnu++0x" } +// +// Copyright (C) 2011 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 +// . + +// +// NB: This file is for testing memory with NO OTHER INCLUDES. + +#include + +// { dg-do compile } + +template +void test01() +{ + // Check for required typedefs + typedef std::pointer_traits test_type; + typedef typename test_type::pointer pointer; + typedef typename test_type::element_type element_type; + typedef typename test_type::difference_type difference_type; +} + +int main() +{ + test01(); + test01(); + test01>(); + test01>(); + test01>(); + test01>(); +} Index: testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc =================================================================== --- testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc (revision 0) +++ testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc (revision 0) @@ -0,0 +1,31 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 +// . + +// NB: This file is for testing memory with NO OTHER INCLUDES. + +#include + +namespace std +{ + typedef short test_type; + template struct pointer_traits; + template struct pointer_traits>; + template struct pointer_traits>; +}