1 // -*- C++ -*- 2 // Testing utilities for the rvalue reference. 3 // 4 // Copyright (C) 2005-2019 Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 // 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License along 18 // with this library; see the file COPYING3. If not see 19 // <http://www.gnu.org/licenses/>. 20 // 21 22 #ifndef _GLIBCXX_TESTSUITE_RVALREF_H 23 #define _GLIBCXX_TESTSUITE_RVALREF_H 1 24 25 #include <testsuite_hooks.h> 26 #include <bits/functional_hash.h> 27 28 namespace __gnu_test 29 { 30 // This class is designed to test libstdc++'s template-based rvalue 31 // reference support. It should fail at compile-time if there is an 32 // attempt to copy it. 33 struct rvalstruct 34 { 35 int val; 36 bool valid; 37 rvalstructrvalstruct38 rvalstruct() : val(0), valid(true) 39 { } 40 rvalstructrvalstruct41 rvalstruct(int inval) : val(inval), valid(true) 42 { } 43 44 rvalstruct& 45 operator=(int newval) 46 { 47 val = newval; 48 valid = true; 49 return *this; 50 } 51 52 rvalstruct(const rvalstruct&) = delete; 53 rvalstructrvalstruct54 rvalstruct(rvalstruct&& in) 55 { 56 VERIFY( in.valid == true ); 57 val = in.val; 58 in.valid = false; 59 valid = true; 60 } 61 62 rvalstruct& 63 operator=(const rvalstruct&) = delete; 64 65 rvalstruct& 66 operator=(rvalstruct&& in) 67 { 68 VERIFY( this != &in ); 69 VERIFY( in.valid == true ); 70 val = in.val; 71 in.valid = false; 72 valid = true; 73 return *this; 74 } 75 }; 76 77 inline bool 78 operator==(const rvalstruct& lhs, const rvalstruct& rhs) 79 { return lhs.val == rhs.val; } 80 81 inline bool 82 operator<(const rvalstruct& lhs, const rvalstruct& rhs) 83 { return lhs.val < rhs.val; } 84 85 void swap(rvalstruct & lhs,rvalstruct & rhs)86 swap(rvalstruct& lhs, rvalstruct& rhs) 87 { 88 VERIFY( lhs.valid && rhs.valid ); 89 int temp = lhs.val; 90 lhs.val = rhs.val; 91 rhs.val = temp; 92 } 93 94 // This is a moveable class which copies how many times it is copied. 95 // This is mainly of use in the containers, where the an element inserted 96 // into a container has to be copied once to get there, but we want to check 97 // nothing else is copied. 98 struct copycounter 99 { 100 static int copycount; 101 int val; 102 bool valid; 103 copycountercopycounter104 copycounter() : val(0), valid(true) 105 { } 106 copycountercopycounter107 copycounter(int inval) : val(inval), valid(true) 108 { } 109 copycountercopycounter110 copycounter(const copycounter& in) : val(in.val), valid(true) 111 { 112 VERIFY( in.valid == true ); 113 ++copycount; 114 } 115 copycountercopycounter116 copycounter(copycounter&& in) noexcept 117 { 118 VERIFY( in.valid == true ); 119 val = in.val; 120 in.valid = false; 121 valid = true; 122 } 123 124 copycounter& 125 operator=(int newval) 126 { 127 val = newval; 128 valid = true; 129 return *this; 130 } 131 132 bool 133 operator=(const copycounter& in) 134 { 135 VERIFY( in.valid == true ); 136 ++copycount; 137 val = in.val; 138 valid = true; 139 return true; 140 } 141 142 copycounter& 143 operator=(copycounter&& in) 144 { 145 VERIFY(in.valid == true); 146 val = in.val; 147 in.valid = false; 148 valid = true; 149 return *this; 150 } 151 ~copycountercopycounter152 ~copycounter() noexcept 153 { valid = false; } 154 }; 155 156 int copycounter::copycount = 0; 157 158 inline bool 159 operator==(const copycounter& lhs, const copycounter& rhs) 160 { return lhs.val == rhs.val; } 161 162 inline bool 163 operator<(const copycounter& lhs, const copycounter& rhs) 164 { return lhs.val < rhs.val; } 165 166 inline void swap(copycounter & lhs,copycounter & rhs)167 swap(copycounter& lhs, copycounter& rhs) 168 { 169 VERIFY( lhs.valid && rhs.valid ); 170 int temp = lhs.val; 171 lhs.val = rhs.val; 172 rhs.val = temp; 173 } 174 175 // In the occasion of libstdc++/48038. 176 struct rvalstruct_compare_by_value 177 { 178 int val; 179 bool ok; 180 rvalstruct_compare_by_valuervalstruct_compare_by_value181 rvalstruct_compare_by_value(int v) 182 : val(v), ok(true) { } 183 rvalstruct_compare_by_valuervalstruct_compare_by_value184 rvalstruct_compare_by_value(const rvalstruct_compare_by_value& rh) 185 : val(rh.val), ok(rh.ok) 186 { 187 VERIFY(rh.ok); 188 } 189 190 rvalstruct_compare_by_value& 191 operator=(const rvalstruct_compare_by_value& rh) 192 { 193 VERIFY( rh.ok ); 194 val = rh.val; 195 ok = rh.ok; 196 return *this; 197 } 198 rvalstruct_compare_by_valuervalstruct_compare_by_value199 rvalstruct_compare_by_value(rvalstruct_compare_by_value&& rh) 200 : val(rh.val), ok(rh.ok) 201 { 202 VERIFY( rh.ok ); 203 rh.ok = false; 204 } 205 206 rvalstruct_compare_by_value& 207 operator=(rvalstruct_compare_by_value&& rh) 208 { 209 VERIFY( rh.ok ); 210 val = rh.val; 211 ok = rh.ok; 212 rh.ok = false; 213 return *this; 214 } 215 }; 216 217 inline bool 218 operator<(rvalstruct_compare_by_value lh, 219 rvalstruct_compare_by_value rh) 220 { 221 VERIFY( rh.ok ); 222 VERIFY( lh.ok ); 223 return lh.val < rh.val; 224 } 225 226 inline bool order(rvalstruct_compare_by_value lh,rvalstruct_compare_by_value rh)227 order(rvalstruct_compare_by_value lh, 228 rvalstruct_compare_by_value rh) 229 { 230 VERIFY( rh.ok ); 231 VERIFY( lh.ok ); 232 return lh.val < rh.val; 233 } 234 235 struct throwing_move_constructor 236 { 237 throwing_move_constructor() = default; 238 throwing_move_constructorthrowing_move_constructor239 throwing_move_constructor(throwing_move_constructor&&) 240 { throw 1; } 241 242 throwing_move_constructor(const throwing_move_constructor&) = default; 243 244 throwing_move_constructor& 245 operator=(const throwing_move_constructor&) = default; 246 }; 247 248 } // namespace __gnu_test 249 250 namespace std 251 { 252 /// std::hash specialization for __gnu_test::rvalstruct. 253 template<> 254 struct hash<__gnu_test::rvalstruct> 255 { 256 typedef size_t result_type; 257 typedef __gnu_test::rvalstruct argument_type; 258 259 size_t 260 operator()(const __gnu_test::rvalstruct& __rvs) const 261 { return __rvs.val; } 262 }; 263 } 264 265 #endif // _GLIBCXX_TESTSUITE_TR1_H 266