]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/ext/pointer.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / ext / pointer.h
index 5c764cfd4b061e3e755b4483f6ba1c39956521ef..534b3c78226e716548f01ccaf0d1214e4675d704 100644 (file)
@@ -1,11 +1,11 @@
 // Custom pointer adapter and sample storage policies
 
-// Copyright (C) 2008 Free Software Foundation, Inc.
+// Copyright (C) 2008-2024 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 2, or (at your option)
+// 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,
 // 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 COPYING.  If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// 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.
 
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+// 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
+// <http://www.gnu.org/licenses/>.
 
 /**
- * @file ext/pointer.h
- * @author Bob Walters
+ *  @file ext/pointer.h
+ *  This file is a GNU extension to the Standard C++ Library.
+ *
+ *  @author Bob Walters
  *
  * Provides reusable _Pointer_adapter for assisting in the development of
  * custom pointer types that can be used with the standard containers via
 #ifndef _POINTER_H
 #define _POINTER_H 1
 
-#include <iosfwd>
+#pragma GCC system_header
+
+#if _GLIBCXX_HOSTED
+#  include <iosfwd>
+#endif
+
 #include <bits/stl_iterator_base_types.h>
 #include <ext/cast.h>
-
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+#include <ext/type_traits.h>
+#if __cplusplus >= 201103L
+# include <bits/move.h>
+# include <bits/ptr_traits.h>
+#endif
+#if __cplusplus > 201703L
+# include <iterator> // for indirectly_readable_traits
+#endif
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /** 
    * @brief A storage policy for use with _Pointer_adapter<> which yields a
@@ -91,12 +103,12 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
    *        the pointer's address as an offset value which is relative to
    *        its own address.
    * 
-   * This is intended for pointers
-   * within shared memory regions which might be mapped at different
-   * addresses by different processes.  For null pointers, a value of 1 is
-   * used.  (0 is legitimate sometimes for nodes in circularly linked lists)
-   * This value was chosen as the least likely to generate an incorrect null,
-   * As there is no reason why any normal pointer would point 1 byte into
+   * This is intended for pointers within shared memory regions which
+   * might be mapped at different addresses by different processes.
+   * For null pointers, a value of 1 is used.  (0 is legitimate
+   * sometimes for nodes in circularly linked lists) This value was
+   * chosen as the least likely to generate an incorrect null, As
+   * there is no reason why any normal pointer would point 1 byte into
    * its own pointer address.
    */
   template<typename _Tp> 
@@ -111,9 +123,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
         if (_M_diff == 1)
           return 0;
         else
-          return reinterpret_cast<_Tp*>(
-                 const_cast<char*>(reinterpret_cast<const char*>(this))
-                 + _M_diff);
+          return reinterpret_cast<_Tp*>(reinterpret_cast<uintptr_t>(this)
+                                       + _M_diff);
       }
   
       void 
@@ -122,21 +133,24 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
         if (!__arg)
           _M_diff = 1;
         else
-          _M_diff = reinterpret_cast<char*>(__arg) 
-                    - reinterpret_cast<char*>(this);
+          _M_diff = reinterpret_cast<uintptr_t>(__arg) 
+                    - reinterpret_cast<uintptr_t>(this);
       }
   
       // Comparison of pointers
       inline bool
       operator<(const _Relative_pointer_impl& __rarg) const
-      { return (this->get() < __rarg.get()); }
+      { return (reinterpret_cast<uintptr_t>(this->get())
+               < reinterpret_cast<uintptr_t>(__rarg.get())); }
 
       inline bool
       operator==(const _Relative_pointer_impl& __rarg) const
-      { return (this->get() == __rarg.get()); }
+      { return (reinterpret_cast<uintptr_t>(this->get())
+               == reinterpret_cast<uintptr_t>(__rarg.get())); }
 
     private:
-      std::ptrdiff_t _M_diff;
+      typedef __UINTPTR_TYPE__ uintptr_t;
+      uintptr_t _M_diff;
     };
   
   /**
@@ -155,8 +169,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
         if (_M_diff == 1)
           return 0;
         else
-          return reinterpret_cast<const _Tp*>(
-                  (reinterpret_cast<const char*>(this)) + _M_diff);
+          return reinterpret_cast<const _Tp*>
+             (reinterpret_cast<uintptr_t>(this) + _M_diff);
       }
   
       void 
@@ -165,27 +179,30 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
         if (!__arg)
           _M_diff = 1;
         else
-          _M_diff = reinterpret_cast<const char*>(__arg) 
-                    - reinterpret_cast<const char*>(this);
+          _M_diff = reinterpret_cast<uintptr_t>(__arg) 
+                    - reinterpret_cast<uintptr_t>(this);
       }
   
       // Comparison of pointers
       inline bool
       operator<(const _Relative_pointer_impl& __rarg) const
-      { return (this->get() < __rarg.get()); }
+      { return (reinterpret_cast<uintptr_t>(this->get())
+               < reinterpret_cast<uintptr_t>(__rarg.get())); }
 
       inline bool
       operator==(const _Relative_pointer_impl& __rarg) const
-      { return (this->get() == __rarg.get()); }
+      { return (reinterpret_cast<uintptr_t>(this->get())
+               == reinterpret_cast<uintptr_t>(__rarg.get())); }
   
     private:
-      std::ptrdiff_t _M_diff;
+      typedef __UINTPTR_TYPE__ uintptr_t;
+      uintptr_t _M_diff;
     };
 
   /**
    * The specialization on this type helps resolve the problem of
-   * reference to void, and eliminates the need to specialize _Pointer_adapter
-   * for cases of void*, const void*, and so on.
+   * reference to void, and eliminates the need to specialize
+   * _Pointer_adapter for cases of void*, const void*, and so on.
    */
   struct _Invalid_type { };
   
