xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // Helpers for quoted stream manipulators -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2013-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file bits/quoted_string.h
26*38fd1498Szrj  *  This is an internal header file, included by other library headers.
27*38fd1498Szrj  *  Do not attempt to use it directly. @headername{iomanip}
28*38fd1498Szrj  */
29*38fd1498Szrj 
30*38fd1498Szrj #ifndef _GLIBCXX_QUOTED_STRING_H
31*38fd1498Szrj #define _GLIBCXX_QUOTED_STRING_H 1
32*38fd1498Szrj 
33*38fd1498Szrj #pragma GCC system_header
34*38fd1498Szrj 
35*38fd1498Szrj #if __cplusplus < 201103L
36*38fd1498Szrj # include <bits/c++0x_warning.h>
37*38fd1498Szrj #else
38*38fd1498Szrj #include <sstream>
39*38fd1498Szrj 
40*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
41*38fd1498Szrj {
42*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
43*38fd1498Szrj 
44*38fd1498Szrj   namespace __detail {
45*38fd1498Szrj     /**
46*38fd1498Szrj      * @brief Struct for delimited strings.
47*38fd1498Szrj      */
48*38fd1498Szrj     template<typename _String, typename _CharT>
49*38fd1498Szrj       struct _Quoted_string
50*38fd1498Szrj       {
51*38fd1498Szrj 	static_assert(is_reference<_String>::value
52*38fd1498Szrj 		   || is_pointer<_String>::value,
53*38fd1498Szrj 		      "String type must be pointer or reference");
54*38fd1498Szrj 
55*38fd1498Szrj 	_Quoted_string(_String __str, _CharT __del, _CharT __esc)
56*38fd1498Szrj 	: _M_string(__str), _M_delim{__del}, _M_escape{__esc}
57*38fd1498Szrj 	{ }
58*38fd1498Szrj 
59*38fd1498Szrj 	_Quoted_string&
60*38fd1498Szrj 	operator=(_Quoted_string&) = delete;
61*38fd1498Szrj 
62*38fd1498Szrj 	_String _M_string;
63*38fd1498Szrj 	_CharT _M_delim;
64*38fd1498Szrj 	_CharT _M_escape;
65*38fd1498Szrj       };
66*38fd1498Szrj 
67*38fd1498Szrj     /**
68*38fd1498Szrj      * @brief Inserter for quoted strings.
69*38fd1498Szrj      *
70*38fd1498Szrj      *  _GLIBCXX_RESOLVE_LIB_DEFECTS
71*38fd1498Szrj      *  DR 2344 quoted()'s interaction with padding is unclear
72*38fd1498Szrj      */
73*38fd1498Szrj     template<typename _CharT, typename _Traits>
74*38fd1498Szrj       std::basic_ostream<_CharT, _Traits>&
75*38fd1498Szrj       operator<<(std::basic_ostream<_CharT, _Traits>& __os,
76*38fd1498Szrj 		 const _Quoted_string<const _CharT*, _CharT>& __str)
77*38fd1498Szrj       {
78*38fd1498Szrj 	std::basic_ostringstream<_CharT, _Traits> __ostr;
79*38fd1498Szrj 	__ostr << __str._M_delim;
80*38fd1498Szrj 	for (const _CharT* __c = __str._M_string; *__c; ++__c)
81*38fd1498Szrj 	  {
82*38fd1498Szrj 	    if (*__c == __str._M_delim || *__c == __str._M_escape)
83*38fd1498Szrj 	      __ostr << __str._M_escape;
84*38fd1498Szrj 	    __ostr << *__c;
85*38fd1498Szrj 	  }
86*38fd1498Szrj 	__ostr << __str._M_delim;
87*38fd1498Szrj 
88*38fd1498Szrj 	return __os << __ostr.str();
89*38fd1498Szrj       }
90*38fd1498Szrj 
91*38fd1498Szrj     /**
92*38fd1498Szrj      * @brief Inserter for quoted strings.
93*38fd1498Szrj      *
94*38fd1498Szrj      *  _GLIBCXX_RESOLVE_LIB_DEFECTS
95*38fd1498Szrj      *  DR 2344 quoted()'s interaction with padding is unclear
96*38fd1498Szrj      */
97*38fd1498Szrj     template<typename _CharT, typename _Traits, typename _String>
98*38fd1498Szrj       std::basic_ostream<_CharT, _Traits>&
99*38fd1498Szrj       operator<<(std::basic_ostream<_CharT, _Traits>& __os,
100*38fd1498Szrj 		 const _Quoted_string<_String, _CharT>& __str)
101*38fd1498Szrj       {
102*38fd1498Szrj 	std::basic_ostringstream<_CharT, _Traits> __ostr;
103*38fd1498Szrj 	__ostr << __str._M_delim;
104*38fd1498Szrj 	for (auto& __c : __str._M_string)
105*38fd1498Szrj 	  {
106*38fd1498Szrj 	    if (__c == __str._M_delim || __c == __str._M_escape)
107*38fd1498Szrj 	      __ostr << __str._M_escape;
108*38fd1498Szrj 	    __ostr << __c;
109*38fd1498Szrj 	  }
110*38fd1498Szrj 	__ostr << __str._M_delim;
111*38fd1498Szrj 
112*38fd1498Szrj 	return __os << __ostr.str();
113*38fd1498Szrj       }
114*38fd1498Szrj 
115*38fd1498Szrj     /**
116*38fd1498Szrj      * @brief Extractor for delimited strings.
117*38fd1498Szrj      *        The left and right delimiters can be different.
118*38fd1498Szrj      */
119*38fd1498Szrj     template<typename _CharT, typename _Traits, typename _Alloc>
120*38fd1498Szrj       std::basic_istream<_CharT, _Traits>&
121*38fd1498Szrj       operator>>(std::basic_istream<_CharT, _Traits>& __is,
122*38fd1498Szrj 		 const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
123*38fd1498Szrj 				      _CharT>& __str)
124*38fd1498Szrj       {
125*38fd1498Szrj 	_CharT __c;
126*38fd1498Szrj 	__is >> __c;
127*38fd1498Szrj 	if (!__is.good())
128*38fd1498Szrj 	  return __is;
129*38fd1498Szrj 	if (__c != __str._M_delim)
130*38fd1498Szrj 	  {
131*38fd1498Szrj 	    __is.unget();
132*38fd1498Szrj 	    __is >> __str._M_string;
133*38fd1498Szrj 	    return __is;
134*38fd1498Szrj 	  }
135*38fd1498Szrj 	__str._M_string.clear();
136*38fd1498Szrj 	std::ios_base::fmtflags __flags
137*38fd1498Szrj 	  = __is.flags(__is.flags() & ~std::ios_base::skipws);
138*38fd1498Szrj 	do
139*38fd1498Szrj 	  {
140*38fd1498Szrj 	    __is >> __c;
141*38fd1498Szrj 	    if (!__is.good())
142*38fd1498Szrj 	      break;
143*38fd1498Szrj 	    if (__c == __str._M_escape)
144*38fd1498Szrj 	      {
145*38fd1498Szrj 		__is >> __c;
146*38fd1498Szrj 		if (!__is.good())
147*38fd1498Szrj 		  break;
148*38fd1498Szrj 	      }
149*38fd1498Szrj 	    else if (__c == __str._M_delim)
150*38fd1498Szrj 	      break;
151*38fd1498Szrj 	    __str._M_string += __c;
152*38fd1498Szrj 	  }
153*38fd1498Szrj 	while (true);
154*38fd1498Szrj 	__is.setf(__flags);
155*38fd1498Szrj 
156*38fd1498Szrj 	return __is;
157*38fd1498Szrj       }
158*38fd1498Szrj   } // namespace __detail
159*38fd1498Szrj 
160*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
161*38fd1498Szrj } // namespace std
162*38fd1498Szrj 
163*38fd1498Szrj #endif // C++11
164*38fd1498Szrj #endif /* _GLIBCXX_QUOTED_STRING_H */
165