14d5abbe8Smrg // Helpers for quoted stream manipulators -*- C++ -*-
24d5abbe8Smrg
3b1e83836Smrg // Copyright (C) 2013-2022 Free Software Foundation, Inc.
44d5abbe8Smrg //
54d5abbe8Smrg // This file is part of the GNU ISO C++ Library. This library is free
64d5abbe8Smrg // software; you can redistribute it and/or modify it under the
74d5abbe8Smrg // terms of the GNU General Public License as published by the
84d5abbe8Smrg // Free Software Foundation; either version 3, or (at your option)
94d5abbe8Smrg // any later version.
104d5abbe8Smrg
114d5abbe8Smrg // This library is distributed in the hope that it will be useful,
124d5abbe8Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
134d5abbe8Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
144d5abbe8Smrg // GNU General Public License for more details.
154d5abbe8Smrg
164d5abbe8Smrg // Under Section 7 of GPL version 3, you are granted additional
174d5abbe8Smrg // permissions described in the GCC Runtime Library Exception, version
184d5abbe8Smrg // 3.1, as published by the Free Software Foundation.
194d5abbe8Smrg
204d5abbe8Smrg // You should have received a copy of the GNU General Public License and
214d5abbe8Smrg // a copy of the GCC Runtime Library Exception along with this program;
224d5abbe8Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
234d5abbe8Smrg // <http://www.gnu.org/licenses/>.
244d5abbe8Smrg
254d5abbe8Smrg /** @file bits/quoted_string.h
264d5abbe8Smrg * This is an internal header file, included by other library headers.
274d5abbe8Smrg * Do not attempt to use it directly. @headername{iomanip}
284d5abbe8Smrg */
294d5abbe8Smrg
304d5abbe8Smrg #ifndef _GLIBCXX_QUOTED_STRING_H
314d5abbe8Smrg #define _GLIBCXX_QUOTED_STRING_H 1
324d5abbe8Smrg
334d5abbe8Smrg #pragma GCC system_header
344d5abbe8Smrg
354d5abbe8Smrg #if __cplusplus < 201103L
364d5abbe8Smrg # include <bits/c++0x_warning.h>
374d5abbe8Smrg #else
384d5abbe8Smrg #include <sstream>
394d5abbe8Smrg
_GLIBCXX_VISIBILITY(default)404d5abbe8Smrg namespace std _GLIBCXX_VISIBILITY(default)
414d5abbe8Smrg {
424d5abbe8Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
434d5abbe8Smrg
44a3e9eb18Smrg namespace __detail {
454d5abbe8Smrg /**
464d5abbe8Smrg * @brief Struct for delimited strings.
474d5abbe8Smrg */
484d5abbe8Smrg template<typename _String, typename _CharT>
494d5abbe8Smrg struct _Quoted_string
504d5abbe8Smrg {
514d5abbe8Smrg static_assert(is_reference<_String>::value
524d5abbe8Smrg || is_pointer<_String>::value,
534d5abbe8Smrg "String type must be pointer or reference");
544d5abbe8Smrg
554d5abbe8Smrg _Quoted_string(_String __str, _CharT __del, _CharT __esc)
564d5abbe8Smrg : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
574d5abbe8Smrg { }
584d5abbe8Smrg
594d5abbe8Smrg _Quoted_string&
604d5abbe8Smrg operator=(_Quoted_string&) = delete;
614d5abbe8Smrg
624d5abbe8Smrg _String _M_string;
634d5abbe8Smrg _CharT _M_delim;
644d5abbe8Smrg _CharT _M_escape;
654d5abbe8Smrg };
664d5abbe8Smrg
67a3e9eb18Smrg #if __cplusplus >= 201703L
68a3e9eb18Smrg template<typename _CharT, typename _Traits>
69a3e9eb18Smrg struct _Quoted_string<basic_string_view<_CharT, _Traits>, _CharT>
70a3e9eb18Smrg {
71a3e9eb18Smrg _Quoted_string(basic_string_view<_CharT, _Traits> __str,
72a3e9eb18Smrg _CharT __del, _CharT __esc)
73a3e9eb18Smrg : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
74a3e9eb18Smrg { }
75a3e9eb18Smrg
76a3e9eb18Smrg _Quoted_string&
77a3e9eb18Smrg operator=(_Quoted_string&) = delete;
78a3e9eb18Smrg
79a3e9eb18Smrg basic_string_view<_CharT, _Traits> _M_string;
80a3e9eb18Smrg _CharT _M_delim;
81a3e9eb18Smrg _CharT _M_escape;
82a3e9eb18Smrg };
83a3e9eb18Smrg #endif // C++17
84a3e9eb18Smrg
854d5abbe8Smrg /**
864d5abbe8Smrg * @brief Inserter for quoted strings.
874d5abbe8Smrg *
88*0a307195Smrg * @headerfile iomanip
894d5abbe8Smrg */
904d5abbe8Smrg template<typename _CharT, typename _Traits>
914d5abbe8Smrg std::basic_ostream<_CharT, _Traits>&
924d5abbe8Smrg operator<<(std::basic_ostream<_CharT, _Traits>& __os,
934d5abbe8Smrg const _Quoted_string<const _CharT*, _CharT>& __str)
944d5abbe8Smrg {
95*0a307195Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
96*0a307195Smrg // DR 2344 quoted()'s interaction with padding is unclear
974d5abbe8Smrg std::basic_ostringstream<_CharT, _Traits> __ostr;
984d5abbe8Smrg __ostr << __str._M_delim;
994d5abbe8Smrg for (const _CharT* __c = __str._M_string; *__c; ++__c)
1004d5abbe8Smrg {
1014d5abbe8Smrg if (*__c == __str._M_delim || *__c == __str._M_escape)
1024d5abbe8Smrg __ostr << __str._M_escape;
1034d5abbe8Smrg __ostr << *__c;
1044d5abbe8Smrg }
1054d5abbe8Smrg __ostr << __str._M_delim;
1064d5abbe8Smrg
1074d5abbe8Smrg return __os << __ostr.str();
1084d5abbe8Smrg }
1094d5abbe8Smrg
1104d5abbe8Smrg /**
1114d5abbe8Smrg * @brief Inserter for quoted strings.
1124d5abbe8Smrg *
113*0a307195Smrg * @headerfile iomanip
1144d5abbe8Smrg */
1154d5abbe8Smrg template<typename _CharT, typename _Traits, typename _String>
1164d5abbe8Smrg std::basic_ostream<_CharT, _Traits>&
1174d5abbe8Smrg operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1184d5abbe8Smrg const _Quoted_string<_String, _CharT>& __str)
1194d5abbe8Smrg {
120*0a307195Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
121*0a307195Smrg // DR 2344 quoted()'s interaction with padding is unclear
1224d5abbe8Smrg std::basic_ostringstream<_CharT, _Traits> __ostr;
1234d5abbe8Smrg __ostr << __str._M_delim;
124a3e9eb18Smrg for (auto __c : __str._M_string)
1254d5abbe8Smrg {
1264d5abbe8Smrg if (__c == __str._M_delim || __c == __str._M_escape)
1274d5abbe8Smrg __ostr << __str._M_escape;
1284d5abbe8Smrg __ostr << __c;
1294d5abbe8Smrg }
1304d5abbe8Smrg __ostr << __str._M_delim;
1314d5abbe8Smrg
1324d5abbe8Smrg return __os << __ostr.str();
1334d5abbe8Smrg }
1344d5abbe8Smrg
1354d5abbe8Smrg /**
1364d5abbe8Smrg * @brief Extractor for delimited strings.
1374d5abbe8Smrg * The left and right delimiters can be different.
138*0a307195Smrg *
139*0a307195Smrg * @headerfile iomanip
1404d5abbe8Smrg */
1414d5abbe8Smrg template<typename _CharT, typename _Traits, typename _Alloc>
1424d5abbe8Smrg std::basic_istream<_CharT, _Traits>&
1434d5abbe8Smrg operator>>(std::basic_istream<_CharT, _Traits>& __is,
1444d5abbe8Smrg const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
1454d5abbe8Smrg _CharT>& __str)
1464d5abbe8Smrg {
1474d5abbe8Smrg _CharT __c;
1484d5abbe8Smrg __is >> __c;
1494d5abbe8Smrg if (!__is.good())
1504d5abbe8Smrg return __is;
1514d5abbe8Smrg if (__c != __str._M_delim)
1524d5abbe8Smrg {
1534d5abbe8Smrg __is.unget();
1544d5abbe8Smrg __is >> __str._M_string;
1554d5abbe8Smrg return __is;
1564d5abbe8Smrg }
1574d5abbe8Smrg __str._M_string.clear();
1584d5abbe8Smrg std::ios_base::fmtflags __flags
1594d5abbe8Smrg = __is.flags(__is.flags() & ~std::ios_base::skipws);
1604d5abbe8Smrg do
1614d5abbe8Smrg {
1624d5abbe8Smrg __is >> __c;
1634d5abbe8Smrg if (!__is.good())
1644d5abbe8Smrg break;
1654d5abbe8Smrg if (__c == __str._M_escape)
1664d5abbe8Smrg {
1674d5abbe8Smrg __is >> __c;
1684d5abbe8Smrg if (!__is.good())
1694d5abbe8Smrg break;
1704d5abbe8Smrg }
1714d5abbe8Smrg else if (__c == __str._M_delim)
1724d5abbe8Smrg break;
1734d5abbe8Smrg __str._M_string += __c;
1744d5abbe8Smrg }
1754d5abbe8Smrg while (true);
1764d5abbe8Smrg __is.setf(__flags);
1774d5abbe8Smrg
1784d5abbe8Smrg return __is;
1794d5abbe8Smrg }
180a3e9eb18Smrg } // namespace __detail
1814d5abbe8Smrg
1824d5abbe8Smrg _GLIBCXX_END_NAMESPACE_VERSION
1834d5abbe8Smrg } // namespace std
1844d5abbe8Smrg
1854d5abbe8Smrg #endif // C++11
1864d5abbe8Smrg #endif /* _GLIBCXX_QUOTED_STRING_H */
187