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 // <istream>
10 
11 // int sync();
12 
13 #include <istream>
14 #include <cassert>
15 
16 #include "test_macros.h"
17 
18 int sync_called = 0;
19 
20 template <class CharT>
21 struct testbuf
22     : public std::basic_streambuf<CharT>
23 {
24     typedef std::basic_string<CharT> string_type;
25     typedef std::basic_streambuf<CharT> base;
26 private:
27     string_type str_;
28 public:
29 
30     testbuf() {}
31     testbuf(const string_type& str)
32         : str_(str)
33     {
34         base::setg(const_cast<CharT*>(str_.data()),
35                    const_cast<CharT*>(str_.data()),
36                    const_cast<CharT*>(str_.data()) + str_.size());
37     }
38 
39     CharT* eback() const {return base::eback();}
40     CharT* gptr() const {return base::gptr();}
41     CharT* egptr() const {return base::egptr();}
42 
43 protected:
44     int sync()
45     {
46         ++sync_called;
47         return 5;
48     }
49 };
50 
51 #ifndef TEST_HAS_NO_EXCEPTIONS
52 struct testbuf_exception { };
53 
54 template <class CharT>
55 struct throwing_testbuf
56     : public std::basic_streambuf<CharT>
57 {
58     typedef std::basic_string<CharT> string_type;
59     typedef std::basic_streambuf<CharT> base;
60 private:
61     string_type str_;
62 public:
63 
64     throwing_testbuf() {}
65     throwing_testbuf(const string_type& str)
66         : str_(str)
67     {
68         base::setg(const_cast<CharT*>(str_.data()),
69                    const_cast<CharT*>(str_.data()),
70                    const_cast<CharT*>(str_.data()) + str_.size());
71     }
72 
73     CharT* eback() const {return base::eback();}
74     CharT* gptr() const {return base::gptr();}
75     CharT* egptr() const {return base::egptr();}
76 
77 protected:
78     virtual int sync()
79     {
80         throw testbuf_exception();
81         return 5;
82     }
83 };
84 #endif // TEST_HAS_NO_EXCEPTIONS
85 
86 int main(int, char**)
87 {
88     {
89         testbuf<char> sb(" 123456789");
90         std::istream is(&sb);
91         assert(is.sync() == 0);
92         assert(sync_called == 1);
93     }
94     {
95         testbuf<wchar_t> sb(L" 123456789");
96         std::wistream is(&sb);
97         assert(is.sync() == 0);
98         assert(sync_called == 2);
99     }
100 #ifndef TEST_HAS_NO_EXCEPTIONS
101     {
102         throwing_testbuf<char> sb(" 123456789");
103         std::basic_istream<char> is(&sb);
104         is.exceptions(std::ios_base::badbit);
105         bool threw = false;
106         try {
107             is.sync();
108         } catch (testbuf_exception const&) {
109             threw = true;
110         }
111         assert( is.bad());
112         assert(!is.eof());
113         assert( is.fail());
114         assert(threw);
115     }
116     {
117         throwing_testbuf<wchar_t> sb(L" 123456789");
118         std::basic_istream<wchar_t> is(&sb);
119         is.exceptions(std::ios_base::badbit);
120         bool threw = false;
121         try {
122             is.sync();
123         } catch (testbuf_exception const&) {
124             threw = true;
125         }
126         assert( is.bad());
127         assert(!is.eof());
128         assert( is.fail());
129         assert(threw);
130     }
131 #endif
132 
133     return 0;
134 }
135