libstdc++
ptr_traits.h
Go to the documentation of this file.
1 // Pointer Traits -*- C++ -*-
2 
3 // Copyright (C) 2011, 2012 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
34 
35 #include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
36 
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
40 
41 _GLIBCXX_HAS_NESTED_TYPE(element_type)
42 _GLIBCXX_HAS_NESTED_TYPE(difference_type)
43 
44  template<typename _Tp, bool = __has_element_type<_Tp>::value>
45  struct __ptrtr_elt_type;
46 
47  template<typename _Tp>
48  struct __ptrtr_elt_type<_Tp, true>
49  {
50  typedef typename _Tp::element_type __type;
51  };
52 
53  template<template<typename, typename...> class _SomePtr, typename _Tp,
54  typename... _Args>
55  struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false>
56  {
57  typedef _Tp __type;
58  };
59 
60  template<typename _Tp, bool = __has_difference_type<_Tp>::value>
61  struct __ptrtr_diff_type
62  {
63  typedef typename _Tp::difference_type __type;
64  };
65 
66  template<typename _Tp>
67  struct __ptrtr_diff_type<_Tp, false>
68  {
69  typedef ptrdiff_t __type;
70  };
71 
72  template<typename _Ptr, typename _Up>
73  class __ptrtr_rebind_helper
74  {
75  template<typename _Ptr2, typename _Up2>
76  static constexpr bool
77  _S_chk(typename _Ptr2::template rebind<_Up2>*)
78  { return true; }
79 
80  template<typename, typename>
81  static constexpr bool
82  _S_chk(...)
83  { return false; }
84 
85  public:
86  static const bool __value = _S_chk<_Ptr, _Up>(nullptr);
87  };
88 
89  template<typename _Ptr, typename _Up>
90  const bool __ptrtr_rebind_helper<_Ptr, _Up>::__value;
91 
92  template<typename _Tp, typename _Up,
93  bool = __ptrtr_rebind_helper<_Tp, _Up>::__value>
94  struct __ptrtr_rebind;
95 
96  template<typename _Tp, typename _Up>
97  struct __ptrtr_rebind<_Tp, _Up, true>
98  {
99  typedef typename _Tp::template rebind<_Up> __type;
100  };
101 
102  template<template<typename, typename...> class _SomePtr, typename _Up,
103  typename _Tp, typename... _Args>
104  struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false>
105  {
106  typedef _SomePtr<_Up, _Args...> __type;
107  };
108 
109  template<typename _Tp, typename = typename remove_cv<_Tp>::type>
110  struct __ptrtr_not_void
111  {
112  typedef _Tp __type;
113  };
114 
115  template<typename _Tp>
116  struct __ptrtr_not_void<_Tp, void>
117  {
118  struct __type { };
119  };
120 
121  template<typename _Ptr>
122  class __ptrtr_pointer_to
123  {
124  typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type;
125  typedef typename __ptrtr_not_void<__orig_type>::__type __element_type;
126 
127  public:
128  static _Ptr pointer_to(__element_type& __e)
129  { return _Ptr::pointer_to(__e); }
130  };
131 
132  /**
133  * @brief Uniform interface to all pointer-like types
134  * @ingroup pointer_abstractions
135  */
136  template<typename _Ptr>
137  struct pointer_traits : __ptrtr_pointer_to<_Ptr>
138  {
139  /// The pointer type
140  typedef _Ptr pointer;
141  /// The type pointed to
142  typedef typename __ptrtr_elt_type<_Ptr>::__type element_type;
143  /// Type used to represent the difference between two pointers
144  typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type;
145 
146  template<typename _Up>
147  using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type;
148  };
149 
150  /**
151  * @brief Partial specialization for built-in pointers.
152  * @ingroup pointer_abstractions
153  */
154  template<typename _Tp>
155  struct pointer_traits<_Tp*>
156  {
157  /// The pointer type
158  typedef _Tp* pointer;
159  /// The type pointed to
160  typedef _Tp element_type;
161  /// Type used to represent the difference between two pointers
162  typedef ptrdiff_t difference_type;
163 
164  template<typename _Up>
165  using rebind = _Up*;
166 
167  /**
168  * @brief Obtain a pointer to an object
169  * @param __r A reference to an object of type @c element_type
170  * @return @c addressof(__r)
171  */
172  static pointer
173  pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) noexcept
174  { return std::addressof(__r); }
175  };
176 
177 _GLIBCXX_END_NAMESPACE_VERSION
178 } // namespace std
179 
180 #endif
181 
182 #endif