// Copyright (C) 2010-2023 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 );
}
}