From 47d877425d6ebb9ba61f062ac32c32cd05b3ddf9 Mon Sep 17 00:00:00 2001 From: Piotr Rak Date: Mon, 19 Jul 2010 03:12:12 +0200 Subject: [PATCH] Add std::pointer_traits. --- libstdc++-v3/ChangeLog | 14 ++ libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/ptr_traits.h | 208 ++++++++++++++++++++ libstdc++-v3/include/std/memory | 1 + .../requirements/explicit_instantiation.cc | 42 ++++ .../20_util/pointer_traits/requirements/members.cc | 49 +++++ .../pointer_traits/requirements/typedefs.cc | 147 ++++++++++++++ 8 files changed, 463 insertions(+), 0 deletions(-) create mode 100644 libstdc++-v3/include/bits/ptr_traits.h create mode 100644 libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc create mode 100644 libstdc++-v3/testsuite/20_util/pointer_traits/requirements/members.cc create mode 100644 libstdc++-v3/testsuite/20_util/pointer_traits/requirements/typedefs.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2d41140..cec9d6e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2010-07-20 Piotr Rak + + * include/bits/ptr_traits.h: New. + (_DEFINE_HAS_MEMTY, _DEFINE_HAS_MEMTY_AUX, __has_element_type, + __ptr_element_type, __has_difference_type, __ptr_difference_type, + __has_rebind, __ptr_rebind, pointer_traits): Define. + * include/std/memory: Add in C++0x mode. + * include/Makefile.am: Add. + * include/Makefile.in: Regenerate. + * testsuite/20_util/pointer_traits/requirements/ + explicit-instantionation.cc: New. + * testsuite/20_util/pointer_traits/requirements/members.cc: New. + * testsuite/20_util/pointer_traits/requirements/typedefs.cc: New. + 2010-07-14 Jonathan Wakely * doc/xml/manual/shared_ptr.xml: Update. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 6c0230a..96e28fb 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -119,6 +119,7 @@ bits_headers = \ ${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}/regex.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 430f85a..a800c10 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -361,6 +361,7 @@ bits_headers = \ ${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}/regex.h \ diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h new file mode 100644 index 0000000..4a171cf --- /dev/null +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -0,0 +1,208 @@ +// pointer_traits implementation -*- C++ -*- + +// Copyright (C) 2010 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 ptr_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _PTR_TRAITS_H +#define _PTR_TRAITS_H 1 + +#include +#include +#include + +_GLIBCXX_BEGIN_NAMESPACE(std) + +#define _DEFINE_HAS_MEMTY_AUX(_Name, _MemType) \ + template \ + struct __has_ ## _Name \ + : std::__sfinae_types \ + { \ + template \ + static __one __test(typename _Tp1::_MemType*); \ + \ + template \ + static __two __test(...); \ + \ + static const bool __value = sizeof(__test<_Tp>(nullptr)) == 1; \ + }; + +#define _DEFINE_HAS_MEMTY(_MemType) \ + _DEFINE_HAS_MEMTY_AUX(_MemType, _MemType) + + // __has_element_type + _DEFINE_HAS_MEMTY(element_type) + + template::__value> + struct __ptr_element_type; + + template + struct __ptr_element_type<_Tp, true> + { typedef typename _Tp::element_type __type; }; + + template class _Ptr, + typename _Tp, + typename..._Args> + struct __ptr_element_type<_Ptr<_Tp, _Args...>, true> + { typedef typename _Ptr<_Tp, _Args...>::element_type __type; }; + + template class _Ptr, + typename _Tp, + typename... _Args> + struct __ptr_element_type<_Ptr<_Tp, _Args...>, false> + { typedef _Tp __type; }; + + // __has_difference_type + _DEFINE_HAS_MEMTY(difference_type) + + template::__value> + struct __ptr_difference_type + { typedef typename _Tp::difference_type __type; }; + + template + struct __ptr_difference_type<_Tp, false> + { typedef std::ptrdiff_t __type; }; + + template + struct __has_rebind + : __sfinae_types + { + template + static __one __test(typename _Tp1::template rebind<_Up>*); + + template + static __two __test(...); + + static const bool __value = sizeof(__test<_Tp>(nullptr)) == 1; + }; + + template::__value> + struct __ptr_rebind; + + template + struct __ptr_rebind<_Tp, _Up, true> + { +#if 0 + typedef typename _Tp::template rebind<_Up> __type; +#else + typedef typename _Tp::template rebind<_Up>::other __type; +#endif + }; + + template class _Ptr, + typename _Tp, + typename _Up, + typename... _Args> + struct __ptr_rebind<_Ptr<_Tp, _Args...>, _Up, true> + { +#if 0 + typedef typename _Ptr<_Tp, _Args...>:: + template rebind<_Up> __type; +#else + typedef typename _Ptr<_Tp, _Args...>:: + template rebind<_Up>::other __type; +#endif + }; + + template class _Ptr, + typename _Tp, + typename _Up, + typename... _Args> + struct __ptr_rebind<_Ptr<_Tp, _Args...>, _Up, false> + { typedef _Ptr<_Up, _Args...> __type; }; + + /** + * @addtogroup pointer_abstractions + * @{ + */ + + /// 20.9.3 Primary template, pointer_traits. + template + struct pointer_traits + { + typedef _Tp pointer; + typedef typename + __ptr_element_type<_Tp>::__type element_type; + typedef typename + __ptr_difference_type<_Tp>::__type difference_type; + + template +#if 0 + using rebind = __ptr_rebind<_Tp, _Up>::__type; +#else + struct rebind + { typedef typename __ptr_rebind<_Tp, _Up>::__type other; }; +#endif + + private: + struct __unspecified_type {}; + typedef typename remove_cv::type _Elem_NoCV; + + public: + static pointer pointer_to(typename conditional::value, + __unspecified_type, + element_type>::type& __r) + { return pointer::pointer_to(__r); } + }; + + /// 20.9.3 pointer_traits, specialization for raw pointers. + template + struct pointer_traits<_Tp*> + { + typedef _Tp* pointer; + typedef _Tp element_type; + typedef std::ptrdiff_t difference_type; + + template +#if 0 + using rebind = _Up; +#else + struct rebind + { typedef _Up* other; }; +#endif + + private: + struct __unspecified_type {}; + typedef typename remove_cv::type _Elem_NoCV; + + // Members. + public: + static pointer pointer_to(typename conditional::value, + __unspecified_type, + element_type>::type& __r) + { return std::addressof(__r); } + }; + + /// @} group pointer_abstractions + +#undef _DEFINE_HAS_MEMTY +#undef _DEFINE_HAS_MEMTY_AUX + +_GLIBCXX_END_NAMESPACE + +#endif /* _PTR_TRAITS_H */ diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 3e7d4e8..f070f34 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -77,6 +77,7 @@ # include # include # include +# include # include // std::less # include # include diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc new file mode 100644 index 0000000..8ee8748 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc @@ -0,0 +1,42 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// 2010-07-20 Piotr Rak +// +// Copyright (C) 2010 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 + +template + struct P + { + typedef Tp_ element_type; + + static P pointer_to(element_type& r); + }; + +namespace std +{ + template class pointer_traits; + template class pointer_traits; + template class pointer_traits>; + template class pointer_traits>; +} + diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/members.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/members.cc new file mode 100644 index 0000000..32c3545 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/members.cc @@ -0,0 +1,49 @@ +// { dg-options "-std=gnu++0x" } +// 2010-07-20 Piotr Rak +// +// Copyright (C) 2010 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 P +{ + typedef int element_type; + + P(int* p = nullptr) + : _p(p) + { } + + static P pointer_to(int&) + { return &instance; } + + int* _p; + static int instance; +}; + +int P::instance = 0; + +int main() +{ + int i; + + VERIFY( std::pointer_traits::pointer_to(i) == std::addressof(i) ); + VERIFY( std::pointer_traits

