1 // Copyright (C) 2010-2021 Free Software Foundation, Inc. 2 // 3 // This file is part of the GNU ISO C++ Library. This library is free 4 // software; you can redistribute it and/or modify it under the 5 // terms of the GNU General Public License as published by the 6 // Free Software Foundation; either version 3, or (at your option) 7 // any later version. 8 // 9 // This library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License along 15 // with this library; see the file COPYING3. If not see 16 // <http://www.gnu.org/licenses/>. 17 // 18 19 #include <vector> 20 #include <deque> 21 #include <list> 22 #ifndef _GLIBCXX_DEBUG 23 # include <debug/vector> 24 # include <debug/deque> 25 # include <debug/list> 26 #endif 27 #include <testsuite_hooks.h> 28 29 namespace __gnu_test 30 { 31 template<typename _Tp> 32 struct CopyableValueType 33 { 34 typedef _Tp value_type; 35 }; 36 37 template<typename _Tp1, typename _Tp2> 38 struct CopyableValueType<std::pair<const _Tp1, _Tp2> > 39 { 40 typedef std::pair<_Tp1, _Tp2> value_type; 41 }; 42 43 template<typename _Tp> 44 struct generate_unique 45 { 46 typedef _Tp value_type; 47 48 value_type build() 49 { 50 static value_type _S_; 51 ++_S_; 52 return _S_; 53 } 54 }; 55 56 template<> 57 struct generate_unique<bool> 58 { 59 typedef bool value_type; 60 61 value_type build() 62 { 63 static value_type _S_; 64 _S_ = !_S_; 65 return _S_; 66 } 67 }; 68 69 template<typename _Tp1, typename _Tp2> 70 struct generate_unique<std::pair<_Tp1, _Tp2> > 71 { 72 typedef _Tp1 first_type; 73 typedef _Tp2 second_type; 74 typedef std::pair<_Tp1, _Tp2> pair_type; 75 76 pair_type build() 77 { 78 static first_type _S_1; 79 static second_type _S_2; 80 ++_S_1; 81 ++_S_2; 82 return pair_type(_S_1, _S_2); 83 } 84 }; 85 86 // Check that invalid range of pointers is detected 87 template<typename _Tp> 88 void 89 check_assign1() 90 { 91 typedef _Tp cont_type; 92 typedef typename cont_type::value_type cont_val_type; 93 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 94 typedef std::vector<val_type> vector_type; 95 96 generate_unique<val_type> gu; 97 98 vector_type v; 99 for (int i = 0; i != 5; ++i) 100 v.push_back(gu.build()); 101 VERIFY(v.size() == 5); 102 103 const val_type* first = &v.front() + 1; 104 const val_type* last = first + 2; 105 106 cont_type c1; 107 c1.assign(first, last); 108 VERIFY(c1.size() == 2); 109 110 cont_type c2; 111 c2.assign(last, first); // Expected failure 112 } 113 114 // Check that invalid range of debug random iterators is detected 115 template<typename _Tp> 116 void 117 check_assign2() 118 { 119 typedef _Tp cont_type; 120 typedef typename cont_type::value_type cont_val_type; 121 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 122 typedef std::vector<val_type> vector_type; 123 124 generate_unique<val_type> gu; 125 126 vector_type v; 127 for (int i = 0; i != 5; ++i) 128 v.push_back(gu.build()); 129 VERIFY(v.size() == 5); 130 131 typename vector_type::iterator first = v.begin() + 1; 132 typename vector_type::iterator last = first + 2; 133 cont_type c1; 134 c1.assign(first, last); 135 VERIFY(c1.size() == 2); 136 137 cont_type c2; 138 c2.assign(last, first); // Expected failure 139 } 140 141 // Check that invalid range of debug not random iterators is detected 142 template<typename _Tp> 143 void 144 check_assign3() 145 { 146 typedef _Tp cont_type; 147 typedef typename cont_type::value_type cont_val_type; 148 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 149 typedef std::list<val_type> list_type; 150 151 generate_unique<val_type> gu; 152 153 list_type l; 154 for (int i = 0; i != 5; ++i) 155 l.push_back(gu.build()); 156 VERIFY(l.size() == 5); 157 158 typename list_type::iterator first = l.begin(); ++first; 159 typename list_type::iterator last = first; ++last; ++last; 160 cont_type c1; 161 c1.assign(first, last); 162 VERIFY(c1.size() == 2); 163 164 cont_type c2; 165 c2.assign(last, first); // Expected failure 166 } 167 168 // Check that invalid range of pointers is detected 169 template<typename _Tp> 170 void 171 check_construct1() 172 { 173 typedef _Tp cont_type; 174 typedef typename cont_type::value_type cont_val_type; 175 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 176 typedef std::vector<val_type> vector_type; 177 178 generate_unique<val_type> gu; 179 180 vector_type v; 181 for (int i = 0; i != 5; ++i) 182 v.push_back(gu.build()); 183 VERIFY(v.size() == 5); 184 185 val_type *first = &v.front() + 1; 186 val_type *last = first + 2; 187 188 cont_type c(last, first); // Expected failure 189 } 190 191 // Check that invalid range of debug random iterators is detected 192 template<typename _Tp> 193 void 194 check_construct2() 195 { 196 typedef _Tp cont_type; 197 typedef typename cont_type::value_type cont_val_type; 198 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 199 typedef std::vector<val_type> vector_type; 200 201 generate_unique<val_type> gu; 202 203 vector_type v; 204 for (int i = 0; i != 5; ++i) 205 v.push_back(gu.build()); 206 VERIFY(v.size() == 5); 207 208 typename vector_type::iterator first = v.begin() + 1; 209 typename vector_type::iterator last = first + 2; 210 211 cont_type c(last, first); // Expected failure 212 } 213 214 // Check that invalid range of debug not random iterators is detected 215 template<typename _Tp> 216 void 217 check_construct3() 218 { 219 typedef _Tp cont_type; 220 typedef typename cont_type::value_type cont_val_type; 221 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 222 typedef std::list<val_type> list_type; 223 224 generate_unique<val_type> gu; 225 226 list_type l; 227 for (int i = 0; i != 5; ++i) 228 l.push_back(gu.build()); 229 VERIFY(l.size() == 5); 230 231 typename list_type::iterator first = l.begin(); ++first; 232 typename list_type::iterator last = first; ++last; ++last; 233 234 cont_type c(last, first); // Expected failure 235 } 236 237 template <typename _Cont> 238 struct InsertRangeHelper 239 { 240 template <typename _It> 241 static void 242 Insert(_Cont& cont, _It first, _It last) 243 { cont.insert(first, last); } 244 }; 245 246 template <typename _Cont> 247 struct InsertRangeHelperAux 248 { 249 template <typename _It> 250 static void 251 Insert(_Cont& cont, _It first, _It last) 252 { cont.insert(cont.begin(), first, last); } 253 }; 254 255 template <typename _Tp1, typename _Tp2> 256 struct InsertRangeHelper<std::vector<_Tp1, _Tp2> > 257 : InsertRangeHelperAux<std::vector<_Tp1, _Tp2> > 258 { }; 259 260 template <typename _Tp1, typename _Tp2> 261 struct InsertRangeHelper<std::deque<_Tp1, _Tp2> > 262 : InsertRangeHelperAux<std::deque<_Tp1, _Tp2> > 263 { }; 264 265 template <typename _Tp1, typename _Tp2> 266 struct InsertRangeHelper<std::list<_Tp1, _Tp2> > 267 : InsertRangeHelperAux<std::list<_Tp1, _Tp2> > 268 { }; 269 270 #ifndef _GLIBCXX_DEBUG 271 template <typename _Tp1, typename _Tp2> 272 struct InsertRangeHelper<__gnu_debug::vector<_Tp1, _Tp2> > 273 : InsertRangeHelperAux<__gnu_debug::vector<_Tp1, _Tp2> > 274 { }; 275 276 template <typename _Tp1, typename _Tp2> 277 struct InsertRangeHelper<__gnu_debug::deque<_Tp1, _Tp2> > 278 : InsertRangeHelperAux<__gnu_debug::deque<_Tp1, _Tp2> > 279 { }; 280 281 template <typename _Tp1, typename _Tp2> 282 struct InsertRangeHelper<__gnu_debug::list<_Tp1, _Tp2> > 283 : InsertRangeHelperAux<__gnu_debug::list<_Tp1, _Tp2> > 284 { }; 285 #endif 286 287 template<typename _Tp> 288 void 289 check_insert1() 290 { 291 typedef _Tp cont_type; 292 typedef typename cont_type::value_type cont_val_type; 293 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 294 typedef std::vector<val_type> vector_type; 295 296 generate_unique<val_type> gu; 297 298 vector_type v; 299 for (int i = 0; i != 5; ++i) 300 v.push_back(gu.build()); 301 VERIFY(v.size() == 5); 302 303 const val_type* first = &v.front() + 1; 304 const val_type* last = first + 2; 305 306 cont_type c1; 307 InsertRangeHelper<cont_type>::Insert(c1, first, last); 308 VERIFY(c1.size() == 2); 309 310 cont_type c2; 311 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 312 } 313 314 template<typename _Tp> 315 void 316 check_insert2() 317 { 318 typedef _Tp cont_type; 319 typedef typename cont_type::value_type cont_val_type; 320 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 321 typedef std::vector<val_type> vector_type; 322 323 generate_unique<val_type> gu; 324 325 vector_type v; 326 for (int i = 0; i != 5; ++i) 327 v.push_back(gu.build()); 328 VERIFY(v.size() == 5); 329 330 typename vector_type::iterator first = v.begin() + 1; 331 typename vector_type::iterator last = first + 2; 332 333 cont_type c1; 334 InsertRangeHelper<cont_type>::Insert(c1, first, last); 335 VERIFY(c1.size() == 2); 336 337 cont_type c2; 338 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 339 } 340 341 template<typename _Tp> 342 void 343 check_insert3() 344 { 345 typedef _Tp cont_type; 346 typedef typename cont_type::value_type cont_val_type; 347 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 348 typedef std::list<val_type> list_type; 349 350 generate_unique<val_type> gu; 351 352 list_type l; 353 for (int i = 0; i != 5; ++i) 354 l.push_back(gu.build()); 355 VERIFY(l.size() == 5); 356 357 typename list_type::iterator first = l.begin(); ++first; 358 typename list_type::iterator last = first; ++last; ++last; 359 360 cont_type c1; 361 InsertRangeHelper<cont_type>::Insert(c1, first, last); 362 VERIFY(c1.size() == 2); 363 364 cont_type c2; 365 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 366 } 367 368 template<typename _Tp> 369 void 370 check_insert4() 371 { 372 typedef _Tp cont_type; 373 typedef typename cont_type::value_type cont_val_type; 374 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 375 typedef std::list<val_type> list_type; 376 377 generate_unique<val_type> gu; 378 379 list_type l; 380 for (int i = 0; i != 5; ++i) 381 l.push_back(gu.build()); 382 VERIFY(l.size() == 5); 383 384 typename list_type::iterator first = l.begin(); ++first; 385 typename list_type::iterator last = first; ++last; ++last; 386 387 cont_type c1; 388 InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end()); 389 VERIFY(c1.size() == 5); 390 391 c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. 392 } 393 394 template<typename _Tp> 395 void use_invalid_iterator() 396 { 397 typedef _Tp cont_type; 398 typedef typename cont_type::value_type cont_val_type; 399 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 400 generate_unique<val_type> gu; 401 402 cont_type c; 403 for (size_t i = 0; i != 5; ++i) 404 c.insert(gu.build()); 405 406 typename cont_type::iterator it = c.begin(); 407 cont_val_type val = *it; 408 c.clear(); 409 VERIFY( *it == val ); 410 } 411 } 412 413