1    	// Pointer Traits -*- C++ -*-
2    	
3    	// Copyright (C) 2011-2019 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file bits/ptr_traits.h
26   	 *  This is an internal header file, included by other library headers.
27   	 *  Do not attempt to use it directly. @headername{memory}
28   	 */
29   	
30   	#ifndef _PTR_TRAITS_H
31   	#define _PTR_TRAITS_H 1
32   	
33   	#if __cplusplus >= 201103L
34   	
35   	#include <bits/move.h>
36   	
37   	namespace std _GLIBCXX_VISIBILITY(default)
38   	{
39   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
40   	
41   	  class __undefined;
42   	
43   	  // Given Template<T, ...> return T, otherwise invalid.
44   	  template<typename _Tp>
45   	    struct __get_first_arg
46   	    { using type = __undefined; };
47   	
48   	  template<template<typename, typename...> class _Template, typename _Tp,
49   	           typename... _Types>
50   	    struct __get_first_arg<_Template<_Tp, _Types...>>
51   	    { using type = _Tp; };
52   	
53   	  template<typename _Tp>
54   	    using __get_first_arg_t = typename __get_first_arg<_Tp>::type;
55   	
56   	  // Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
57   	  template<typename _Tp, typename _Up>
58   	    struct __replace_first_arg
59   	    { };
60   	
61   	  template<template<typename, typename...> class _Template, typename _Up,
62   	           typename _Tp, typename... _Types>
63   	    struct __replace_first_arg<_Template<_Tp, _Types...>, _Up>
64   	    { using type = _Template<_Up, _Types...>; };
65   	
66   	  template<typename _Tp, typename _Up>
67   	    using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type;
68   	
69   	  template<typename _Tp>
70   	    using __make_not_void
71   	      = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;
72   	
73   	  /**
74   	   * @brief  Uniform interface to all pointer-like types
75   	   * @ingroup pointer_abstractions
76   	  */
77   	  template<typename _Ptr>
78   	    struct pointer_traits
79   	    {
80   	    private:
81   	      template<typename _Tp>
82   		using __element_type = typename _Tp::element_type;
83   	
84   	      template<typename _Tp>
85   		using __difference_type = typename _Tp::difference_type;
86   	
87   	      template<typename _Tp, typename _Up, typename = void>
88   		struct __rebind : __replace_first_arg<_Tp, _Up> { };
89   	
90   	      template<typename _Tp, typename _Up>
91   		struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
92   		{ using type = typename _Tp::template rebind<_Up>; };
93   	
94   	    public:
95   	      /// The pointer type.
96   	      using pointer = _Ptr;
97   	
98   	      /// The type pointed to.
99   	      using element_type
100  		= __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>;
101  	
102  	      /// The type used to represent the difference between two pointers.
103  	      using difference_type
104  		= __detected_or_t<ptrdiff_t, __difference_type, _Ptr>;
105  	
106  	      /// A pointer to a different type.
107  	      template<typename _Up>
108  	        using rebind = typename __rebind<_Ptr, _Up>::type;
109  	
110  	      static _Ptr
111  	      pointer_to(__make_not_void<element_type>& __e)
112  	      { return _Ptr::pointer_to(__e); }
113  	
114  	      static_assert(!is_same<element_type, __undefined>::value,
115  		  "pointer type defines element_type or is like SomePointer<T, Args>");
116  	    };
117  	
118  	  /**
119  	   * @brief  Partial specialization for built-in pointers.
120  	   * @ingroup pointer_abstractions
121  	  */
122  	  template<typename _Tp>
123  	    struct pointer_traits<_Tp*>
124  	    {
125  	      /// The pointer type
126  	      typedef _Tp* pointer;
127  	      /// The type pointed to
128  	      typedef _Tp  element_type;
129  	      /// Type used to represent the difference between two pointers
130  	      typedef ptrdiff_t difference_type;
131  	
132  	      template<typename _Up>
133  	        using rebind = _Up*;
134  	
135  	      /**
136  	       *  @brief  Obtain a pointer to an object
137  	       *  @param  __r  A reference to an object of type @c element_type
138  	       *  @return @c addressof(__r)
139  	      */
140  	      static _GLIBCXX20_CONSTEXPR pointer
141  	      pointer_to(__make_not_void<element_type>& __r) noexcept
142  	      { return std::addressof(__r); }
143  	    };
144  	
145  	  /// Convenience alias for rebinding pointers.
146  	  template<typename _Ptr, typename _Tp>
147  	    using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>;
148  	
149  	  template<typename _Tp>
150  	    constexpr _Tp*
(1) Event noescape: "std::__to_address<std::__detail::_Hash_node<std::pair<int const, osd_stat_t>, false> >(mempool::pool_allocator<(mempool::pool_index_t)17, std::__detail::_Hash_node<std::pair<int const, osd_stat_t>, false> >::value_type *)" does not free or save its parameter "__ptr".
151  	    __to_address(_Tp* __ptr) noexcept
152  	    {
153  	      static_assert(!std::is_function<_Tp>::value, "not a function pointer");
(1) Event return_parm: Returning parameter "__ptr".
154  	      return __ptr;
155  	    }
156  	
157  	#if __cplusplus <= 201703L
158  	  template<typename _Ptr>
159  	    constexpr typename std::pointer_traits<_Ptr>::element_type*
160  	    __to_address(const _Ptr& __ptr)
161  	    { return std::__to_address(__ptr.operator->()); }
162  	#else
163  	  template<typename _Ptr>
164  	    constexpr auto
165  	    __to_address(const _Ptr& __ptr) noexcept
166  	    -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr))
167  	    { return std::pointer_traits<_Ptr>::to_address(__ptr); }
168  	
169  	  template<typename _Ptr, typename... _None>
170  	    constexpr auto
171  	    __to_address(const _Ptr& __ptr, _None...) noexcept
172  	    { return std::__to_address(__ptr.operator->()); }
173  	
174  	  /**
175  	   * @brief Obtain address referenced by a pointer to an object
176  	   * @param __ptr A pointer to an object
177  	   * @return @c __ptr
178  	   * @ingroup pointer_abstractions
179  	  */
180  	  template<typename _Tp>
181  	    constexpr _Tp*
182  	    to_address(_Tp* __ptr) noexcept
183  	    { return std::__to_address(__ptr); }
184  	
185  	  /**
186  	   * @brief Obtain address referenced by a pointer to an object
187  	   * @param __ptr A pointer to an object
188  	   * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is
189  	             well-formed, otherwise @c to_address(__ptr.operator->())
190  	   * @ingroup pointer_abstractions
191  	  */
192  	  template<typename _Ptr>
193  	    constexpr auto
194  	    to_address(const _Ptr& __ptr) noexcept
195  	    { return std::__to_address(__ptr); }
196  	#endif // C++2a
197  	
198  	_GLIBCXX_END_NAMESPACE_VERSION
199  	} // namespace std
200  	
201  	#endif
202  	
203  	#endif
204