1// Copyright (C) 2010-2015 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 29namespace __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<typename _Tp1, typename _Tp2> 57 struct generate_unique<std::pair<_Tp1, _Tp2> > 58 { 59 typedef _Tp1 first_type; 60 typedef _Tp2 second_type; 61 typedef std::pair<_Tp1, _Tp2> pair_type; 62 63 pair_type build() 64 { 65 static first_type _S_1; 66 static second_type _S_2; 67 ++_S_1; 68 ++_S_2; 69 return pair_type(_S_1, _S_2); 70 } 71 }; 72 73 // Check that invalid range of pointers is detected 74 template<typename _Tp> 75 void 76 check_assign1() 77 { 78 bool test __attribute__((unused)) = true; 79 80 typedef _Tp cont_type; 81 typedef typename cont_type::value_type cont_val_type; 82 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 83 typedef std::vector<val_type> vector_type; 84 85 generate_unique<val_type> gu; 86 87 vector_type v; 88 for (int i = 0; i != 5; ++i) 89 v.push_back(gu.build()); 90 VERIFY(v.size() == 5); 91 92 const val_type* first = &v.front() + 1; 93 const val_type* last = first + 2; 94 95 cont_type c1; 96 c1.assign(first, last); 97 VERIFY(c1.size() == 2); 98 99 cont_type c2; 100 c2.assign(last, first); // Expected failure 101 } 102 103 // Check that invalid range of debug random iterators is detected 104 template<typename _Tp> 105 void 106 check_assign2() 107 { 108 bool test __attribute__((unused)) = true; 109 110 typedef _Tp cont_type; 111 typedef typename cont_type::value_type cont_val_type; 112 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 113 typedef std::vector<val_type> vector_type; 114 115 generate_unique<val_type> gu; 116 117 vector_type v; 118 for (int i = 0; i != 5; ++i) 119 v.push_back(gu.build()); 120 VERIFY(v.size() == 5); 121 122 typename vector_type::iterator first = v.begin() + 1; 123 typename vector_type::iterator last = first + 2; 124 cont_type c1; 125 c1.assign(first, last); 126 VERIFY(c1.size() == 2); 127 128 cont_type c2; 129 c2.assign(last, first); // Expected failure 130 } 131 132 // Check that invalid range of debug not random iterators is detected 133 template<typename _Tp> 134 void 135 check_assign3() 136 { 137 bool test __attribute__((unused)) = true; 138 139 typedef _Tp cont_type; 140 typedef typename cont_type::value_type cont_val_type; 141 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 142 typedef std::list<val_type> list_type; 143 144 generate_unique<val_type> gu; 145 146 list_type l; 147 for (int i = 0; i != 5; ++i) 148 l.push_back(gu.build()); 149 VERIFY(l.size() == 5); 150 151 typename list_type::iterator first = l.begin(); ++first; 152 typename list_type::iterator last = first; ++last; ++last; 153 cont_type c1; 154 c1.assign(first, last); 155 VERIFY(c1.size() == 2); 156 157 cont_type c2; 158 c2.assign(last, first); // Expected failure 159 } 160 161 // Check that invalid range of pointers is detected 162 template<typename _Tp> 163 void 164 check_construct1() 165 { 166 bool test __attribute__((unused)) = true; 167 168 typedef _Tp cont_type; 169 typedef typename cont_type::value_type cont_val_type; 170 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 171 typedef std::vector<val_type> vector_type; 172 173 generate_unique<val_type> gu; 174 175 vector_type v; 176 for (int i = 0; i != 5; ++i) 177 v.push_back(gu.build()); 178 VERIFY(v.size() == 5); 179 180 val_type *first = &v.front() + 1; 181 val_type *last = first + 2; 182 183 cont_type c(last, first); // Expected failure 184 } 185 186 // Check that invalid range of debug random iterators is detected 187 template<typename _Tp> 188 void 189 check_construct2() 190 { 191 bool test __attribute__((unused)) = true; 192 193 typedef _Tp cont_type; 194 typedef typename cont_type::value_type cont_val_type; 195 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 196 typedef std::vector<val_type> vector_type; 197 198 generate_unique<val_type> gu; 199 200 vector_type v; 201 for (int i = 0; i != 5; ++i) 202 v.push_back(gu.build()); 203 VERIFY(v.size() == 5); 204 205 typename vector_type::iterator first = v.begin() + 1; 206 typename vector_type::iterator last = first + 2; 207 208 cont_type c(last, first); // Expected failure 209 } 210 211 // Check that invalid range of debug not random iterators is detected 212 template<typename _Tp> 213 void 214 check_construct3() 215 { 216 bool test __attribute__((unused)) = true; 217 218 typedef _Tp cont_type; 219 typedef typename cont_type::value_type cont_val_type; 220 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 221 typedef std::list<val_type> list_type; 222 223 generate_unique<val_type> gu; 224 225 list_type l; 226 for (int i = 0; i != 5; ++i) 227 l.push_back(gu.build()); 228 VERIFY(l.size() == 5); 229 230 typename list_type::iterator first = l.begin(); ++first; 231 typename list_type::iterator last = first; ++last; ++last; 232 233 cont_type c(last, first); // Expected failure 234 } 235 236 template <typename _Cont> 237 struct InsertRangeHelper 238 { 239 template <typename _It> 240 static void 241 Insert(_Cont& cont, _It first, _It last) 242 { cont.insert(first, last); } 243 }; 244 245 template <typename _Cont> 246 struct InsertRangeHelperAux 247 { 248 template <typename _It> 249 static void 250 Insert(_Cont& cont, _It first, _It last) 251 { cont.insert(cont.begin(), first, last); } 252 }; 253 254 template <typename _Tp1, typename _Tp2> 255 struct InsertRangeHelper<std::vector<_Tp1, _Tp2> > 256 : InsertRangeHelperAux<std::vector<_Tp1, _Tp2> > 257 { }; 258 259 template <typename _Tp1, typename _Tp2> 260 struct InsertRangeHelper<std::deque<_Tp1, _Tp2> > 261 : InsertRangeHelperAux<std::deque<_Tp1, _Tp2> > 262 { }; 263 264 template <typename _Tp1, typename _Tp2> 265 struct InsertRangeHelper<std::list<_Tp1, _Tp2> > 266 : InsertRangeHelperAux<std::list<_Tp1, _Tp2> > 267 { }; 268 269#ifndef _GLIBCXX_DEBUG 270 template <typename _Tp1, typename _Tp2> 271 struct InsertRangeHelper<__gnu_debug::vector<_Tp1, _Tp2> > 272 : InsertRangeHelperAux<__gnu_debug::vector<_Tp1, _Tp2> > 273 { }; 274 275 template <typename _Tp1, typename _Tp2> 276 struct InsertRangeHelper<__gnu_debug::deque<_Tp1, _Tp2> > 277 : InsertRangeHelperAux<__gnu_debug::deque<_Tp1, _Tp2> > 278 { }; 279 280 template <typename _Tp1, typename _Tp2> 281 struct InsertRangeHelper<__gnu_debug::list<_Tp1, _Tp2> > 282 : InsertRangeHelperAux<__gnu_debug::list<_Tp1, _Tp2> > 283 { }; 284#endif 285 286 template<typename _Tp> 287 void 288 check_insert1() 289 { 290 bool test __attribute__((unused)) = true; 291 292 typedef _Tp cont_type; 293 typedef typename cont_type::value_type cont_val_type; 294 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 295 typedef std::vector<val_type> vector_type; 296 297 generate_unique<val_type> gu; 298 299 vector_type v; 300 for (int i = 0; i != 5; ++i) 301 v.push_back(gu.build()); 302 VERIFY(v.size() == 5); 303 304 const val_type* first = &v.front() + 1; 305 const val_type* last = first + 2; 306 307 cont_type c1; 308 InsertRangeHelper<cont_type>::Insert(c1, first, last); 309 VERIFY(c1.size() == 2); 310 311 cont_type c2; 312 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 313 } 314 315 template<typename _Tp> 316 void 317 check_insert2() 318 { 319 bool test __attribute__((unused)) = true; 320 321 typedef _Tp cont_type; 322 typedef typename cont_type::value_type cont_val_type; 323 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 324 typedef std::vector<val_type> vector_type; 325 326 generate_unique<val_type> gu; 327 328 vector_type v; 329 for (int i = 0; i != 5; ++i) 330 v.push_back(gu.build()); 331 VERIFY(v.size() == 5); 332 333 typename vector_type::iterator first = v.begin() + 1; 334 typename vector_type::iterator last = first + 2; 335 336 cont_type c1; 337 InsertRangeHelper<cont_type>::Insert(c1, first, last); 338 VERIFY(c1.size() == 2); 339 340 cont_type c2; 341 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 342 } 343 344 template<typename _Tp> 345 void 346 check_insert3() 347 { 348 bool test __attribute__((unused)) = true; 349 350 typedef _Tp cont_type; 351 typedef typename cont_type::value_type cont_val_type; 352 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 353 typedef std::list<val_type> list_type; 354 355 generate_unique<val_type> gu; 356 357 list_type l; 358 for (int i = 0; i != 5; ++i) 359 l.push_back(gu.build()); 360 VERIFY(l.size() == 5); 361 362 typename list_type::iterator first = l.begin(); ++first; 363 typename list_type::iterator last = first; ++last; ++last; 364 365 cont_type c1; 366 InsertRangeHelper<cont_type>::Insert(c1, first, last); 367 VERIFY(c1.size() == 2); 368 369 cont_type c2; 370 InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure 371 } 372 373 template<typename _Tp> 374 void 375 check_insert4() 376 { 377 bool test __attribute__((unused)) = true; 378 379 typedef _Tp cont_type; 380 typedef typename cont_type::value_type cont_val_type; 381 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 382 typedef std::list<val_type> list_type; 383 384 generate_unique<val_type> gu; 385 386 list_type l; 387 for (int i = 0; i != 5; ++i) 388 l.push_back(gu.build()); 389 VERIFY(l.size() == 5); 390 391 typename list_type::iterator first = l.begin(); ++first; 392 typename list_type::iterator last = first; ++last; ++last; 393 394 cont_type c1; 395 InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end()); 396 VERIFY(c1.size() == 5); 397 398 c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. 399 } 400 401 template<typename _Tp> 402 void use_invalid_iterator() 403 { 404 bool test __attribute__((unused)) = true; 405 406 typedef _Tp cont_type; 407 typedef typename cont_type::value_type cont_val_type; 408 typedef typename CopyableValueType<cont_val_type>::value_type val_type; 409 generate_unique<val_type> gu; 410 411 cont_type c; 412 for (size_t i = 0; i != 5; ++i) 413 c.insert(gu.build()); 414 415 typename cont_type::iterator it = c.begin(); 416 cont_val_type val = *it; 417 c.clear(); 418 VERIFY( *it == val ); 419 } 420} 421 422