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