xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/quoted_string.h (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
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