VCCC  2024.05
VisualCamp Common C++ library
pointer_traits.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 3/7/24.
3 //
4 
5 #ifndef VCCC_MEMORY_POINTER_TRAITS_HPP
6 #define VCCC_MEMORY_POINTER_TRAITS_HPP
7 
8 #include <cstddef>
9 
16 
17 namespace vccc {
18 namespace detail {
19 
21 struct pointer_traits_element_type {};
22 
23 template<typename Ptr>
24 struct pointer_traits_element_type<Ptr, true> {
25  using type = typename Ptr::element_type;
26 };
27 
28 template<template<typename, typename...> class Ptr, typename T, typename... Args>
29 struct pointer_traits_element_type<Ptr<T, Args...>, false> {
30  using type = T;
31 };
32 
34 struct pointer_traits_difference_type {
35  using type = typename Ptr::difference_type;
36 };
37 
38 template<typename Ptr>
39 struct pointer_traits_difference_type<Ptr, false> {
40  using type = std::ptrdiff_t;
41 };
42 
43 template<typename T, typename U, typename = void>
44 struct has_rebind : std::false_type {};
45 template<typename T, typename U>
46 struct has_rebind<T, U, void_t<typename T::template rebind<U>>> : std::true_type {};
47 
49 struct pointer_traits_rebind;
50 
51 template<typename Ptr, typename U>
52 struct pointer_traits_rebind<Ptr, U, true> {
53  using type = typename Ptr::template rebind<U>;
54 };
55 
56 template<template<typename, typename...> class Ptr, typename U, typename T, typename... Args>
57 struct pointer_traits_rebind<Ptr<T, Args...>, U, false> {
58  using type = Ptr<U, Args...>;
59 };
60 
61 template<typename Ptr, bool = has_typename_type<pointer_traits_element_type<Ptr>>::value /* true */>
62 struct pointer_traits_impl {
63  using pointer = Ptr;
64  using element_type = typename pointer_traits_element_type<Ptr>::type;
65  using difference_type = typename pointer_traits_difference_type<Ptr>::type;
66 
67  template<typename U>
68  using rebind = typename pointer_traits_rebind<Ptr, U>::type;
69 
70  static pointer pointer_to(element_type& r) {
71  return Ptr::pointer_to(r);
72  }
73 };
74 
75 template<typename Ptr>
76 struct pointer_traits_impl<Ptr, false> {};
77 
78 } // namespace detail
79 
82 
83 template<typename Ptr>
85  : detail::pointer_traits_impl<Ptr> {};
86 
87 template<typename T>
88 struct pointer_traits<T*> {
89  using pointer = T*;
90  using element_type = T;
91  using difference_type = std::ptrdiff_t;
92 
93  template<typename U>
94  using rebind = U*;
95 
97  return vccc::addressof(r);
98  }
99 };
100 
102 
103 } // namespace vccc
104 
105 #endif // VCCC_MEMORY_POINTER_TRAITS_HPP
#define VCCC_CONSTEXPR_AFTER_CXX17
Definition: constexpr.hpp:20
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
void void_t
Definition: void_t.hpp:19
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
static VCCC_CONSTEXPR_AFTER_CXX17 pointer pointer_to(element_type &r) noexcept
Definition: pointer_traits.hpp:96
U * rebind
Definition: pointer_traits.hpp:94
T * pointer
Definition: pointer_traits.hpp:89
T element_type
Definition: pointer_traits.hpp:90
std::ptrdiff_t difference_type
Definition: pointer_traits.hpp:91
Definition: pointer_traits.hpp:85