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 // <iomanip>
11
12 // quoted
13
14 #include <iomanip>
15 #include <sstream>
16 #include <string>
17 #include <cassert>
18
19 #include "test_macros.h"
20
21 #if TEST_STD_VER > 11
22
23 template <class CharT, class Traits>
is_skipws(const std::basic_istream<CharT,Traits> & is)24 bool is_skipws ( const std::basic_istream<CharT, Traits>& is ) {
25 return ( is.flags() & std::ios_base::skipws ) != 0;
26 }
27
28 template <class CharT, class Traits = std::char_traits<CharT>>
both_ways(const CharT * p)29 void both_ways ( const CharT *p ) {
30 std::basic_string<CharT, Traits> str(p);
31 auto q = std::quoted(str);
32
33 std::basic_stringstream<CharT, Traits> ss;
34 bool skippingws = is_skipws ( ss );
35 ((void)skippingws); // Prevent unused warning
36 ss << q;
37 ss >> q;
38 }
39
40 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip(const CharT * p)41 void round_trip ( const CharT *p ) {
42 std::basic_stringstream<CharT, Traits> ss;
43 bool skippingws = is_skipws ( ss );
44
45 ss << std::quoted(p);
46 std::basic_string<CharT, Traits> s;
47 ss >> std::quoted(s);
48 assert ( s == p );
49 assert ( skippingws == is_skipws ( ss ));
50 }
51
52
53 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_ws(const CharT * p)54 void round_trip_ws ( const CharT *p ) {
55 std::basic_stringstream<CharT, Traits> ss;
56 std::noskipws ( ss );
57 bool skippingws = is_skipws ( ss );
58
59 ss << std::quoted(p);
60 std::basic_string<CharT, Traits> s;
61 ss >> std::quoted(s);
62 assert ( s == p );
63 assert ( skippingws == is_skipws ( ss ));
64 }
65
66 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_d(const CharT * p,char delim)67 void round_trip_d ( const CharT *p, char delim ) {
68 std::basic_stringstream<CharT, Traits> ss;
69 CharT d(delim);
70
71 ss << std::quoted(p, d);
72 std::basic_string<CharT, Traits> s;
73 ss >> std::quoted(s, d);
74 assert ( s == p );
75 }
76
77 template <class CharT, class Traits = std::char_traits<CharT>>
round_trip_e(const CharT * p,char escape)78 void round_trip_e ( const CharT *p, char escape ) {
79 std::basic_stringstream<CharT, Traits> ss;
80 CharT e(escape);
81
82 ss << std::quoted(p, CharT('"'), e );
83 std::basic_string<CharT, Traits> s;
84 ss >> std::quoted(s, CharT('"'), e );
85 assert ( s == p );
86 }
87
88
89 template <class CharT, class Traits = std::char_traits<CharT>>
quote(const CharT * p,char delim='"',char escape='\\\\')90 std::basic_string<CharT, Traits> quote ( const CharT *p, char delim='"', char escape='\\' ) {
91 std::basic_stringstream<CharT, Traits> ss;
92 CharT d(delim);
93 CharT e(escape);
94 ss << std::quoted(p, d, e);
95 std::basic_string<CharT, Traits> s;
96 ss >> s; // no quote
97 return s;
98 }
99
100 template <class CharT, class Traits = std::char_traits<CharT>>
unquote(const CharT * p,char delim='"',char escape='\\\\')101 std::basic_string<CharT, Traits> unquote ( const CharT *p, char delim='"', char escape='\\' ) {
102 std::basic_stringstream<CharT, Traits> ss;
103 ss << p;
104
105 CharT d(delim);
106 CharT e(escape);
107 std::basic_string<CharT, Traits> s;
108 ss >> std::quoted(s, d, e);
109 return s;
110 }
111
test_padding()112 void test_padding () {
113 {
114 std::stringstream ss;
115 ss << std::left << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
116 assert ( ss.str() == "`abc`!!!!!" );
117 }
118
119 {
120 std::stringstream ss;
121 ss << std::right << std::setw(10) << std::setfill('!') << std::quoted("abc", '`');
122 assert ( ss.str() == "!!!!!`abc`" );
123 }
124 }
125
126
main()127 int main()
128 {
129 both_ways ( "" ); // This is a compilation check
130
131 round_trip ( "" );
132 round_trip_ws ( "" );
133 round_trip_d ( "", 'q' );
134 round_trip_e ( "", 'q' );
135
136 round_trip ( L"" );
137 round_trip_ws ( L"" );
138 round_trip_d ( L"", 'q' );
139 round_trip_e ( L"", 'q' );
140
141 round_trip ( "Hi" );
142 round_trip_ws ( "Hi" );
143 round_trip_d ( "Hi", '!' );
144 round_trip_e ( "Hi", '!' );
145 assert ( quote ( "Hi", '!' ) == "!Hi!" );
146 assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
147
148 round_trip ( L"Hi" );
149 round_trip_ws ( L"Hi" );
150 round_trip_d ( L"Hi", '!' );
151 round_trip_e ( L"Hi", '!' );
152 assert ( quote ( L"Hi", '!' ) == L"!Hi!" );
153 assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
154
155 round_trip ( "Hi Mom" );
156 round_trip_ws ( "Hi Mom" );
157 round_trip ( L"Hi Mom" );
158 round_trip_ws ( L"Hi Mom" );
159
160 assert ( quote ( "" ) == "\"\"" );
161 assert ( quote ( L"" ) == L"\"\"" );
162 assert ( quote ( "a" ) == "\"a\"" );
163 assert ( quote ( L"a" ) == L"\"a\"" );
164
165 // missing end quote - must not hang
166 assert ( unquote ( "\"abc" ) == "abc" );
167 assert ( unquote ( L"\"abc" ) == L"abc" );
168
169 assert ( unquote ( "abc" ) == "abc" ); // no delimiter
170 assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
171 assert ( unquote ( "abc def" ) == "abc" ); // no delimiter
172 assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
173
174 assert ( unquote ( "" ) == "" ); // nothing there
175 assert ( unquote ( L"" ) == L"" ); // nothing there
176 test_padding ();
177 }
178
179 #else
main()180 int main() {}
181 #endif
182