// Copyright (C) 2010-2017 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . // #include #include #include #ifndef _GLIBCXX_DEBUG # include # include # include #endif #include namespace __gnu_test { template struct CopyableValueType { typedef _Tp value_type; }; template struct CopyableValueType > { typedef std::pair<_Tp1, _Tp2> value_type; }; template struct generate_unique { typedef _Tp value_type; value_type build() { static value_type _S_; ++_S_; return _S_; } }; template<> struct generate_unique { typedef bool value_type; value_type build() { static value_type _S_; _S_ = !_S_; return _S_; } }; template struct generate_unique > { typedef _Tp1 first_type; typedef _Tp2 second_type; typedef std::pair<_Tp1, _Tp2> pair_type; pair_type build() { static first_type _S_1; static second_type _S_2; ++_S_1; ++_S_2; return pair_type(_S_1, _S_2); } }; // Check that invalid range of pointers is detected template void check_assign1() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); const val_type* first = &v.front() + 1; const val_type* last = first + 2; cont_type c1; c1.assign(first, last); VERIFY(c1.size() == 2); cont_type c2; c2.assign(last, first); // Expected failure } // Check that invalid range of debug random iterators is detected template void check_assign2() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); typename vector_type::iterator first = v.begin() + 1; typename vector_type::iterator last = first + 2; cont_type c1; c1.assign(first, last); VERIFY(c1.size() == 2); cont_type c2; c2.assign(last, first); // Expected failure } // Check that invalid range of debug not random iterators is detected template void check_assign3() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::list list_type; generate_unique gu; list_type l; for (int i = 0; i != 5; ++i) l.push_back(gu.build()); VERIFY(l.size() == 5); typename list_type::iterator first = l.begin(); ++first; typename list_type::iterator last = first; ++last; ++last; cont_type c1; c1.assign(first, last); VERIFY(c1.size() == 2); cont_type c2; c2.assign(last, first); // Expected failure } // Check that invalid range of pointers is detected template void check_construct1() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); val_type *first = &v.front() + 1; val_type *last = first + 2; cont_type c(last, first); // Expected failure } // Check that invalid range of debug random iterators is detected template void check_construct2() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); typename vector_type::iterator first = v.begin() + 1; typename vector_type::iterator last = first + 2; cont_type c(last, first); // Expected failure } // Check that invalid range of debug not random iterators is detected template void check_construct3() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::list list_type; generate_unique gu; list_type l; for (int i = 0; i != 5; ++i) l.push_back(gu.build()); VERIFY(l.size() == 5); typename list_type::iterator first = l.begin(); ++first; typename list_type::iterator last = first; ++last; ++last; cont_type c(last, first); // Expected failure } template struct InsertRangeHelper { template static void Insert(_Cont& cont, _It first, _It last) { cont.insert(first, last); } }; template struct InsertRangeHelperAux { template static void Insert(_Cont& cont, _It first, _It last) { cont.insert(cont.begin(), first, last); } }; template struct InsertRangeHelper > : InsertRangeHelperAux > { }; template struct InsertRangeHelper > : InsertRangeHelperAux > { }; template struct InsertRangeHelper > : InsertRangeHelperAux > { }; #ifndef _GLIBCXX_DEBUG template struct InsertRangeHelper<__gnu_debug::vector<_Tp1, _Tp2> > : InsertRangeHelperAux<__gnu_debug::vector<_Tp1, _Tp2> > { }; template struct InsertRangeHelper<__gnu_debug::deque<_Tp1, _Tp2> > : InsertRangeHelperAux<__gnu_debug::deque<_Tp1, _Tp2> > { }; template struct InsertRangeHelper<__gnu_debug::list<_Tp1, _Tp2> > : InsertRangeHelperAux<__gnu_debug::list<_Tp1, _Tp2> > { }; #endif template void check_insert1() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); const val_type* first = &v.front() + 1; const val_type* last = first + 2; cont_type c1; InsertRangeHelper::Insert(c1, first, last); VERIFY(c1.size() == 2); cont_type c2; InsertRangeHelper::Insert(c2, last, first); // Expected failure } template void check_insert2() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::vector vector_type; generate_unique gu; vector_type v; for (int i = 0; i != 5; ++i) v.push_back(gu.build()); VERIFY(v.size() == 5); typename vector_type::iterator first = v.begin() + 1; typename vector_type::iterator last = first + 2; cont_type c1; InsertRangeHelper::Insert(c1, first, last); VERIFY(c1.size() == 2); cont_type c2; InsertRangeHelper::Insert(c2, last, first); // Expected failure } template void check_insert3() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::list list_type; generate_unique gu; list_type l; for (int i = 0; i != 5; ++i) l.push_back(gu.build()); VERIFY(l.size() == 5); typename list_type::iterator first = l.begin(); ++first; typename list_type::iterator last = first; ++last; ++last; cont_type c1; InsertRangeHelper::Insert(c1, first, last); VERIFY(c1.size() == 2); cont_type c2; InsertRangeHelper::Insert(c2, last, first); // Expected failure } template void check_insert4() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; typedef std::list list_type; generate_unique gu; list_type l; for (int i = 0; i != 5; ++i) l.push_back(gu.build()); VERIFY(l.size() == 5); typename list_type::iterator first = l.begin(); ++first; typename list_type::iterator last = first; ++last; ++last; cont_type c1; InsertRangeHelper::Insert(c1, l.begin(), l.end()); VERIFY(c1.size() == 5); c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. } template void use_invalid_iterator() { typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; generate_unique gu; cont_type c; for (size_t i = 0; i != 5; ++i) c.insert(gu.build()); typename cont_type::iterator it = c.begin(); cont_val_type val = *it; c.clear(); VERIFY( *it == val ); } }