@@ -210,8 +227,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     { typedef const volatile _Invalid_type&  reference; };
 
   /**
-   * This structure accomodates the way in which std::iterator_traits<>
-   * is normally specialized for const T*, so that value_type is still T.
+   * This structure accommodates the way in which
+   * std::iterator_traits<> is normally specialized for const T*, so
+   * that value_type is still T.
    */
   template<typename _Tp> 
     struct _Unqualified_type 
@@ -221,37 +239,32 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     struct _Unqualified_type<const _Tp> 
     { typedef _Tp type; };
     
-  template<typename _Tp> 
-    struct _Unqualified_type<volatile _Tp> 
-    { typedef volatile _Tp type; };
-    
-  template<typename _Tp> 
-    struct _Unqualified_type<volatile const _Tp> 
-    { typedef volatile _Tp type; };
-  
   /**
-   * The following provides an 'alternative pointer' that works with the
-   * containers when specified as the pointer typedef of the allocator.
+   * The following provides an 'alternative pointer' that works with
+   * the containers when specified as the pointer typedef of the
+   * allocator.
    *
-   * The pointer type used with the containers doesn't have to be this class,
-   * but it must support the implicit conversions, pointer arithmetic,
-   * comparison operators, etc. that are supported by this class, and avoid
-   * raising compile-time ambiguities.  Because creating a working pointer can
-   * be challenging, this pointer template was designed to wrapper an 
-   * easier storage policy type, so that it becomes reusable for creating
-   * other pointer types. 
+   * The pointer type used with the containers doesn't have to be this
+   * class, but it must support the implicit conversions, pointer
+   * arithmetic, comparison operators, etc. that are supported by this
+   * class, and avoid raising compile-time ambiguities.  Because
+   * creating a working pointer can be challenging, this pointer
+   * template was designed to wrapper an easier storage policy type,
+   * so that it becomes reusable for creating other pointer types.
    *
-   * A key point of this class is also that it allows container writers to
-   * 'assume' Alocator::pointer is a typedef for a normal pointer.  This class
-   * supports most of the conventions of a true pointer, and can, for instance
-   * handle implicit conversion to const and base class pointer types.  The
-   * only impositions on container writers to support extended pointers are:
-   * 1) use the Allocator::pointer typedef appropriately for pointer types.
-   * 2) if you need pointer casting, use the __pointer_cast<> functions
-   *    from ext/cast.h.  This allows pointer cast operations to be overloaded
-   *    is necessary by custom pointers.
+   * A key point of this class is also that it allows container
+   * writers to 'assume' Allocator::pointer is a typedef for a normal
+   * pointer.  This class supports most of the conventions of a true
+   * pointer, and can, for instance handle implicit conversion to
+   * const and base class pointer types.  The only impositions on
+   * container writers to support extended pointers are: 1) use the
+   * Allocator::pointer typedef appropriately for pointer types.  2)
+   * if you need pointer casting, use the __pointer_cast<> functions
+   * from ext/cast.h.  This allows pointer cast operations to be
+   * overloaded as necessary by custom pointers.
    *
-   * Note:  The const qualifier works with this pointer adapter as follows:
+   * Note: The const qualifier works with this pointer adapter as
+   * follows:
    *
    * _Tp*             == _Pointer_adapter<_Std_pointer_impl<_Tp> >;
    * const _Tp*       == _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
@@ -337,6 +350,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       { return _Storage_policy::get()[__index]; }
 
       // To allow implicit conversion to "bool", for "if (ptr)..."
+#if __cplusplus >= 201103L
+      explicit operator bool() const { return _Storage_policy::get() != 0; }
+#else
     private:
       typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;
 
@@ -351,6 +367,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       inline bool
       operator!() const 
       { return (_Storage_policy::get() == 0); }
+#endif
   
       // Pointer differences
       inline friend std::ptrdiff_t 
@@ -411,13 +428,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       } \
 // END of _CXX_POINTER_ARITH_OPERATOR_SET macro
   
-      // Expand into the various pointer arithmatic operators needed.
+      // Expand into the various pointer arithmetic operators needed.
       _CXX_POINTER_ARITH_OPERATOR_SET(short);
       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
       _CXX_POINTER_ARITH_OPERATOR_SET(int);
       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
       _CXX_POINTER_ARITH_OPERATOR_SET(long);
       _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long);
+#ifdef _GLIBCXX_USE_LONG_LONG
+      _CXX_POINTER_ARITH_OPERATOR_SET(long long);
+      _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long);
+#endif
 
       // Mathematical Manipulators
       inline _Pointer_adapter& 
@@ -428,11 +449,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       }
   
       inline _Pointer_adapter 
-      operator++(int __unused) 
+      operator++(int)
       {
-        _Pointer_adapter tmp(*this);
+        _Pointer_adapter __tmp(*this);
         _Storage_policy::set(_Storage_policy::get() + 1);
-        return tmp;
+        return __tmp;
       }
   
       inline _Pointer_adapter& 
@@ -445,40 +466,46 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       inline _Pointer_adapter
       operator--(int) 
       {
-        _Pointer_adapter tmp(*this);
+        _Pointer_adapter __tmp(*this);
         _Storage_policy::set(_Storage_policy::get() - 1);
-        return tmp;
+        return __tmp;
       }
-  
+
+#if __cpp_lib_three_way_comparison
+      friend std::strong_ordering
+      operator<=>(const _Pointer_adapter& __lhs, const _Pointer_adapter& __rhs)
+      noexcept
+      { return __lhs.get() <=> __rhs.get(); }
+#endif
     }; // class _Pointer_adapter
 
 
-#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR,BLANK) \
+#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
   template<typename _Tp1, typename _Tp2> \
     inline bool \
-    operator OPERATOR##BLANK (const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
-    { return __lhs.get() OPERATOR##BLANK __rhs; } \
+    operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
+    { return __lhs.get() OPERATOR __rhs; } \
 \
   template<typename _Tp1, typename _Tp2> \
     inline bool \
-    operator OPERATOR##BLANK (_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
-    { return __lhs OPERATOR##BLANK __rhs.get(); } \
+    operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
+    { return __lhs OPERATOR __rhs.get(); } \
 \
   template<typename _Tp1, typename _Tp2> \
     inline bool \
-    operator OPERATOR##BLANK (const _Pointer_adapter<_Tp1>& __lhs, \
+    operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
                               const _Pointer_adapter<_Tp2>& __rhs) \
-    { return __lhs.get() OPERATOR##BLANK __rhs.get(); } \
+    { return __lhs.get() OPERATOR __rhs.get(); } \
 \
 // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
   
   // Expand into the various comparison operators needed.
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==,);
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=,);
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<,);
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=,);
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>,);
-  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=,);
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==)
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=)
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<)
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=)
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>)
+  _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=)
 
   // These are here for expressions like "ptr == 0", "ptr != 0"
   template<typename _Tp>
@@ -502,7 +529,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     { return __rhs.get() != reinterpret_cast<void*>(__lhs); } 
 
   /**
-   * Comparison operators for _Pointer_adapter defer to the base class'es
+   * Comparison operators for _Pointer_adapter defer to the base class'
    * comparison operators, when possible.
    */
   template<typename _Tp>
