// Custom pointer adapter and sample storage policies
-// Copyright (C) 2008, 2009, 2010 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
#pragma GCC system_header
-#include <iosfwd>
+#if _GLIBCXX_HOSTED
+# include <iosfwd>
+#endif
+
#include <bits/stl_iterator_base_types.h>
#include <ext/cast.h>
#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
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief A storage policy for use with _Pointer_adapter<> which yields a
if (_M_diff == 1)
return 0;
else
- return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
+ return reinterpret_cast<_Tp*>(reinterpret_cast<uintptr_t>(this)
+ _M_diff);
}
if (!__arg)
_M_diff = 1;
else
- _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
- - reinterpret_cast<_UIntPtrType>(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 (reinterpret_cast<_UIntPtrType>(this->get())
- < reinterpret_cast<_UIntPtrType>(__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 (reinterpret_cast<_UIntPtrType>(this->get())
- == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
+ { return (reinterpret_cast<uintptr_t>(this->get())
+ == reinterpret_cast<uintptr_t>(__rarg.get())); }
private:
-#ifdef _GLIBCXX_USE_LONG_LONG
- typedef __gnu_cxx::__conditional_type<
- (sizeof(unsigned long) >= sizeof(void*)),
- unsigned long, unsigned long long>::__type _UIntPtrType;
-#else
- typedef unsigned long _UIntPtrType;
-#endif
- _UIntPtrType _M_diff;
+ typedef __UINTPTR_TYPE__ uintptr_t;
+ uintptr_t _M_diff;
};
/**
return 0;
else
return reinterpret_cast<const _Tp*>
- (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
+ (reinterpret_cast<uintptr_t>(this) + _M_diff);
}
void
if (!__arg)
_M_diff = 1;
else
- _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
- - reinterpret_cast<_UIntPtrType>(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 (reinterpret_cast<_UIntPtrType>(this->get())
- < reinterpret_cast<_UIntPtrType>(__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 (reinterpret_cast<_UIntPtrType>(this->get())
- == reinterpret_cast<_UIntPtrType>(__rarg.get())); }
+ { return (reinterpret_cast<uintptr_t>(this->get())
+ == reinterpret_cast<uintptr_t>(__rarg.get())); }
private:
-#ifdef _GLIBCXX_USE_LONG_LONG
- typedef __gnu_cxx::__conditional_type<
- (sizeof(unsigned long) >= sizeof(void*)),
- unsigned long, unsigned long long>::__type _UIntPtrType;
-#else
- typedef unsigned long _UIntPtrType;
-#endif
- _UIntPtrType _M_diff;
+ typedef __UINTPTR_TYPE__ uintptr_t;
+ uintptr_t _M_diff;
};
/**
{ typedef const volatile _Invalid_type& reference; };
/**
- * This structure accomodates the way in which
+ * This structure accommodates the way in which
* std::iterator_traits<> is normally specialized for const T*, so
* that value_type is still T.
*/
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
* 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
+ * 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
* 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.
+ * overloaded as necessary by custom pointers.
*
* Note: The const qualifier works with this pointer adapter as
* follows:
{ 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;
inline bool
operator!() const
{ return (_Storage_policy::get() == 0); }
+#endif
// Pointer differences
inline friend std::ptrdiff_t
} \
// 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&
inline _Pointer_adapter
operator++(int)
{
- _Pointer_adapter tmp(*this);
+ _Pointer_adapter __tmp(*this);
_Storage_policy::set(_Storage_policy::get() + 1);
- return tmp;
+ return __tmp;
}
inline _Pointer_adapter&
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
{ 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>
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
+
+#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;
-_GLIBCXX_END_NAMESPACE
+ 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