Commit 83ac9249 by Ed Smith-Rowland Committed by Edward Smith-Rowland

Implement N3654 - Quoted Strings Library Proposal

2013-06-08  Ed Smith-Rowland  <3dw4rd@verizon.net>

	Implement N3654 - Quoted Strings Library Proposal
	* include/std/iomanip: Add quoted(String, Char delim, Char escape)
	manipulators and supporting machinery in c++1y mode.
	* testsuite/27_io/manipulators/standard/char/quoted.cc: New.
	* testsuite/27_io/manipulators/standard/wchar_t/quoted.cc: New.

From-SVN: r199860
parent ed52a84e
2013-06-08 Ed Smith-Rowland <3dw4rd@verizon.net>
Implement N3654 - Quoted Strings Library Proposal
* include/std/iomanip: Add quoted(String, Char delim, Char escape)
manipulators and supporting machinery in c++1y mode.
* testsuite/27_io/manipulators/standard/char/quoted.cc: New.
* testsuite/27_io/manipulators/standard/wchar_t/quoted.cc: New.
2013-06-08 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/bits/alloc_traits.h (allocator_traits::max_size()): LWG
......
......@@ -334,7 +334,160 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __os;
}
#endif
#if __cplusplus > 201103L
namespace __detail {
/**
* @brief Struct for delimited strings.
* The left and right delimiters can be different.
*/
template<typename _String, typename _CharT>
struct _Quoted_string
{
static_assert(is_reference<_String>::value
|| is_pointer<_String>::value,
"String type must be pointer or reference");
_Quoted_string(_String __str, _CharT __del, _CharT __esc)
: _M_string(__str), _M_delim{__del}, _M_escape{__esc}
{ }
_Quoted_string&
operator=(_Quoted_string&) = delete;
_String _M_string;
_CharT _M_delim;
_CharT _M_escape;
};
/**
* @brief Inserter for delimited strings.
* The left and right delimiters can be different.
*/
template<typename _CharT, typename _Traits>
auto&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const _Quoted_string<const _CharT*, _CharT>& __str)
{
__os << __str._M_delim;
for (const _CharT* __c = __str._M_string; *__c; ++__c)
{
if (*__c == __str._M_delim || *__c == __str._M_escape)
__os << __str._M_escape;
__os << *__c;
}
__os << __str._M_delim;
return __os;
}
/**
* @brief Inserter for delimited strings.
* The left and right delimiters can be different.
*/
template<typename _CharT, typename _Traits, typename _String>
auto&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const _Quoted_string<_String, _CharT>& __str)
{
__os << __str._M_delim;
for (auto& __c : __str._M_string)
{
if (__c == __str._M_delim || __c == __str._M_escape)
__os << __str._M_escape;
__os << __c;
}
__os << __str._M_delim;
return __os;
}
/**
* @brief Extractor for delimited strings.
* The left and right delimiters can be different.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
auto&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
_CharT>& __str)
{
__str._M_string.clear();
_CharT __c;
__is >> __c;
if (!__is.good())
return __is;
if (__c != __str._M_delim)
{
__is.unget();
__is >> __str._M_string;
return __is;
}
std::ios_base::fmtflags __flags
= __is.flags(__is.flags() & ~std::ios_base::skipws);
do
{
__is >> __c;
if (!__is.good())
break;
if (__c == __str._M_escape)
{
__is >> __c;
if (!__is.good())
break;
}
else if (__c == __str._M_delim)
break;
__str._M_string += __c;
}
while (true);
__is.setf(__flags);
return __is;
}
} // namespace __detail
/**
* @brief Manipulator for quoted strings.
* @param __str String to quote.
* @param __delim Character to quote string with.
* @param __escape Escape character to escape itself or quote character.
*/
template<typename _CharT>
inline auto
quoted(const _CharT* __string,
_CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
return __detail::_Quoted_string<const _CharT*, _CharT>(__string, __delim,
__escape);
}
template<typename _CharT, typename _Traits, typename _Alloc>
inline auto
quoted(const basic_string<_CharT, _Traits, _Alloc>& __string,
_CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
return __detail::_Quoted_string<
const basic_string<_CharT, _Traits, _Alloc>&, _CharT>(
__string, __delim, __escape);
}
template<typename _CharT, typename _Traits, typename _Alloc>
inline auto
quoted(basic_string<_CharT, _Traits, _Alloc>& __string,
_CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
{
return __detail::_Quoted_string<
basic_string<_CharT, _Traits, _Alloc>&, _CharT>(
__string, __delim, __escape);
}
#endif // __cplusplus > 201103L
#endif // __cplusplus >= 201103L
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
......
// { dg-do run }
// { dg-options "-std=gnu++1y" }
// Copyright (C) 2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// 27.7.6 - Quoted manipulators [quoted.manip]
#include <string>
#include <sstream>
#include <iomanip>
#include <testsuite_hooks.h>
void
test01()
{
// Basic test from paper.
bool test [[gnu::unused]] = true;
std::stringstream ss;
std::string original = "foolish me";
std::string round_trip;
ss << std::quoted(original);
ss >> std::quoted(round_trip);
VERIFY( original == round_trip );
}
void
test02()
{
// Test skipws correctness.
bool test [[gnu::unused]] = true;
std::stringstream ss;
ss << std::quoted("Hello Goodbye") << ' ' << 1 << ' ' << 2;
std::string song;
int thing1, thing2;
ss >> std::quoted(song) >> thing1 >> thing2;
VERIFY( song == "Hello Goodbye" );
VERIFY( thing1 == 1 );
VERIFY( thing2 == 2 );
}
void
test03()
{
// Test read of unquoted string.
bool test [[gnu::unused]] = true;
std::stringstream ss;
ss << "Alpha Omega";
std::string testit;
ss >> std::quoted(testit);
VERIFY( testit == "Alpha" );
}
auto
test04(const std::string& message)
{
// Test 'const basic_string&'
bool test [[gnu::unused]] = true;
std::stringstream ss;
ss << "** Error: " << std::quoted(message) << " **";
return ss.str();
}
int
main()
{
test01();
test02();
test03();
auto ss = test04("My biscuits are burnin'!");
VERIFY( ss == "** Error: \"My biscuits are burnin'!\" **" );
return 0;
}
// { dg-do run }
// { dg-options "-std=gnu++1y" }
// Copyright (C) 2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// 27.7.6 - Quoted manipulators [quoted.manip]
#include <string>
#include <sstream>
#include <iomanip>
#include <testsuite_hooks.h>
void
test01()
{
// Basic test from paper.
bool test [[gnu::unused]] = true;
std::wstringstream ss;
std::wstring original = L"foolish me";
std::wstring round_trip;
ss << std::quoted(original);
ss >> std::quoted(round_trip);
VERIFY( original == round_trip );
}
void
test02()
{
// Test skipws correctness.
bool test [[gnu::unused]] = true;
std::wstringstream ss;
ss << std::quoted(L"Hello Goodbye") << L' ' << 1 << L' ' << 2;
std::wstring song;
int thing1, thing2;
ss >> std::quoted(song) >> thing1 >> thing2;
VERIFY( song == L"Hello Goodbye" );
VERIFY( thing1 == 1 );
VERIFY( thing2 == 2 );
}
void
test03()
{
// Test read of unquoted string.
bool test [[gnu::unused]] = true;
std::wstringstream ss;
ss << L"Alpha Omega";
std::wstring testit;
ss >> std::quoted(testit);
VERIFY( testit == L"Alpha" );
}
auto
test04(const std::wstring& message)
{
// Test 'const basic_string&'
bool test [[gnu::unused]] = true;
std::wstringstream ss;
ss << L"** Error: " << std::quoted(message) << L" **";
return ss.str();
}
int
main()
{
test01();
test02();
test03();
auto ss = test04(L"My biscuits are burnin'!");
VERIFY( ss == L"** Error: \"My biscuits are burnin'!\" **" );
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment