Index: include/ext/pointer_traits.h =================================================================== --- include/ext/pointer_traits.h (revision 0) +++ include/ext/pointer_traits.h (revision 0) @@ -0,0 +1,72 @@ +// -*- C++ -*- + +// Copyright (C) 2008, 2009 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 +// . + +#ifndef _POINTER_TRAITS_H +#define _POINTER_TRAITS_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * pointer_traits supports the derrivation of value_type + * and pointer-to-other-type for pointers. Custom pointer + * types are required to have a typedef value_type. + * The need for this arose from the combination of the N2913 (SCARY) + * proposal and desire to support non-standard pointers in containters. + * It addresses a need for a means to rebind<> a + * pointer type within a class that did not have access to the + * Allocator type, rather only to some Pointer type. + */ + template + struct __pointer_traits + { + typedef _Pointer pointer; + typedef typename pointer::value_type value_type; + + //template + // using rebind = typename pointer::template rebind<_U>; + + template + struct rebind { + typedef typename _Pointer::template rebind<_U>::other other; + }; + }; + + // Specialization for standard pointers + template + struct __pointer_traits<_T*> + { + typedef _T* pointer; + typedef _T value_type; + + //template using rebind = _U*; + + template + struct rebind { + typedef _U* other; + }; + }; + +_GLIBCXX_END_NAMESPACE + +#endif // _POINTER_TRAITS_H Index: include/ext/pointer.h =================================================================== --- include/ext/pointer.h (revision 154725) +++ include/ext/pointer.h (working copy) @@ -40,6 +40,7 @@ #include #include #include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) @@ -60,7 +61,13 @@ public: // the type this pointer points to. typedef _Tp element_type; - + + // template using rebind = _Std_pointer_impl<_U>; + template + struct rebind { + typedef _Std_pointer_impl<_U> other; + }; + // A method to fetch the pointer value as a standard T* value; inline _Tp* get() const @@ -103,6 +110,12 @@ public: typedef _Tp element_type; + // template using rebind = _Relative_pointer_impl<_U>; + template + struct rebind { + typedef _Relative_pointer_impl<_U> other; + }; + _Tp* get() const { @@ -154,6 +167,12 @@ { public: typedef const _Tp element_type; + + // template using rebind = _Relative_pointer_impl<_U>; + template + struct rebind { + typedef _Relative_pointer_impl<_U> other; + }; const _Tp* get() const @@ -290,6 +309,14 @@ typedef _Pointer_adapter pointer; typedef typename _Reference_type::reference reference; + //template using rebind = _Pointer_adapter< + // typename _Storage_policy::template rebind >; + template + struct rebind { + typedef _Pointer_adapter< typename _Storage_policy::template + rebind<_U>::other > other; + }; + // Reminder: 'const' methods mean that the method is valid when the // pointer is immutable, and has nothing to do with whether the // 'pointee' is const. Index: include/bits/forward_list.h =================================================================== --- include/bits/forward_list.h (revision 154725) +++ include/bits/forward_list.h (working copy) @@ -38,25 +38,31 @@ #include #include #include +#include _GLIBCXX_BEGIN_NAMESPACE(std) using __gnu_cxx::__static_pointer_cast; using __gnu_cxx::__const_pointer_cast; + using __gnu_cxx::__pointer_traits; /** * @brief A helper basic node class for %forward_list. * This is just a linked list with nothing inside it. * There are purely list shuffling utility methods here. + * + * This type is passed the implementation of void* as the + * template parameter (_Alloc::template rebind::other::pointer) + * so that only one instantiation of this type occurs per pointer + * implementation. */ - template + template struct _Fwd_list_node_base { - // The type allocated by _Alloc cannot be this type, so we rebind - typedef typename _Alloc::template rebind<_Fwd_list_node_base<_Alloc> > - ::other::pointer _Pointer; - typedef typename _Alloc::template rebind<_Fwd_list_node_base<_Alloc> > - ::other::const_pointer _Const_pointer; + typedef typename __pointer_traits<_Void_Pointer>::template rebind< + _Fwd_list_node_base<_Void_Pointer> >::other _Pointer; + typedef typename __pointer_traits<_Void_Pointer>::template rebind< + const _Fwd_list_node_base<_Void_Pointer> >::other _Const_pointer; _Pointer _M_next; @@ -81,15 +87,18 @@ * This is just a linked list with a data value in each node. * There is a sorting utility method. */ - template - struct _Fwd_list_node : public _Fwd_list_node_base<_Alloc> + template + struct _Fwd_list_node : public _Fwd_list_node_base< + typename __pointer_traits<_Tp_pointer>::template rebind::other > { - typedef typename _Alloc::template rebind<_Fwd_list_node<_Tp, _Alloc> > - ::other::pointer _Pointer; + typedef typename __pointer_traits<_Tp_pointer>::template rebind< + void>::other _Void_pointer; + typedef typename __pointer_traits<_Tp_pointer>::template rebind< + _Fwd_list_node<_Tp, _Tp_pointer> >::other _Pointer; template _Fwd_list_node(_Args&&... __args) - : _Fwd_list_node_base<_Alloc>(), + : _Fwd_list_node_base<_Void_pointer>(), _M_value(std::forward<_Args>(__args)...) { } _Tp _M_value; @@ -100,18 +109,18 @@ * * All the functions are op overloads. */ - template + template struct _Fwd_list_iterator { - typedef _Fwd_list_iterator<_Tp, _Alloc> _Self; - typedef _Fwd_list_node<_Tp, _Alloc> _Node; - typedef _Fwd_list_node_base<_Alloc> _Node_base; + typedef _Fwd_list_iterator<_Tp, _Pointer> _Self; + typedef _Fwd_list_node<_Tp, _Pointer> _Node; + typedef _Fwd_list_node_base _Node_base; - typedef _Tp value_type; - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::difference_type difference_type; - typedef std::forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Pointer pointer; + typedef _Tp& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; _Fwd_list_iterator() : _M_node() { } @@ -167,19 +176,21 @@ * * All the functions are op overloads. */ - template + template struct _Fwd_list_const_iterator { - typedef _Fwd_list_const_iterator<_Tp, _Alloc> _Self; - typedef const _Fwd_list_node<_Tp, _Alloc> _Node; - typedef const _Fwd_list_node_base<_Alloc> _Node_base; - typedef _Fwd_list_iterator<_Tp, _Alloc> iterator; + typedef _Fwd_list_const_iterator<_Tp, _Pointer> _Self; + typedef const _Fwd_list_node<_Tp, _Pointer> _Node; + typedef const _Fwd_list_node_base + _Node_base; + typedef _Fwd_list_iterator<_Tp, _Pointer> iterator; - typedef _Tp value_type; - typedef typename _Alloc::const_pointer pointer; - typedef typename _Alloc::const_reference reference; - typedef typename _Alloc::difference_type difference_type; - typedef std::forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef typename __pointer_traits<_Pointer>::template rebind< + const _Tp>::other pointer; + typedef const _Tp& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; _Fwd_list_const_iterator() : _M_node() { } @@ -236,19 +247,19 @@ /** * @brief Forward list iterator equality comparison. */ - template + template inline bool - operator==(const _Fwd_list_iterator<_Tp, _Alloc>& __x, - const _Fwd_list_const_iterator<_Tp, _Alloc>& __y) + operator==(const _Fwd_list_iterator<_Tp, _Pointer>& __x, + const _Fwd_list_const_iterator<_Tp, _Pointer>& __y) { return __x._M_node == __y._M_node; } /** * @brief Forward list iterator inequality comparison. */ - template + template inline bool - operator!=(const _Fwd_list_iterator<_Tp, _Alloc>& __x, - const _Fwd_list_const_iterator<_Tp, _Alloc>& __y) + operator!=(const _Fwd_list_iterator<_Tp, _Pointer>& __x, + const _Fwd_list_const_iterator<_Tp, _Pointer>& __y) { return __x._M_node != __y._M_node; } /** @@ -259,14 +270,18 @@ { protected: typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + typedef typename _Tp_alloc_type::pointer _Pointer; + typedef typename _Tp_alloc_type::const_pointer _Const_Pointer; + typedef typename _Alloc::template rebind::other::pointer + _Void_pointer; typedef typename _Alloc::template - rebind<_Fwd_list_node<_Tp, _Tp_alloc_type>>::other _Node_alloc_type; + rebind<_Fwd_list_node<_Tp, _Pointer>>::other _Node_alloc_type; struct _Fwd_list_impl : public _Node_alloc_type { - _Fwd_list_node_base<_Tp_alloc_type> _M_head; + _Fwd_list_node_base<_Void_pointer> _M_head; _Fwd_list_impl() : _Node_alloc_type(), _M_head() @@ -280,12 +295,11 @@ _Fwd_list_impl _M_impl; public: - typedef _Fwd_list_iterator<_Tp, _Tp_alloc_type> iterator; - typedef _Fwd_list_const_iterator<_Tp, _Tp_alloc_type> const_iterator; + typedef _Fwd_list_iterator<_Tp, _Pointer> iterator; + typedef _Fwd_list_const_iterator<_Tp, _Pointer> const_iterator; + typedef _Fwd_list_node<_Tp, _Pointer> _Node; + typedef _Fwd_list_node_base<_Void_pointer> _Node_base; - typedef _Fwd_list_node<_Tp, _Tp_alloc_type> _Node; - typedef _Fwd_list_node_base<_Tp_alloc_type> _Node_base; - _Node_alloc_type& _M_get_Node_allocator() { return *static_cast<_Node_alloc_type*>(&this->_M_impl); } Index: include/bits/forward_list.tcc =================================================================== --- include/bits/forward_list.tcc (revision 154725) +++ include/bits/forward_list.tcc (working copy) @@ -31,9 +31,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) - template + template void - _Fwd_list_node_base<_Alloc>:: + _Fwd_list_node_base<_List_Pointer>:: _M_transfer_after(_Pointer __bbegin) { _Pointer __bend = __bbegin; @@ -42,9 +42,9 @@ _M_transfer_after(__bbegin, __bend); } - template + template void - _Fwd_list_node_base<_Alloc>:: + _Fwd_list_node_base<_List_Pointer>:: _M_transfer_after(_Pointer __bbegin, _Pointer __bend) { _Pointer __keep = __bbegin->_M_next; @@ -58,9 +58,9 @@ _M_next = __keep; } - template + template void - _Fwd_list_node_base<_Alloc>:: + _Fwd_list_node_base<_List_Pointer>:: _M_reverse_after() { _Pointer __tail = _M_next; Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 154725) +++ include/Makefile.am (working copy) @@ -509,6 +509,7 @@ ${ext_srcdir}/numeric_traits.h \ ${ext_srcdir}/pod_char_traits.h \ ${ext_srcdir}/pointer.h \ + ${ext_srcdir}/pointer_traits.h \ ${ext_srcdir}/pool_allocator.h \ ${ext_srcdir}/rb_tree \ ${ext_srcdir}/rope \ Index: testsuite/ext/ext_pointer/1_neg.cc =================================================================== --- testsuite/ext/ext_pointer/1_neg.cc (revision 154725) +++ testsuite/ext/ext_pointer/1_neg.cc (working copy) @@ -91,13 +91,13 @@ aptr5 = __const_pointer_cast(cbptr); // ok } -// { dg-error "invalid conversion " "" { target *-*-* } 314 } -// { dg-error "initializing argument 1 of" "" { target *-*-* } 314 } -// { dg-error "invalid conversion " "" { target *-*-* } 308 } -// { dg-error "initializing argument 1 of" "" { target *-*-* } 308 } -// { dg-error "invalid conversion " "" { target *-*-* } 331 } -// { dg-error "initializing argument 1 of" "" { target *-*-* } 331 } -// { dg-error "invalid conversion " "" { target *-*-* } 339 } -// { dg-error "initializing argument 1 of" "" { target *-*-* } 339 } +// { dg-error "invalid conversion " "" { target *-*-* } 335 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 335 } +// { dg-error "invalid conversion " "" { target *-*-* } 341 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 341 } +// { dg-error "invalid conversion " "" { target *-*-* } 358 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 358 } +// { dg-error "invalid conversion " "" { target *-*-* } 366 } +// { dg-error "initializing argument 1 of" "" { target *-*-* } 366 } // { dg-excess-errors "In constructor" } Index: testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc =================================================================== --- testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc (revision 154725) +++ testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1197 } +// { dg-error "no matching" "" { target *-*-* } 1211 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation Index: testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc =================================================================== --- testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc (revision 154725) +++ testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1197 } +// { dg-error "no matching" "" { target *-*-* } 1211 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation Index: testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc =================================================================== --- testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc (revision 154725) +++ testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1197 } +// { dg-error "no matching" "" { target *-*-* } 1211 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation Index: testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc =================================================================== --- testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc (revision 154725) +++ testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1197 } +// { dg-error "no matching" "" { target *-*-* } 1211 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation