summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc
blob: 5d4de3d6cb5416c53e973f9d78b71aeafe29b37a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (C) 2020-2022 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 { target { { ! lp64 } && { ! simulator } } } }
// { dg-timeout-factor 2 }

#include <istream>
#include <streambuf>
#include <limits>
#include <testsuite_hooks.h>

typedef char C;

struct buff : std::basic_streambuf<C>
{
  typedef std::streamsize		  streamsize;
  typedef std::numeric_limits<streamsize> limits;

  buff() : count(0), buf() { }

  int_type underflow()
  {
    // Number of characters left until we overflow the counter
    const streamsize headroom = limits::max() - count;

    if (headroom == 0)
      return traits_type::eof();

    if (bufsz < headroom)
      count += bufsz;
    else
      count = limits::max();

    this->setg(buf + 1, buf + 1, buf + bufsz);

    return buf[0];
  }

  int_type overflow(int_type c)
  {
    if (traits_type::eq_int_type(c , traits_type::eof()))
      return c;
    this->setp(buf, buf + bufsz - 1);
    return traits_type::not_eof(c);
  }

  streamsize count;

  static const streamsize bufsz = (2048 << limits::digits10) + 1;
  char_type buf[bufsz];
};

void
test01()
{
  // Not possible to overflow 64-bit streamsize in reasonable time.
  if (std::numeric_limits<std::streamsize>::digits > 32)
    return;

  std::basic_istream<C> in(new buff);
  buff out;
  in.get(out);
  VERIFY( in.gcount() == std::numeric_limits<std::streamsize>::max() );

  delete in.rdbuf(new buff);

  in.get();
  VERIFY( in.gcount() == 1 );

  in.get(out, 'a');
  VERIFY( in.gcount() == std::numeric_limits<std::streamsize>::max() );
}

int
main()
{
  test01();
}