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