@@ -535,12 +562,50 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
                const _Pointer_adapter<_Tp>& __rhs)
     { return !(__lhs._Tp::operator<(__rhs)); }
 
+#if _GLIBCXX_HOSTED
   template<typename _CharT, typename _Traits, typename _StoreT>
     inline std::basic_ostream<_CharT, _Traits>&
     operator<<(std::basic_ostream<_CharT, _Traits>& __os, 
                const _Pointer_adapter<_StoreT>& __p)
     { return (__os << __p.get()); }
+#endif // HOSTED
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
 
-_GLIBCXX_END_NAMESPACE
+#if __cplusplus >= 201103L
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Storage_policy>
+    struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>>
+    {
+      /// The pointer type
+      typedef __gnu_cxx::_Pointer_adapter<_Storage_policy>         pointer;
+      /// The type pointed to
+      typedef typename pointer::element_type            element_type;
+      /// Type used to represent the difference between two pointers
+      typedef typename pointer::difference_type         difference_type;
+
+      template<typename _Up>
+        using rebind = typename __gnu_cxx::_Pointer_adapter<
+         typename pointer_traits<_Storage_policy>::template rebind<_Up>>;
+
+      static pointer pointer_to(typename pointer::reference __r) noexcept
+      { return pointer(std::addressof(__r)); }
+    };
+
+#if __cpp_lib_concepts
+  template<typename _Policy>
+    struct indirectly_readable_traits<__gnu_cxx::_Pointer_adapter<_Policy>>
+    {
+      using value_type
+       = typename __gnu_cxx::_Pointer_adapter<_Policy>::value_type;
+    };
+#endif
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif
 
 #endif // _POINTER_H