libstdc++
|
00001 // Helpers for quoted stream manipulators -*- C++ -*- 00002 00003 // Copyright (C) 2013-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/quoted_string.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{iomanip} 00028 */ 00029 00030 #ifndef _GLIBCXX_QUOTED_STRING_H 00031 #define _GLIBCXX_QUOTED_STRING_H 1 00032 00033 #pragma GCC system_header 00034 00035 #if __cplusplus < 201103L 00036 # include <bits/c++0x_warning.h> 00037 #else 00038 #include <sstream> 00039 00040 namespace std _GLIBCXX_VISIBILITY(default) 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 namespace __detail { 00045 /** 00046 * @brief Struct for delimited strings. 00047 */ 00048 template<typename _String, typename _CharT> 00049 struct _Quoted_string 00050 { 00051 static_assert(is_reference<_String>::value 00052 || is_pointer<_String>::value, 00053 "String type must be pointer or reference"); 00054 00055 _Quoted_string(_String __str, _CharT __del, _CharT __esc) 00056 : _M_string(__str), _M_delim{__del}, _M_escape{__esc} 00057 { } 00058 00059 _Quoted_string& 00060 operator=(_Quoted_string&) = delete; 00061 00062 _String _M_string; 00063 _CharT _M_delim; 00064 _CharT _M_escape; 00065 }; 00066 00067 #if __cplusplus >= 201703L 00068 template<typename _CharT, typename _Traits> 00069 struct _Quoted_string<basic_string_view<_CharT, _Traits>, _CharT> 00070 { 00071 _Quoted_string(basic_string_view<_CharT, _Traits> __str, 00072 _CharT __del, _CharT __esc) 00073 : _M_string(__str), _M_delim{__del}, _M_escape{__esc} 00074 { } 00075 00076 _Quoted_string& 00077 operator=(_Quoted_string&) = delete; 00078 00079 basic_string_view<_CharT, _Traits> _M_string; 00080 _CharT _M_delim; 00081 _CharT _M_escape; 00082 }; 00083 #endif // C++17 00084 00085 /** 00086 * @brief Inserter for quoted strings. 00087 * 00088 * _GLIBCXX_RESOLVE_LIB_DEFECTS 00089 * DR 2344 quoted()'s interaction with padding is unclear 00090 */ 00091 template<typename _CharT, typename _Traits> 00092 std::basic_ostream<_CharT, _Traits>& 00093 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00094 const _Quoted_string<const _CharT*, _CharT>& __str) 00095 { 00096 std::basic_ostringstream<_CharT, _Traits> __ostr; 00097 __ostr << __str._M_delim; 00098 for (const _CharT* __c = __str._M_string; *__c; ++__c) 00099 { 00100 if (*__c == __str._M_delim || *__c == __str._M_escape) 00101 __ostr << __str._M_escape; 00102 __ostr << *__c; 00103 } 00104 __ostr << __str._M_delim; 00105 00106 return __os << __ostr.str(); 00107 } 00108 00109 /** 00110 * @brief Inserter for quoted strings. 00111 * 00112 * _GLIBCXX_RESOLVE_LIB_DEFECTS 00113 * DR 2344 quoted()'s interaction with padding is unclear 00114 */ 00115 template<typename _CharT, typename _Traits, typename _String> 00116 std::basic_ostream<_CharT, _Traits>& 00117 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00118 const _Quoted_string<_String, _CharT>& __str) 00119 { 00120 std::basic_ostringstream<_CharT, _Traits> __ostr; 00121 __ostr << __str._M_delim; 00122 for (auto __c : __str._M_string) 00123 { 00124 if (__c == __str._M_delim || __c == __str._M_escape) 00125 __ostr << __str._M_escape; 00126 __ostr << __c; 00127 } 00128 __ostr << __str._M_delim; 00129 00130 return __os << __ostr.str(); 00131 } 00132 00133 /** 00134 * @brief Extractor for delimited strings. 00135 * The left and right delimiters can be different. 00136 */ 00137 template<typename _CharT, typename _Traits, typename _Alloc> 00138 std::basic_istream<_CharT, _Traits>& 00139 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00140 const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&, 00141 _CharT>& __str) 00142 { 00143 _CharT __c; 00144 __is >> __c; 00145 if (!__is.good()) 00146 return __is; 00147 if (__c != __str._M_delim) 00148 { 00149 __is.unget(); 00150 __is >> __str._M_string; 00151 return __is; 00152 } 00153 __str._M_string.clear(); 00154 std::ios_base::fmtflags __flags 00155 = __is.flags(__is.flags() & ~std::ios_base::skipws); 00156 do 00157 { 00158 __is >> __c; 00159 if (!__is.good()) 00160 break; 00161 if (__c == __str._M_escape) 00162 { 00163 __is >> __c; 00164 if (!__is.good()) 00165 break; 00166 } 00167 else if (__c == __str._M_delim) 00168 break; 00169 __str._M_string += __c; 00170 } 00171 while (true); 00172 __is.setf(__flags); 00173 00174 return __is; 00175 } 00176 } // namespace __detail 00177 00178 _GLIBCXX_END_NAMESPACE_VERSION 00179 } // namespace std 00180 00181 #endif // C++11 00182 #endif /* _GLIBCXX_QUOTED_STRING_H */