Changeset bfc972e in mainline
- Timestamp:
- 2018-07-05T21:41:24Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ca8d393
- Parents:
- 17012fcf
- git-author:
- Dzejrou <dzejrou@…> (2018-05-16 00:49:54)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:24)
- Location:
- uspace/lib/cpp
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/memory.hpp
r17012fcf rbfc972e 32 32 #include <internal/aux.hpp> 33 33 #include <internal/functional/hash.hpp> 34 #include <internal/memory/addressof.hpp> 34 35 #include <internal/memory/allocator_arg.hpp> 35 #include <internal/memory/ addressof.hpp>36 #include <internal/memory/type_getters.hpp> 36 37 #include <iterator> 37 38 #include <new> … … 43 44 /** 44 45 * 20.7.3, pointer traits: 46 * Note: The type getters that are used in pointer_traits 47 * and allocator_traits are implemented in 48 * <internal/memory/type_getters.hpp>. 45 49 */ 46 50 … … 48 52 struct pointer_traits 49 53 { 50 using pointer = Ptr;51 // TODO: element type, difference type52 53 // TODO: this is conditional, see standard 54 using pointer = Ptr; 55 using element_type = typename aux::ptr_get_element_type<Ptr>::type; 56 using difference_type = typename aux::ptr_get_difference_type<Ptr>::type; 57 54 58 template<class U> 55 using rebind = typename Ptr::template rebind<U>; 59 using rebind = typename aux::ptr_get_rebind<Ptr, U>::type; 60 61 static pointer pointer_to( // If is_void_t<element_type>, this type is unspecified. 62 conditional_t<is_void_v<element_type>, char, element_type&> x 63 ) 64 { 65 return Ptr::pointer_to(x); 66 } 56 67 }; 68 69 template<class T> 70 struct pointer_traits<T*> 71 { 72 using pointer = T*; 73 using element_type = T; 74 using difference_type = ptrdiff_t; 75 76 template<class U> 77 using rebind = U*; 78 79 static pointer pointer_to( 80 conditional_t<is_void_v<element_type>, char, element_type&> x 81 ) 82 { 83 return std::addressof(x); 84 } 85 }; 86 87 /** 88 * 20.7.4, pointer safety: 89 */ 90 91 // TODO: implement 92 93 /** 94 * 20.7.5, align: 95 */ 96 97 // TODO: implement 57 98 58 99 /** … … 84 125 * 20.7.8, allocator traits: 85 126 */ 86 87 namespace aux88 {89 /**90 * The standard mandates that we reuse type from allocators91 * *if* they are defined or that we use something different.92 * These structures help us alternate between those by93 * using SFINAE.94 * TODO: Create tests for these!95 */96 97 template<class T, class = void>98 struct get_pointer: aux::type_is<typename T::value_type*>99 { /* DUMMY BODY */ };100 101 template<class T>102 struct get_pointer<T, void_t<typename T::pointer>>103 : aux::type_is<typename T::pointer>104 { /* DUMMY BODY */ };105 106 template<class T, class Ptr, class = void>107 struct get_const_pointer108 : aux::type_is<typename pointer_traits<Ptr>::template rebind<const typename T::value_type>>109 { /* DUMMY BODY */ };110 111 template<class T, class Ptr>112 struct get_const_pointer<T, Ptr, void_t<typename T::const_pointer>>113 : aux::type_is<typename T::const_pointer>114 { /* DUMMY BODY */ };115 116 template<class T, class Ptr, class = void>117 struct get_void_pointer118 : aux::type_is<typename pointer_traits<Ptr>::template rebind<void>>119 { /* DUMMY BODY */ };120 121 template<class T, class Ptr>122 struct get_void_pointer<T, Ptr, void_t<typename T::void_pointer>>123 : aux::type_is<typename T::void_pointer>124 { /* DUMMY BODY */ };125 126 template<class T, class Ptr, class = void>127 struct get_const_void_pointer128 : aux::type_is<typename pointer_traits<Ptr>::template rebind<const void>>129 { /* DUMMY BODY */ };130 131 template<class T, class Ptr>132 struct get_const_void_pointer<T, Ptr, void_t<typename T::const_void_pointer>>133 : aux::type_is<typename T::const_void_pointer>134 { /* DUMMY BODY */ };135 136 template<class T, class Ptr, class = void>137 struct get_difference_type138 : aux::type_is<typename pointer_traits<Ptr>::difference_type>139 { /* DUMMY BODY */ };140 141 template<class T, class Ptr>142 struct get_difference_type<T, Ptr, void_t<typename T::difference_type>>143 : aux::type_is<typename T::difference_type>144 { /* DUMMY BODY */ };145 146 template<class T, class Difference, class = void>147 struct get_size_type: aux::type_is<make_unsigned_t<Difference>>148 { /* DUMMY BODY */ };149 150 template<class T, class Difference>151 struct get_size_type<T, Difference, void_t<typename T::size_type>>152 : aux::type_is<typename T::size_type>153 { /* DUMMY BODY */ };154 155 template<class T, class = void>156 struct get_copy_propagate: aux::type_is<false_type>157 { /* DUMMY BODY */ };158 159 template<class T>160 struct get_copy_propagate<T, void_t<typename T::propagate_on_container_copy_assignment>>161 : aux::type_is<typename T::propagate_on_container_copy_assignment>162 { /* DUMMY BODY */ };163 164 template<class T, class = void>165 struct get_move_propagate: aux::type_is<false_type>166 { /* DUMMY BODY */ };167 168 template<class T>169 struct get_move_propagate<T, void_t<typename T::propagate_on_container_move_assignment>>170 : aux::type_is<typename T::propagate_on_container_move_assignment>171 { /* DUMMY BODY */ };172 173 template<class T, class = void>174 struct get_swap_propagate: aux::type_is<false_type>175 { /* DUMMY BODY */ };176 177 template<class T>178 struct get_swap_propagate<T, void_t<typename T::propagate_on_container_swap>>179 : aux::type_is<typename T::propagate_on_container_swap>180 { /* DUMMY BODY */ };181 182 template<class T, class = void>183 struct get_always_equal: aux::type_is<typename is_empty<T>::type>184 { /* DUMMY BODY */ };185 186 template<class T>187 struct get_always_equal<T, void_t<typename T::is_always_equal>>188 : aux::type_is<typename T::is_always_equal>189 { /* DUMMY BODY */ };190 191 template<class Alloc, class T, class = void>192 struct get_rebind_other193 { /* DUMMY BODY */ };194 195 template<class Alloc, class T>196 struct get_rebind_other<Alloc, T, void_t<typename Alloc::template rebind<T>::other>>197 : aux::type_is<typename Alloc::template rebind<T>::other>198 { /* DUMMY BODY */ };199 200 /* TODO: How am I suppose to do this?!201 template<template<class T, class... Args> class Alloc>202 struct get_rebind_args;203 */204 205 template<class Alloc, class T>206 struct get_rebind_args: aux::type_is<typename get_rebind_other<Alloc, T>::type>207 { /* DUMMY BODY */ };208 }209 127 210 128 template<class Alloc> -
uspace/lib/cpp/include/internal/test/tests.hpp
r17012fcf rbfc972e 252 252 private: 253 253 void test_unique_ptr(); 254 void test_shared_ptr(); 255 void test_weak_ptr(); 256 void test_allocators(); 257 void test_pointers(); 254 258 }; 255 259 } -
uspace/lib/cpp/src/internal/test/memory.cpp
r17012fcf rbfc972e 31 31 #include <internal/test/tests.hpp> 32 32 #include <memory> 33 #include <type_traits> 33 34 #include <utility> 34 35 35 36 namespace std::test 36 37 { 38 namespace aux 39 { 40 struct dummy_pointer1 41 { 42 using element_type = int; 43 using difference_type = bool; 44 45 template<class U> 46 using rebind = unsigned; 47 48 int tag{}; 49 50 static dummy_pointer1 pointer_to(element_type& x) 51 { 52 dummy_pointer1 res; 53 res.tag = x; 54 return res; 55 } 56 }; 57 58 template<class T, class... Args> 59 struct dummy_pointer2 60 { 61 using element_type = signed char; 62 using difference_type = unsigned char; 63 }; 64 65 struct dummy_allocator1 66 { 67 using value_type = int; 68 }; 69 70 struct dummy_allocator2 71 { 72 using value_type = int; 73 using pointer = char*; 74 using const_pointer = const void*; 75 }; 76 } 77 37 78 bool memory_test::run(bool report) 38 79 { … … 42 83 test_unique_ptr(); 43 84 test_shared_ptr(); 85 test_weak_ptr(); 86 test_allocators(); 87 test_pointers(); 44 88 45 89 return end(); … … 110 154 { 111 155 auto ptr2 = ptr1; 112 test_eq("shared_ptr copy pt1", ptr1.use_count(), 2 U);113 test_eq("shared_ptr copy pt2", ptr2.use_count(), 2 U);156 test_eq("shared_ptr copy pt1", ptr1.use_count(), 2L); 157 test_eq("shared_ptr copy pt2", ptr2.use_count(), 2L); 114 158 test_eq("shared_ptr copy no constructor call", mock::copy_constructor_calls, 0U); 115 159 test_eq("shared_ptr not unique", ptr1.unique(), false); 116 160 117 161 auto ptr3 = std::move(ptr2); 118 test_eq("shared_ptr move pt1", ptr1.use_count(), 2U); 119 test_eq("shared_ptr move pt2", ptr3.use_count(), 2U); 162 test_eq("shared_ptr move pt1", ptr1.use_count(), 2L); 163 test_eq("shared_ptr move pt2", ptr3.use_count(), 2L); 164 test_eq("shared_ptr move pt3", ptr2.use_count(), 0L); 120 165 121 166 test_eq("shared_ptr move origin empty", (bool)ptr2, false); … … 125 170 test_eq("shared_ptr original out of scope", mock::destructor_calls, 1U); 126 171 } 172 173 void memory_test::test_weak_ptr() 174 { 175 mock::clear(); 176 { 177 std::weak_ptr<mock> wptr1{}; 178 { 179 auto ptr1 = std::make_shared<mock>(); 180 wptr1 = ptr1; 181 { 182 std::weak_ptr<mock> wptr2 = ptr1; 183 test_eq("weak_ptr shares use count", wptr2.use_count(), 1L); 184 test_eq("weak_ptr not expired", wptr2.expired(), false); 185 186 auto ptr2 = wptr2.lock(); 187 test_eq("locked ptr increases use count", ptr1.use_count(), 2L); 188 } 189 } 190 test_eq("weak_ptr expired after all shared_ptrs die", wptr1.expired(), true); 191 test_eq("shared object destroyed while weak_ptr exists", mock::destructor_calls, 1U); 192 } 193 } 194 195 void memory_test::test_allocators() 196 { 197 using dummy_traits1 = std::allocator_traits<aux::dummy_allocator1>; 198 using dummy_traits2 = std::allocator_traits<aux::dummy_allocator2>; 199 200 /* static_assert(std::is_same_v<typename dummy_traits1::pointer, int*>); */ 201 /* static_assert(std::is_same_v<typename dummy_traits2::pointer, char*>); */ 202 } 203 204 void memory_test::test_pointers() 205 { 206 using dummy_traits1 = std::pointer_traits<aux::dummy_pointer1>; 207 using dummy_traits2 = std::pointer_traits<aux::dummy_pointer2<int, char>>; 208 using int_traits = std::pointer_traits<int*>; 209 210 static_assert(std::is_same_v<typename dummy_traits1::pointer, aux::dummy_pointer1>); 211 static_assert(std::is_same_v<typename dummy_traits1::element_type, int>); 212 static_assert(std::is_same_v<typename dummy_traits1::difference_type, bool>); 213 static_assert(std::is_same_v<typename dummy_traits1::template rebind<long>, unsigned>); 214 215 int x{10}; 216 test_eq("pointer_traits<Ptr>::pointer_to", dummy_traits1::pointer_to(x).tag, 10); 217 218 static_assert(std::is_same_v<typename dummy_traits2::pointer, aux::dummy_pointer2<int, char>>); 219 static_assert(std::is_same_v<typename dummy_traits2::element_type, signed char>); 220 static_assert(std::is_same_v<typename dummy_traits2::difference_type, unsigned char>); 221 222 static_assert(std::is_same_v<typename int_traits::pointer, int*>); 223 static_assert(std::is_same_v<typename int_traits::element_type, int>); 224 static_assert(std::is_same_v<typename int_traits::difference_type, ptrdiff_t>); 225 static_assert(std::is_same_v<typename int_traits::rebind<char>, char*>); 226 } 127 227 }
Note:
See TracChangeset
for help on using the changeset viewer.