1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // REQUIRES: locale.en_US.UTF-8
10 
11 // <fstream>
12 
13 // int_type underflow();
14 
15 // This test is not entirely portable
16 
17 #include <fstream>
18 #include <cstddef>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 #include "platform_support.h" // locale name macros
23 
24 template <class CharT>
25 struct test_buf
26     : public std::basic_filebuf<CharT>
27 {
28     typedef std::basic_filebuf<CharT> base;
29     typedef typename base::char_type  char_type;
30     typedef typename base::int_type   int_type;
31 
ebacktest_buf32     char_type* eback() const {return base::eback();}
gptrtest_buf33     char_type* gptr()  const {return base::gptr();}
egptrtest_buf34     char_type* egptr() const {return base::egptr();}
gbumptest_buf35     void gbump(int n) {base::gbump(n);}
36 
underflowtest_buf37     virtual int_type underflow() {return base::underflow();}
38 };
39 
main(int,char **)40 int main(int, char**)
41 {
42     {
43         test_buf<char> f;
44         assert(f.open("underflow.dat", std::ios_base::in) != 0);
45         assert(f.is_open());
46         assert(f.eback() == 0);
47         assert(f.gptr() == 0);
48         assert(f.egptr() == 0);
49         assert(f.underflow() == '1');
50         assert(f.eback() != 0);
51         assert(f.eback() == f.gptr());
52         assert(*f.gptr() == '1');
53         assert(f.egptr() - f.eback() == 9);
54     }
55     {
56         test_buf<char> f;
57         assert(f.open("underflow.dat", std::ios_base::in) != 0);
58         assert(f.pubsetbuf(0, 0));
59         assert(f.is_open());
60         assert(f.eback() == 0);
61         assert(f.gptr() == 0);
62         assert(f.egptr() == 0);
63         assert(f.underflow() == '1');
64         assert(f.eback() != 0);
65         assert(f.eback() == f.gptr());
66         assert(*f.gptr() == '1');
67         assert(f.egptr() - f.eback() == 8);
68         f.gbump(8);
69         assert(f.sgetc() == '9');
70         assert(f.eback()[0] == '5');
71         assert(f.eback()[1] == '6');
72         assert(f.eback()[2] == '7');
73         assert(f.eback()[3] == '8');
74         assert(f.gptr() - f.eback() == 4);
75         assert(*f.gptr() == '9');
76         assert(f.egptr() - f.gptr() == 1);
77     }
78     {
79         test_buf<wchar_t> f;
80         assert(f.open("underflow.dat", std::ios_base::in) != 0);
81         assert(f.is_open());
82         assert(f.eback() == 0);
83         assert(f.gptr() == 0);
84         assert(f.egptr() == 0);
85         assert(f.underflow() == L'1');
86         assert(f.eback() != 0);
87         assert(f.eback() == f.gptr());
88         assert(*f.gptr() == L'1');
89         assert(f.egptr() - f.eback() == 9);
90     }
91     {
92         test_buf<wchar_t> f;
93         assert(f.pubsetbuf(0, 0));
94         assert(f.open("underflow.dat", std::ios_base::in) != 0);
95         assert(f.is_open());
96         assert(f.eback() == 0);
97         assert(f.gptr() == 0);
98         assert(f.egptr() == 0);
99         assert(f.underflow() == L'1');
100         assert(f.eback() != 0);
101         assert(f.eback() == f.gptr());
102         assert(*f.gptr() == L'1');
103         assert(f.egptr() - f.eback() == 8);
104         f.gbump(8);
105         assert(f.sgetc() == L'9');
106         assert(f.eback()[0] == L'5');
107         assert(f.eback()[1] == L'6');
108         assert(f.eback()[2] == L'7');
109         assert(f.eback()[3] == L'8');
110         assert(f.gptr() - f.eback() == 4);
111         assert(*f.gptr() == L'9');
112         assert(f.egptr() - f.gptr() == 1);
113     }
114     {
115         typedef std::char_traits<wchar_t> Traits;
116         test_buf<wchar_t> f;
117         f.pubimbue(std::locale(LOCALE_en_US_UTF_8));
118         assert(f.open("underflow_utf8.dat", std::ios_base::in) != 0);
119         assert(f.is_open());
120         assert(f.sbumpc() == 0x4E51);
121         assert(f.sbumpc() == 0x4E52);
122         assert(f.sbumpc() == 0x4E53);
123         assert(f.sbumpc() == static_cast<Traits::int_type>(-1));
124     }
125 
126   return 0;
127 }
128