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 
testbuftestbuf30     testbuf() {}
testbuftestbuf31     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 
ebacktestbuf39     CharT* eback() const {return base::eback();}
gptrtestbuf40     CharT* gptr() const {return base::gptr();}
egptrtestbuf41     CharT* egptr() const {return base::egptr();}
42 
43 protected:
synctestbuf44     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 
throwing_testbufthrowing_testbuf64     throwing_testbuf() {}
throwing_testbufthrowing_testbuf65     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 
ebackthrowing_testbuf73     CharT* eback() const {return base::eback();}
gptrthrowing_testbuf74     CharT* gptr() const {return base::gptr();}
egptrthrowing_testbuf75     CharT* egptr() const {return base::egptr();}
76 
77 protected:
syncthrowing_testbuf78     virtual int sync()
79     {
80         throw testbuf_exception();
81         return 5;
82     }
83 };
84 #endif // TEST_HAS_NO_EXCEPTIONS
85 
main(int,char **)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 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
95     {
96         testbuf<wchar_t> sb(L" 123456789");
97         std::wistream is(&sb);
98         assert(is.sync() == 0);
99         assert(sync_called == 2);
100     }
101 #endif
102 #ifndef TEST_HAS_NO_EXCEPTIONS
103     {
104         throwing_testbuf<char> sb(" 123456789");
105         std::basic_istream<char> is(&sb);
106         is.exceptions(std::ios_base::badbit);
107         bool threw = false;
108         try {
109             is.sync();
110         } catch (testbuf_exception const&) {
111             threw = true;
112         }
113         assert( is.bad());
114         assert(!is.eof());
115         assert( is.fail());
116         assert(threw);
117     }
118 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
119     {
120         throwing_testbuf<wchar_t> sb(L" 123456789");
121         std::basic_istream<wchar_t> is(&sb);
122         is.exceptions(std::ios_base::badbit);
123         bool threw = false;
124         try {
125             is.sync();
126         } catch (testbuf_exception const&) {
127             threw = true;
128         }
129         assert( is.bad());
130         assert(!is.eof());
131         assert( is.fail());
132         assert(threw);
133     }
134 #endif
135 #endif // TEST_HAS_NO_EXCEPTIONS
136 
137     return 0;
138 }
139