[PATCH] Implement std::pointer_traits::to_address as per P0653R0
Glen Fernandes
glen.fernandes@gmail.com
Sun Jul 16 21:54:00 GMT 2017
Implement pointer_traits::to_address as in P0653r0
* include/bits/allocated_ptr.h (allocated_ptr): Use
pointer_traits::to_address.
* include/bits/ptr_traits.h (pointer_traits): Implement to_address.
* include/ext/pointer.h (pointer_traits): Define to_address in
pointer_traits specialization.
* testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc:
Define operator->.
* testsuite/20_util/pointer_traits/to_address.cc: New tests.
Tested i686-pc-linux-gnu.
Glen
-------------- next part --------------
commit 7180839baa6dff48dc7a1536a2de0688f79d38dc
Author: Glen Fernandes <glenjofe@gmail.com>
Date: Sun Jul 16 16:49:18 2017 -0400
Implement pointer_traits::to_address as in P0653r0
* include/bits/allocated_ptr.h (allocated_ptr): Use pointer_traits::to_address.
* include/bits/ptr_traits.h (pointer_traits): Implement to_address.
* include/ext/pointer.h (pointer_traits): Define to_address in pointer_traits specialization.
* testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc: Define operator->.
* testsuite/20_util/pointer_traits/to_address.cc: New tests.
diff --git a/libstdc++-v3/include/bits/allocated_ptr.h b/libstdc++-v3/include/bits/allocated_ptr.h
index 773b3f5..72e0179 100644
--- a/libstdc++-v3/include/bits/allocated_ptr.h
+++ b/libstdc++-v3/include/bits/allocated_ptr.h
@@ -82,16 +82,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/// Get the address that the owned pointer refers to.
- value_type* get() { return _S_raw_ptr(_M_ptr); }
+ value_type* get()
+ { return std::pointer_traits<pointer>::to_address(_M_ptr); }
private:
- static value_type* _S_raw_ptr(value_type* __ptr) { return __ptr; }
-
- template<typename _Ptr>
- static auto
- _S_raw_ptr(_Ptr __ptr) -> decltype(_S_raw_ptr(__ptr.operator->()))
- { return _S_raw_ptr(__ptr.operator->()); }
-
_Alloc* _M_alloc;
pointer _M_ptr;
};
diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h
index 797e7fc..93e95ad 100644
--- a/libstdc++-v3/include/bits/ptr_traits.h
+++ b/libstdc++-v3/include/bits/ptr_traits.h
@@ -111,6 +111,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pointer_to(__make_not_void<element_type>& __e)
{ return _Ptr::pointer_to(__e); }
+ private:
+ template<typename _Tp>
+ static element_type*
+ __to_address(_Tp __p) noexcept
+ { return pointer_traits<_Tp>::to_address(__p); }
+ public:
+ /**
+ * @brief Obtain address referenced by a pointer to an object
+ * @param __p A pointer to an object
+ * @return @c pointer_traits<decltype(Expr)>::to_address(Expr)
+ where @c Expr is @c __p.operator->()
+ */
+ static element_type*
+ to_address(pointer __p) noexcept
+ { return __to_address(__p.operator->()); }
+
static_assert(!is_same<element_type, __undefined>::value,
"pointer type defines element_type or is like SomePointer<T, Args>");
};
@@ -140,6 +156,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static pointer
pointer_to(__make_not_void<element_type>& __r) noexcept
{ return std::addressof(__r); }
+
+ /**
+ * @brief Obtain address referenced by a pointer to an object
+ * @param __p A pointer to an object
+ * @return @c __p
+ */
+ static element_type*
+ to_address(pointer __p) noexcept { return __p; }
};
/// Convenience alias for rebinding pointers.
diff --git a/libstdc++-v3/include/ext/pointer.h b/libstdc++-v3/include/ext/pointer.h
index 8432da0..d7ab4e2 100644
--- a/libstdc++-v3/include/ext/pointer.h
+++ b/libstdc++-v3/include/ext/pointer.h
@@ -584,6 +584,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static pointer pointer_to(typename pointer::reference __r) noexcept
{ return pointer(std::addressof(__r)); }
+
+ static element_type* to_address(pointer __p) noexcept
+ { return __p.operator->(); }
};
_GLIBCXX_END_NAMESPACE_VERSION
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
index f54f793..a3ab52d 100644
--- a/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/pointer_traits/requirements/explicit_instantiation.cc
@@ -28,12 +28,14 @@ struct P1
using difference_type = long;
template<typename U> using rebind = P1<U>;
static P1 pointer_to(T&) { return {}; }
+ T* operator->() const noexcept { return {}; }
};
template<typename T>
struct P2
{
static P2 pointer_to(T&) { return {}; }
+ T* operator->() const noexcept { return {}; }
};
namespace std
diff --git a/libstdc++-v3/testsuite/20_util/pointer_traits/to_address.cc b/libstdc++-v3/testsuite/20_util/pointer_traits/to_address.cc
new file mode 100644
index 0000000..3c8cfbd
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pointer_traits/to_address.cc
@@ -0,0 +1,69 @@
+// { dg-do run { target c++11 } }
+
+// Copyright (C) 2011-2017 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/>.
+
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct P1
+{
+ typedef int element_type;
+ int* value;
+ explicit P1(int* ptr) noexcept : value(ptr) { }
+ int* operator->() const noexcept { return value; }
+};
+
+struct P2
+{
+ typedef P1::element_type element_type;
+ P1 value;
+ explicit P2(P1 ptr) noexcept : value(ptr) { }
+ P1 operator->() const noexcept { return value; }
+};
+
+void test01()
+{
+ int i = 0;
+ P1 p1( &i );
+ VERIFY( std::pointer_traits<P1>::to_address(p1) == &i );
+}
+
+void test02()
+{
+ int i = 0;
+ P1 p1( &i );
+ P2 p2( p1 );
+ VERIFY( std::pointer_traits<P2>::to_address(p2) == &i );
+}
+
+void test03()
+{
+ int i = 0;
+ VERIFY( std::pointer_traits<int*>::to_address(&i) == &i );
+ VERIFY( std::pointer_traits<const int*>::to_address(&i) == &i );
+ VERIFY( std::pointer_traits<void*>::to_address(&i) == &i );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
More information about the Gcc-patches
mailing list