diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 96d166fa225..e72219227f9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2010-04-24 Jonathan Wakely + + * include/bits/unique_ptr (unique_ptr::pointer): Use deleter's + pointer type if it exists. + * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: New. + * testsuite/20_util/unique_ptr/assign/assign_neg.cc: Adjust. + * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust. + 2010-04-22 Johannes Singler * include/parallel/partition.h (__parallel_partition): diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index afa3043c428..7b07ca477f4 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -83,10 +83,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type; typedef _Tp* unique_ptr::* __unspecified_pointer_type; + // use SFINAE to determine whether _Del::pointer exists + class _Pointer + { + template + static typename _Up::pointer __test(typename _Up::pointer*); + + template + static _Tp* __test(...); + + typedef typename remove_reference<_Tp_Deleter>::type _Del; + + public: + typedef decltype( __test<_Del>(0) ) type; + }; + public: - typedef _Tp* pointer; - typedef _Tp element_type; - typedef _Tp_Deleter deleter_type; + typedef typename _Pointer::type pointer; + typedef _Tp element_type; + typedef _Tp_Deleter deleter_type; // Constructors. unique_ptr() diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc index 4bf8e4b4349..525364b3412 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc @@ -49,13 +49,13 @@ test03() std::unique_ptr p2 = p1; } -// { dg-error "deleted function" "" { target *-*-* } 342 } +// { dg-error "deleted function" "" { target *-*-* } 357 } // { dg-error "used here" "" { target *-*-* } 42 } // { dg-error "no matching" "" { target *-*-* } 48 } -// { dg-warning "candidates are" "" { target *-*-* } 115 } -// { dg-warning "note" "" { target *-*-* } 108 } -// { dg-warning "note" "" { target *-*-* } 103 } -// { dg-warning "note" "" { target *-*-* } 98 } -// { dg-warning "note" "" { target *-*-* } 92 } -// { dg-error "deleted function" "" { target *-*-* } 207 } +// { dg-warning "candidates are" "" { target *-*-* } 130 } +// { dg-warning "note" "" { target *-*-* } 123 } +// { dg-warning "note" "" { target *-*-* } 118 } +// { dg-warning "note" "" { target *-*-* } 113 } +// { dg-warning "note" "" { target *-*-* } 107 } +// { dg-error "deleted function" "" { target *-*-* } 222 } // { dg-error "used here" "" { target *-*-* } 49 } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc index 3308fcbf81b..3b389b9da68 100644 --- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc @@ -36,4 +36,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 35 } -// { dg-error "deleted function" "" { target *-*-* } 332 } +// { dg-error "deleted function" "" { target *-*-* } 347 } diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc new file mode 100644 index 00000000000..5074844f42f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/requirements/pointer_type.cc @@ -0,0 +1,50 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2010 Free Software Foundation +// +// 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 +// . + +// 20.6.11 Template class unique_ptr [unique.ptr.single] + +#include +#include + +struct A +{ + void operator()(void* p) const { } +}; + +struct B +{ + typedef char* pointer; + void operator()(pointer p) const { } +}; + +int main() +{ + typedef std::unique_ptr up; + typedef std::unique_ptr upA; + typedef std::unique_ptr upB; + typedef std::unique_ptr upAr; + typedef std::unique_ptr upBr; + + static_assert( std::is_same< up::pointer, int*>::value, "" ); + static_assert( std::is_same< upA::pointer, int*>::value, "" ); + static_assert( std::is_same< upB::pointer, char*>::value, "" ); + static_assert( std::is_same< upAr::pointer, int*>::value, "" ); + static_assert( std::is_same< upBr::pointer, char*>::value, "" ); +}