::pointer_to(i)._p == &P::instance ); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/typedefs.cc new file mode 100644 index 0000000..bdad4ee --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/typedefs.cc @@ -0,0 +1,147 @@ +// { dg-options "-std=gnu++0x" } +// 2010-07-20 Piotr Rak +// +// Copyright (C) 2010 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 + +template struct X { }; + +struct P0 +{ + typedef int element_type; + + template +#if 0 + using rebind = int; +#else + struct rebind + { typedef int other; }; +#endif +}; + +template + struct P1 + { + typedef int element_type; + typedef void difference_type; + }; + +template + struct P2 + { + typedef void difference_type; + + template +#if 0 + using rebind = int; +#else + struct rebind + { typedef int other; }; +#endif + }; + +template + struct P3 + { + typedef void difference_type; + }; + + +template + struct P4 + { + template +#if 0 + using rebind = X +#else + struct rebind + { typedef X other; }; +#endif + }; + +void test01() +{ + using std::is_same; + + typedef std::pointer_traits pt_0; + typedef std::pointer_traits> pt_1; + typedef std::pointer_traits> pt_2; + typedef std::pointer_traits> pt_3; + typedef std::pointer_traits> pt_4; + + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + + VERIFY( (is_same >::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + + VERIFY( (is_same >::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + + VERIFY( (is_same >::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + + VERIFY( (is_same >::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + +#if 0 + VERIFY( (is_same, int >::value) ); + VERIFY( (is_same, P1 >::value) ); + VERIFY( (is_same, int >::value) ); + VERIFY( (is_same, P3 >::value) ); + VERIFY( (is_same, X >::value) ); +#else + VERIFY( (is_same::other, int >::value) ); + VERIFY( (is_same::other, P1 >::value) ); + VERIFY( (is_same::other, int >::value) ); + VERIFY( (is_same::other, P3 >::value) ); + VERIFY( (is_same::other, X >::value) ); +#endif + +} + +void test02() +{ + using std::is_same; + + typedef std::pointer_traits pt; + + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); + VERIFY( (is_same::value) ); +#if 0 + VERIFY( (is_same, void* >::value) ); +#else + VERIFY( (is_same::other, void* >::value) ); +#endif +} + +int main() +{ + test01(); + test02(); + return 0; +} -- 1.7.1.1