blob: 9061bfb31870f8e241b56c6931528dc50789ce88 [file] [log] [blame]
// Copyright (C) 2018-2021 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
// <http://www.gnu.org/licenses/>.
// { dg-do run }
#include <vector>
#include <stdexcept>
#include <limits>
#include <testsuite_hooks.h>
typedef std::vector<char> test_type;
typedef test_type::size_type size_type;
typedef test_type::difference_type difference_type;
const difference_type diffmax = std::numeric_limits<difference_type>::max();
void
test01()
{
test_type v;
VERIFY( v.max_size() <= diffmax );
}
void
test02()
{
size_type n = size_type(diffmax) + 1;
VERIFY( n > test_type().max_size() );
try {
test_type v(n);
VERIFY( false );
} catch (const std::length_error&) { }
try {
test_type v(n, 'x');
VERIFY( false );
} catch (const std::length_error&) { }
try {
test_type v(n, 'x', test_type::allocator_type());
VERIFY( false );
} catch (const std::length_error&) { }
}
#ifdef __GLIBCXX_TYPE_INT_N_0
template<typename T, typename U, bool = (sizeof(T) > sizeof(long long))>
struct Base_
{
typedef T difference_type;
typedef U size_type;
};
template<typename T, typename U>
struct Base_<T, U, false>
{
typedef long long difference_type;
typedef unsigned long long size_type;
};
typedef Base_<__GLIBCXX_TYPE_INT_N_0, unsigned __GLIBCXX_TYPE_INT_N_0> Base;
#else
struct Base
{
typedef long long difference_type;
typedef unsigned long long size_type;
};
#endif
// An iterator with a difference_type larger than ptrdiff_t
struct Iter : Base
{
typedef std::random_access_iterator_tag iterator_category;
typedef char value_type;
typedef const char* pointer;
typedef const char& reference;
using Base::difference_type;
Iter() : n(0) { }
Iter(size_type n) : n(n) { }
reference operator*() const { return value; }
pointer operator->() const { return &value; }
Iter& operator++() { ++n; return *this; }
Iter operator++(int) { Iter tmp(*this); ++n; return tmp; }
Iter& operator--() { --n; return *this; }
Iter operator--(int) { Iter tmp(*this); --n; return tmp; }
Iter& operator+=(difference_type d) { n += d; return *this; }
Iter& operator-=(difference_type d) { n -= d; return *this; }
difference_type operator-(const Iter& rhs) const { return n - rhs.n; }
reference operator[](difference_type d) const { return value; }
bool operator==(const Iter& rhs) const { return n == rhs.n; }
bool operator!=(const Iter& rhs) const { return n != rhs.n; }
bool operator<(const Iter& rhs) const { return n < rhs.n; }
bool operator>(const Iter& rhs) const { return n > rhs.n; }
bool operator<=(const Iter& rhs) const { return n <= rhs.n; }
bool operator>=(const Iter& rhs) const { return n >= rhs.n; }
private:
size_type n;
static const char value = 'x';
};
const char Iter::value;
Iter operator+(Iter i, Iter::difference_type n) { return i += n; }
Iter operator+(Iter::difference_type n, Iter i) { return i += n; }
Iter operator-(Iter::difference_type n, Iter i) { return i -= n; }
void
test03()
{
Iter first, last(Iter::size_type(diffmax) + 1);
VERIFY( std::distance(first, last) > test_type().max_size() );
try {
test_type vec(first, last);
VERIFY(false);
} catch (const std::length_error&) { }
}
int
main()
{
test01();
test02();
test03();
}