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

source code of libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp