11debfc3dSmrg // Helpers for quoted stream manipulators -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg // Copyright (C) 2013-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /** @file bits/quoted_string.h
261debfc3dSmrg * This is an internal header file, included by other library headers.
271debfc3dSmrg * Do not attempt to use it directly. @headername{iomanip}
281debfc3dSmrg */
291debfc3dSmrg
301debfc3dSmrg #ifndef _GLIBCXX_QUOTED_STRING_H
311debfc3dSmrg #define _GLIBCXX_QUOTED_STRING_H 1
321debfc3dSmrg
331debfc3dSmrg #pragma GCC system_header
341debfc3dSmrg
351debfc3dSmrg #if __cplusplus < 201103L
361debfc3dSmrg # include <bits/c++0x_warning.h>
371debfc3dSmrg #else
381debfc3dSmrg #include <sstream>
391debfc3dSmrg
_GLIBCXX_VISIBILITY(default)401debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
411debfc3dSmrg {
421debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
431debfc3dSmrg
44a2dc1f3fSmrg namespace __detail {
451debfc3dSmrg /**
461debfc3dSmrg * @brief Struct for delimited strings.
471debfc3dSmrg */
481debfc3dSmrg template<typename _String, typename _CharT>
491debfc3dSmrg struct _Quoted_string
501debfc3dSmrg {
511debfc3dSmrg static_assert(is_reference<_String>::value
521debfc3dSmrg || is_pointer<_String>::value,
531debfc3dSmrg "String type must be pointer or reference");
541debfc3dSmrg
551debfc3dSmrg _Quoted_string(_String __str, _CharT __del, _CharT __esc)
561debfc3dSmrg : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
571debfc3dSmrg { }
581debfc3dSmrg
591debfc3dSmrg _Quoted_string&
601debfc3dSmrg operator=(_Quoted_string&) = delete;
611debfc3dSmrg
621debfc3dSmrg _String _M_string;
631debfc3dSmrg _CharT _M_delim;
641debfc3dSmrg _CharT _M_escape;
651debfc3dSmrg };
661debfc3dSmrg
67a2dc1f3fSmrg #if __cplusplus >= 201703L
68a2dc1f3fSmrg template<typename _CharT, typename _Traits>
69a2dc1f3fSmrg struct _Quoted_string<basic_string_view<_CharT, _Traits>, _CharT>
70a2dc1f3fSmrg {
71a2dc1f3fSmrg _Quoted_string(basic_string_view<_CharT, _Traits> __str,
72a2dc1f3fSmrg _CharT __del, _CharT __esc)
73a2dc1f3fSmrg : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
74a2dc1f3fSmrg { }
75a2dc1f3fSmrg
76a2dc1f3fSmrg _Quoted_string&
77a2dc1f3fSmrg operator=(_Quoted_string&) = delete;
78a2dc1f3fSmrg
79a2dc1f3fSmrg basic_string_view<_CharT, _Traits> _M_string;
80a2dc1f3fSmrg _CharT _M_delim;
81a2dc1f3fSmrg _CharT _M_escape;
82a2dc1f3fSmrg };
83a2dc1f3fSmrg #endif // C++17
84a2dc1f3fSmrg
851debfc3dSmrg /**
861debfc3dSmrg * @brief Inserter for quoted strings.
871debfc3dSmrg *
881debfc3dSmrg * _GLIBCXX_RESOLVE_LIB_DEFECTS
891debfc3dSmrg * DR 2344 quoted()'s interaction with padding is unclear
901debfc3dSmrg */
911debfc3dSmrg template<typename _CharT, typename _Traits>
921debfc3dSmrg std::basic_ostream<_CharT, _Traits>&
931debfc3dSmrg operator<<(std::basic_ostream<_CharT, _Traits>& __os,
941debfc3dSmrg const _Quoted_string<const _CharT*, _CharT>& __str)
951debfc3dSmrg {
961debfc3dSmrg std::basic_ostringstream<_CharT, _Traits> __ostr;
971debfc3dSmrg __ostr << __str._M_delim;
981debfc3dSmrg for (const _CharT* __c = __str._M_string; *__c; ++__c)
991debfc3dSmrg {
1001debfc3dSmrg if (*__c == __str._M_delim || *__c == __str._M_escape)
1011debfc3dSmrg __ostr << __str._M_escape;
1021debfc3dSmrg __ostr << *__c;
1031debfc3dSmrg }
1041debfc3dSmrg __ostr << __str._M_delim;
1051debfc3dSmrg
1061debfc3dSmrg return __os << __ostr.str();
1071debfc3dSmrg }
1081debfc3dSmrg
1091debfc3dSmrg /**
1101debfc3dSmrg * @brief Inserter for quoted strings.
1111debfc3dSmrg *
1121debfc3dSmrg * _GLIBCXX_RESOLVE_LIB_DEFECTS
1131debfc3dSmrg * DR 2344 quoted()'s interaction with padding is unclear
1141debfc3dSmrg */
1151debfc3dSmrg template<typename _CharT, typename _Traits, typename _String>
1161debfc3dSmrg std::basic_ostream<_CharT, _Traits>&
1171debfc3dSmrg operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1181debfc3dSmrg const _Quoted_string<_String, _CharT>& __str)
1191debfc3dSmrg {
1201debfc3dSmrg std::basic_ostringstream<_CharT, _Traits> __ostr;
1211debfc3dSmrg __ostr << __str._M_delim;
122a2dc1f3fSmrg for (auto __c : __str._M_string)
1231debfc3dSmrg {
1241debfc3dSmrg if (__c == __str._M_delim || __c == __str._M_escape)
1251debfc3dSmrg __ostr << __str._M_escape;
1261debfc3dSmrg __ostr << __c;
1271debfc3dSmrg }
1281debfc3dSmrg __ostr << __str._M_delim;
1291debfc3dSmrg
1301debfc3dSmrg return __os << __ostr.str();
1311debfc3dSmrg }
1321debfc3dSmrg
1331debfc3dSmrg /**
1341debfc3dSmrg * @brief Extractor for delimited strings.
1351debfc3dSmrg * The left and right delimiters can be different.
1361debfc3dSmrg */
1371debfc3dSmrg template<typename _CharT, typename _Traits, typename _Alloc>
1381debfc3dSmrg std::basic_istream<_CharT, _Traits>&
1391debfc3dSmrg operator>>(std::basic_istream<_CharT, _Traits>& __is,
1401debfc3dSmrg const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
1411debfc3dSmrg _CharT>& __str)
1421debfc3dSmrg {
1431debfc3dSmrg _CharT __c;
1441debfc3dSmrg __is >> __c;
1451debfc3dSmrg if (!__is.good())
1461debfc3dSmrg return __is;
1471debfc3dSmrg if (__c != __str._M_delim)
1481debfc3dSmrg {
1491debfc3dSmrg __is.unget();
1501debfc3dSmrg __is >> __str._M_string;
1511debfc3dSmrg return __is;
1521debfc3dSmrg }
1531debfc3dSmrg __str._M_string.clear();
1541debfc3dSmrg std::ios_base::fmtflags __flags
1551debfc3dSmrg = __is.flags(__is.flags() & ~std::ios_base::skipws);
1561debfc3dSmrg do
1571debfc3dSmrg {
1581debfc3dSmrg __is >> __c;
1591debfc3dSmrg if (!__is.good())
1601debfc3dSmrg break;
1611debfc3dSmrg if (__c == __str._M_escape)
1621debfc3dSmrg {
1631debfc3dSmrg __is >> __c;
1641debfc3dSmrg if (!__is.good())
1651debfc3dSmrg break;
1661debfc3dSmrg }
1671debfc3dSmrg else if (__c == __str._M_delim)
1681debfc3dSmrg break;
1691debfc3dSmrg __str._M_string += __c;
1701debfc3dSmrg }
1711debfc3dSmrg while (true);
1721debfc3dSmrg __is.setf(__flags);
1731debfc3dSmrg
1741debfc3dSmrg return __is;
1751debfc3dSmrg }
176a2dc1f3fSmrg } // namespace __detail
1771debfc3dSmrg
1781debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
1791debfc3dSmrg } // namespace std
1801debfc3dSmrg
1811debfc3dSmrg #endif // C++11
1821debfc3dSmrg #endif /* _GLIBCXX_QUOTED_STRING_H */
183