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