]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/45628-2.cc
re PR libstdc++/45628 (std::fstream::tellg invalidates I/O buffer)
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 27_io / basic_filebuf / seekoff / 45628-2.cc
CommitLineData
3531cf5e
DK
1// Copyright (C) 2010 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// { dg-require-fileio "" }
19
20#include <fstream>
21#include <testsuite_hooks.h>
22#include <testsuite_character.h>
23
24const char name_01[] = "tmp_seekoff_45628.tst";
25
26unsigned underflows, overflows;
27
28class my_filebuf
29: public std::basic_filebuf<__gnu_test::pod_uchar>
30{
31 virtual int_type
32 underflow()
33 {
34 ++underflows;
35 return std::basic_filebuf<__gnu_test::pod_uchar>::underflow();
36 }
37 virtual int_type
38 overflow(int_type c)
39 {
40 ++overflows;
41 return std::basic_filebuf<__gnu_test::pod_uchar>::overflow(c);
42 }
43};
44
45// libstdc++/45628
46void test01()
47{
48 bool test __attribute__((unused)) = true;
49
50 using __gnu_test::pod_uchar;
51 std::locale loc(std::locale::classic(),
52 new std::codecvt<my_filebuf::traits_type::char_type, char,
53 my_filebuf::traits_type::state_type>);
54
55 my_filebuf::pos_type opos[3], ipos[3];
56 my_filebuf q;
57 q.pubimbue(loc);
58
59 q.open(name_01, std::ios_base::in | std::ios_base::out
60 | std::ios_base::trunc);
61
62 q.sputc(pod_uchar::from<char>('a'));
63 opos[0] = q.pubseekoff(0, std::ios_base::cur);
64 q.sputc(pod_uchar::from<char>('b'));
65 opos[1] = q.pubseekoff(0, std::ios_base::cur);
66 q.sputc(pod_uchar::from<char>('c'));
67 opos[2] = q.pubseekoff(0, std::ios_base::cur);
68
69 VERIFY( overflows <= 9 ); // pubseekoff calls overflow twice if converting.
70 // NB: checking opos==ipos is not very rigorous as long as it flushes, since
71 // all positions will be at initial state.
72 q.pubseekoff(0, std::ios_base::beg);
73
74 q.sbumpc();
75 VERIFY( underflows == 1 );
76
77 ipos[0] = q.pubseekoff(0, std::ios_base::cur);
78 VERIFY( ipos[0] == opos[0] );
79 q.sbumpc();
80 ipos[1] = q.pubseekoff(0, std::ios_base::cur);
81 VERIFY( ipos[1] == opos[1] );
82 q.sbumpc();
83 ipos[2] = q.pubseekoff(0, std::ios_base::cur);
84 VERIFY( ipos[2] == opos[2] );
85
86 VERIFY( underflows == 1 ); // pubseekoff never flushes get area
87
88 // Bonus test: check automatic mode switches.
89 q.sputc(pod_uchar::from<char>('d'));
90
91 q.pubseekpos( ipos[1] );
92 q.sputc(pod_uchar::from<char>('e'));
93
94 VERIFY( my_filebuf::traits_type::eq(
95 my_filebuf::traits_type::to_char_type(q.sgetc()),
96 pod_uchar::from<char>('d')) );
97}
98
99int main()
100{
101 test01();
102 return 0;
103}