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 // FILE_DEPENDENCIES: underflow.dat, underflow_utf8.dat
11 
12 // XFAIL: LIBCXX-WINDOWS-FIXME
13 
14 // <fstream>
15 
16 // int_type underflow();
17 
18 // This test is not entirely portable
19 
20 #include <fstream>
21 #include <cstddef>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 #include "platform_support.h" // locale name macros
26 
27 template <class CharT>
28 struct test_buf
29     : public std::basic_filebuf<CharT>
30 {
31     typedef std::basic_filebuf<CharT> base;
32     typedef typename base::char_type  char_type;
33     typedef typename base::int_type   int_type;
34 
35     char_type* eback() const {return base::eback();}
36     char_type* gptr()  const {return base::gptr();}
37     char_type* egptr() const {return base::egptr();}
38     void gbump(int n) {base::gbump(n);}
39 
40     virtual int_type underflow() {return base::underflow();}
41 };
42 
43 int main(int, char**)
44 {
45     {
46         test_buf<char> f;
47         assert(f.open("underflow.dat", std::ios_base::in) != 0);
48         assert(f.is_open());
49         assert(f.eback() == 0);
50         assert(f.gptr() == 0);
51         assert(f.egptr() == 0);
52         assert(f.underflow() == '1');
53         assert(f.eback() != 0);
54         assert(f.eback() == f.gptr());
55         assert(*f.gptr() == '1');
56         assert(f.egptr() - f.eback() == 9);
57     }
58     {
59         test_buf<char> f;
60         assert(f.open("underflow.dat", std::ios_base::in) != 0);
61         assert(f.pubsetbuf(0, 0));
62         assert(f.is_open());
63         assert(f.eback() == 0);
64         assert(f.gptr() == 0);
65         assert(f.egptr() == 0);
66         assert(f.underflow() == '1');
67         assert(f.eback() != 0);
68         assert(f.eback() == f.gptr());
69         assert(*f.gptr() == '1');
70         assert(f.egptr() - f.eback() == 8);
71         f.gbump(8);
72         assert(f.sgetc() == '9');
73         assert(f.eback()[0] == '5');
74         assert(f.eback()[1] == '6');
75         assert(f.eback()[2] == '7');
76         assert(f.eback()[3] == '8');
77         assert(f.gptr() - f.eback() == 4);
78         assert(*f.gptr() == '9');
79         assert(f.egptr() - f.gptr() == 1);
80     }
81 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
82     {
83         test_buf<wchar_t> f;
84         assert(f.open("underflow.dat", std::ios_base::in) != 0);
85         assert(f.is_open());
86         assert(f.eback() == 0);
87         assert(f.gptr() == 0);
88         assert(f.egptr() == 0);
89         assert(f.underflow() == L'1');
90         assert(f.eback() != 0);
91         assert(f.eback() == f.gptr());
92         assert(*f.gptr() == L'1');
93         assert(f.egptr() - f.eback() == 9);
94     }
95     {
96         test_buf<wchar_t> f;
97         assert(f.pubsetbuf(0, 0));
98         assert(f.open("underflow.dat", std::ios_base::in) != 0);
99         assert(f.is_open());
100         assert(f.eback() == 0);
101         assert(f.gptr() == 0);
102         assert(f.egptr() == 0);
103         assert(f.underflow() == L'1');
104         assert(f.eback() != 0);
105         assert(f.eback() == f.gptr());
106         assert(*f.gptr() == L'1');
107         assert(f.egptr() - f.eback() == 8);
108         f.gbump(8);
109         assert(f.sgetc() == L'9');
110         assert(f.eback()[0] == L'5');
111         assert(f.eback()[1] == L'6');
112         assert(f.eback()[2] == L'7');
113         assert(f.eback()[3] == L'8');
114         assert(f.gptr() - f.eback() == 4);
115         assert(*f.gptr() == L'9');
116         assert(f.egptr() - f.gptr() == 1);
117     }
118     {
119         typedef std::char_traits<wchar_t> Traits;
120         test_buf<wchar_t> f;
121         f.pubimbue(std::locale(LOCALE_en_US_UTF_8));
122         assert(f.open("underflow_utf8.dat", std::ios_base::in) != 0);
123         assert(f.is_open());
124         assert(f.sbumpc() == 0x4E51);
125         assert(f.sbumpc() == 0x4E52);
126         assert(f.sbumpc() == 0x4E53);
127         assert(f.sbumpc() == static_cast<Traits::int_type>(-1));
128     }
129 #endif // TEST_HAS_NO_WIDE_CHARACTERS
130 
131   return 0;
132 }
133