mirror of
https://github.com/boostorg/io.git
synced 2025-07-31 20:54:29 +02:00
Clean up code, add initial documentation draft
[SVN r63082]
This commit is contained in:
145
doc/quoted_manip.html
Normal file
145
doc/quoted_manip.html
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Boost quoted string manipulator</title>
|
||||
<meta name="generator" content="Microsoft FrontPage 5.0" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../doc/html/minimal.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0"
|
||||
style="border-collapse: collapse">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="277"><a href="../../../index.htm"><img
|
||||
src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle"
|
||||
width="300" height="86" border="0" /></a></td>
|
||||
<td>
|
||||
<h1 align="center">Quoted String<br>
|
||||
Stream
|
||||
I/O Manipulator</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>C++ Standard library stream I/O for strings that contain embedded spaces
|
||||
can produce unexpected results. For example,</p>
|
||||
<blockquote>
|
||||
<pre>std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string round_trip;
|
||||
|
||||
ss << original;
|
||||
ss >> round_trip;
|
||||
|
||||
std::cout << original; // outputs: fooled you
|
||||
std::cout << round_trip; // outputs: fooled
|
||||
|
||||
assert(original == round_trip); // assert will fire</pre>
|
||||
</blockquote>
|
||||
<p>The Boost quoted string stream I/O manipulator places delimiters, defaulted
|
||||
to the double-quote (<code>"</code>), around strings on output, and strips off
|
||||
the delimiters on input. This ensures strings with embedded spaces round-trip as
|
||||
desired. For example,</p>
|
||||
<blockquote>
|
||||
<pre>std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string round_trip;
|
||||
|
||||
ss << quoted(original);
|
||||
ss >> quoted(round_trip);
|
||||
|
||||
std::cout << quoted(original); // outputs: "fooled you"
|
||||
std::cout << round_trip; // outputs: fooled you
|
||||
|
||||
assert(original == round_trip); // assert will not fire</pre>
|
||||
</blockquote>
|
||||
<h2>Header <boost/io/quoted_manip.hpp> synopsis</h2>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
// manipulator for const std::basic_string&
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
<b><i>unspecified-type1</i></b> quoted(const std::basic_string<Char, Traits, Alloc>& string, Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for const C-string*
|
||||
|
||||
template <class Char>
|
||||
<b><i>unspecified-type2</i></b> quoted(const Char* string, Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for non-const std::basic_string&
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
<b><i>unspecified-type3</i></b> quoted(std::basic_string<Char, Traits, Alloc>& string, Char escape='\\', Char delim='\"');
|
||||
}
|
||||
}</pre>
|
||||
<p><i><b><code>unspecified_type1</code></b></i>, <i><b><code>unspecified_type2</code></b></i>,
|
||||
and <i><b><code>unspecified_type3</code></b></i> are implementation supplied
|
||||
types with implementation supplied <code>operator<<</code>:</p>
|
||||
<blockquote>
|
||||
<pre>template <class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os, const <i><b><code>unspecified_typeN</code></b></i>& proxy);</pre>
|
||||
<p><i>Effects:</i> Inserts characters into <code>os</code>:</p>
|
||||
<ul>
|
||||
<li><code>delim</code>.</li>
|
||||
<li>Each character in <code>string</code>. If the character to be output is
|
||||
equal to <code>escape</code> or <code>delim</code>, as determined by <code>
|
||||
operator==</code>, first output <code>escape</code>. </li>
|
||||
<li><code>delim</code>.</li>
|
||||
</ul>
|
||||
<p><i>Remarks:</i> <code>string</code>, <code>escape</code>, and <code>delim</code>
|
||||
have the type and value of the corresponding arguments of the call to the <code>
|
||||
quoted</code> function that constructed <code>proxy</code>.</p>
|
||||
<p><i>Returns:</i> <code>os</code>. </p>
|
||||
</blockquote>
|
||||
<p><i><b><code>unspecified_type3</code></b></i> is an implementation supplied
|
||||
type with an implementation supplied <code>operator>></code>:</p>
|
||||
<blockquote>
|
||||
<pre>template <class Char, class Traits>
|
||||
std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is, const <i><b><code>unspecified_type3</code></b></i>& proxy);</pre>
|
||||
<p><i>Effects:</i> Extracts characters from <code>os</code>:</p>
|
||||
<ul>
|
||||
<li>If the first character extracted is equal to delim, as determined by
|
||||
<code>operator==</code>, then:<ul>
|
||||
<li>Turn off the <code>skipws</code> flag.</li>
|
||||
<li><code>string.clear()</code></li>
|
||||
<li>Until an unescaped <code>delim</code> character is reached, extract
|
||||
characters from <code>os</code> and append them to <code>string</code>,
|
||||
except that if an <code>escape</code> is reached, ignore it and append the
|
||||
next character to <code>string</code>.</li>
|
||||
<li>Discard the final <code>delim</code> character.</li>
|
||||
<li>Restore the <code>skipws</code> flag to its original value.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Otherwise, <code>os >> string</code>.</li>
|
||||
</ul>
|
||||
<p><i>Remarks:</i> <code>string</code>, <code>escape</code>, and <code>delim</code>
|
||||
have the type and value of the corresponding arguments of the call to the <code>
|
||||
quoted</code> function that constructed <code>proxy</code>.</p>
|
||||
<p><i>Returns:</i> <code>is</code>. </p>
|
||||
</blockquote>
|
||||
<h2>Acknowledgements</h2>
|
||||
<p>The <code>quoted()</code> stream manipulator emerged from discussions on the
|
||||
Boost developers mailing list. Participants included Beman Dawes, Rob Stewart,
|
||||
Alexander Lamaison, Eric Niebler, Vicente Botet, Andrey Semashev, Phil Richards,
|
||||
and Rob Murray. Eric Niebler's suggestions provided the basis for the name and
|
||||
form of the templates. </p>
|
||||
<hr>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->18 June 2010<!--webbot bot="Timestamp" endspan i-checksum="17559" --></p>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,12 +1,16 @@
|
||||
// boost/io/quoted_manip.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Library home page http://www.boost.org/libs/io
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_QUOTE_MANIP
|
||||
#define BOOST_QUOTE_MANIP
|
||||
#ifndef BOOST_IO_QUOTED_MANIP
|
||||
#define BOOST_IO_QUOTED_MANIP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
@@ -20,25 +24,28 @@ namespace boost
|
||||
|
||||
// ------------ public interface ------------------------------------------------//
|
||||
|
||||
// manipulator for const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
template <class Char>
|
||||
detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for non-const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& s,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for const C-string*
|
||||
template <class Char>
|
||||
detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape='\\', Char delim='\"');
|
||||
|
||||
// ----------- implementation details -------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// proxy used as an argument pack
|
||||
template <class String, class Char>
|
||||
struct quoted_proxy
|
||||
{
|
||||
@@ -50,34 +57,45 @@ namespace boost
|
||||
: string(s_), escape(escape_), delim(delim_) {}
|
||||
};
|
||||
|
||||
// abstract away difference between proxies with const or non-const basic_strings
|
||||
template <class Char, class Traits, class Alloc>
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
|
||||
std::basic_ostream<Char, Traits>&
|
||||
basic_string_inserter_imp(std::basic_ostream<Char, Traits>& os,
|
||||
std::basic_string<Char, Traits, Alloc> const & string, Char escape, Char delim)
|
||||
{
|
||||
os << proxy.delim;
|
||||
std::basic_string<Char, Traits, Alloc>::const_iterator end_it = proxy.string.end();
|
||||
for (std::basic_string<Char, Traits, Alloc>::const_iterator it = proxy.string.begin();
|
||||
os << delim;
|
||||
std::basic_string<Char, Traits, Alloc>::const_iterator end_it = string.end();
|
||||
for (std::basic_string<Char, Traits, Alloc>::const_iterator it = string.begin();
|
||||
it != end_it;
|
||||
++it )
|
||||
{
|
||||
if (*it == proxy.delim || *it == proxy.escape)
|
||||
os << proxy.escape;
|
||||
if (*it == delim || *it == escape)
|
||||
os << escape;
|
||||
os << *it;
|
||||
}
|
||||
os << proxy.delim;
|
||||
os << delim;
|
||||
return os;
|
||||
}
|
||||
|
||||
// inserter for const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
|
||||
{
|
||||
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
|
||||
}
|
||||
|
||||
// inserter for non-const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||
{
|
||||
return os <<
|
||||
*reinterpret_cast<const quoted_proxy<std::basic_string
|
||||
<Char, Traits, Alloc> const &, Char>*>(&proxy);
|
||||
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
|
||||
}
|
||||
|
||||
|
||||
// inserter for const C-string* proxies
|
||||
template <class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const Char*, Char>& proxy)
|
||||
@@ -95,6 +113,7 @@ namespace boost
|
||||
return os;
|
||||
}
|
||||
|
||||
// extractor for non-const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||
@@ -126,8 +145,7 @@ namespace boost
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// manipulator implementations
|
||||
|
||||
// manipulator implementation for const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||
@@ -136,14 +154,7 @@ namespace boost
|
||||
(s, escape, delim);
|
||||
}
|
||||
|
||||
template <class Char>
|
||||
inline detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape, Char delim)
|
||||
{
|
||||
return detail::quoted_proxy<const Char*, Char> (s, escape, delim);
|
||||
}
|
||||
|
||||
|
||||
// manipulator implementation for non-const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||
@@ -152,7 +163,15 @@ namespace boost
|
||||
(s, escape, delim);
|
||||
}
|
||||
|
||||
// manipulator implementation for const C-string*
|
||||
template <class Char>
|
||||
inline detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape, Char delim)
|
||||
{
|
||||
return detail::quoted_proxy<const Char*, Char> (s, escape, delim);
|
||||
}
|
||||
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_QUOTE_MANIP
|
||||
#endif // BOOST_IO_QUOTED_MANIP
|
||||
|
Reference in New Issue
Block a user