1// -*- C++ -*- 2// Testing utilities for the rvalue reference. 3// 4// Copyright (C) 2005-2015 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 28namespace __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 38 rvalstruct() : val(0), valid(true) 39 { } 40 41 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 54 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 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 107 copycounter() : val(0), valid(true) 108 { } 109 110 copycounter(int inval) : val(inval), valid(true) 111 { } 112 113 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 120 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 159 ~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 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 189 rvalstruct_compare_by_value(int v) 190 : val(v), ok(true) { } 191 192 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 209 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 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 253 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 264namespace 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