1 // -*- C++ -*- 2 // Testing utilities for the rvalue reference. 3 // 4 // Copyright (C) 2005-2013 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 bool test __attribute__((unused)) = true; 57 VERIFY( in.valid == true ); 58 val = in.val; 59 in.valid = false; 60 valid = true; 61 } 62 63 rvalstruct& 64 operator=(const rvalstruct&) = delete; 65 66 rvalstruct& 67 operator=(rvalstruct&& in) 68 { 69 bool test __attribute__((unused)) = true; 70 VERIFY( this != &in ); 71 VERIFY( in.valid == true ); 72 val = in.val; 73 in.valid = false; 74 valid = true; 75 return *this; 76 } 77 }; 78 79 inline bool 80 operator==(const rvalstruct& lhs, const rvalstruct& rhs) 81 { return lhs.val == rhs.val; } 82 83 inline bool 84 operator<(const rvalstruct& lhs, const rvalstruct& rhs) 85 { return lhs.val < rhs.val; } 86 87 void swap(rvalstruct & lhs,rvalstruct & rhs)88 swap(rvalstruct& lhs, rvalstruct& rhs) 89 { 90 bool test __attribute__((unused)) = true; 91 VERIFY( lhs.valid && rhs.valid ); 92 int temp = lhs.val; 93 lhs.val = rhs.val; 94 rhs.val = temp; 95 } 96 97 // This is a moveable class which copies how many times it is copied. 98 // This is mainly of use in the containers, where the an element inserted 99 // into a container has to be copied once to get there, but we want to check 100 // nothing else is copied. 101 struct copycounter 102 { 103 static int copycount; 104 int val; 105 bool valid; 106 copycountercopycounter107 copycounter() : val(0), valid(true) 108 { } 109 copycountercopycounter110 copycounter(int inval) : val(inval), valid(true) 111 { } 112 copycountercopycounter113 copycounter(const copycounter& in) : val(in.val), valid(true) 114 { 115 bool test __attribute__((unused)) = true; 116 VERIFY( in.valid == true ); 117 ++copycount; 118 } 119 copycountercopycounter120 copycounter(copycounter&& in) noexcept 121 { 122 bool test __attribute__((unused)) = true; 123 VERIFY( in.valid == true ); 124 val = in.val; 125 in.valid = false; 126 valid = true; 127 } 128 129 copycounter& 130 operator=(int newval) 131 { 132 val = newval; 133 valid = true; 134 return *this; 135 } 136 137 bool 138 operator=(const copycounter& in) 139 { 140 bool test __attribute__((unused)) = true; 141 VERIFY( in.valid == true ); 142 ++copycount; 143 val = in.val; 144 valid = true; 145 return true; 146 } 147 148 copycounter& 149 operator=(copycounter&& in) 150 { 151 bool test __attribute__((unused)) = true; 152 VERIFY(in.valid == true); 153 val = in.val; 154 in.valid = false; 155 valid = true; 156 return *this; 157 } 158 ~copycountercopycounter159 ~copycounter() noexcept 160 { valid = false; } 161 }; 162 163 int copycounter::copycount = 0; 164 165 inline bool 166 operator==(const copycounter& lhs, const copycounter& rhs) 167 { return lhs.val == rhs.val; } 168 169 inline bool 170 operator<(const copycounter& lhs, const copycounter& rhs) 171 { return lhs.val < rhs.val; } 172 173 inline void swap(copycounter & lhs,copycounter & rhs)174 swap(copycounter& lhs, copycounter& rhs) 175 { 176 bool test __attribute__((unused)) = true; 177 VERIFY( lhs.valid && rhs.valid ); 178 int temp = lhs.val; 179 lhs.val = rhs.val; 180 rhs.val = temp; 181 } 182 183 // In the occasion of libstdc++/48038. 184 struct rvalstruct_compare_by_value 185 { 186 int val; 187 bool ok; 188 rvalstruct_compare_by_valuervalstruct_compare_by_value189 rvalstruct_compare_by_value(int v) 190 : val(v), ok(true) { } 191 rvalstruct_compare_by_valuervalstruct_compare_by_value192 rvalstruct_compare_by_value(const rvalstruct_compare_by_value& rh) 193 : val(rh.val), ok(rh.ok) 194 { 195 bool test __attribute__((unused)) = true; 196 VERIFY(rh.ok); 197 } 198 199 rvalstruct_compare_by_value& 200 operator=(const rvalstruct_compare_by_value& rh) 201 { 202 bool test __attribute__((unused)) = true; 203 VERIFY( rh.ok ); 204 val = rh.val; 205 ok = rh.ok; 206 return *this; 207 } 208 rvalstruct_compare_by_valuervalstruct_compare_by_value209 rvalstruct_compare_by_value(rvalstruct_compare_by_value&& rh) 210 : val(rh.val), ok(rh.ok) 211 { 212 bool test __attribute__((unused)) = true; 213 VERIFY( rh.ok ); 214 rh.ok = false; 215 } 216 217 rvalstruct_compare_by_value& 218 operator=(rvalstruct_compare_by_value&& rh) 219 { 220 bool test __attribute__((unused)) = true; 221 VERIFY( rh.ok ); 222 val = rh.val; 223 ok = rh.ok; 224 rh.ok = false; 225 return *this; 226 } 227 }; 228 229 inline bool 230 operator<(rvalstruct_compare_by_value lh, 231 rvalstruct_compare_by_value rh) 232 { 233 bool test __attribute__((unused)) = true; 234 VERIFY( rh.ok ); 235 VERIFY( lh.ok ); 236 return lh.val < rh.val; 237 } 238 239 inline bool order(rvalstruct_compare_by_value lh,rvalstruct_compare_by_value rh)240 order(rvalstruct_compare_by_value lh, 241 rvalstruct_compare_by_value rh) 242 { 243 bool test __attribute__((unused)) = true; 244 VERIFY( rh.ok ); 245 VERIFY( lh.ok ); 246 return lh.val < rh.val; 247 } 248 249 struct throwing_move_constructor 250 { 251 throwing_move_constructor() = default; 252 throwing_move_constructorthrowing_move_constructor253 throwing_move_constructor(throwing_move_constructor&&) 254 { throw 1; } 255 256 throwing_move_constructor(const throwing_move_constructor&) = default; 257 258 throwing_move_constructor& 259 operator=(const throwing_move_constructor&) = default; 260 }; 261 262 } // namespace __gnu_test 263 264 namespace std 265 { 266 /// std::hash specialization for __gnu_test::rvalstruct. 267 template<> 268 struct hash<__gnu_test::rvalstruct> 269 { 270 typedef size_t result_type; 271 typedef __gnu_test::rvalstruct argument_type; 272 273 size_t 274 operator()(const __gnu_test::rvalstruct& __rvs) const 275 { return __rvs.val; } 276 }; 277 } 278 279 #endif // _GLIBCXX_TESTSUITE_TR1_H 280