mirror of
https://github.com/boostorg/io.git
synced 2025-08-02 21:54:26 +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
|
// Copyright Beman Dawes 2010
|
||||||
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// See http://www.boost.org/LICENSE_1_0.txt
|
// See http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
// Library home page http://www.boost.org/libs/io
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifndef BOOST_QUOTE_MANIP
|
#ifndef BOOST_IO_QUOTED_MANIP
|
||||||
#define BOOST_QUOTE_MANIP
|
#define BOOST_IO_QUOTED_MANIP
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -20,25 +24,28 @@ namespace boost
|
|||||||
|
|
||||||
// ------------ public interface ------------------------------------------------//
|
// ------------ public interface ------------------------------------------------//
|
||||||
|
|
||||||
|
// manipulator for const std::basic_string&
|
||||||
template <class Char, class Traits, class Alloc>
|
template <class Char, class Traits, class Alloc>
|
||||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||||
quoted(const std::basic_string<Char, Traits, Alloc>& s,
|
quoted(const std::basic_string<Char, Traits, Alloc>& s,
|
||||||
Char escape='\\', Char delim='\"');
|
Char escape='\\', Char delim='\"');
|
||||||
|
|
||||||
template <class Char>
|
// manipulator for non-const std::basic_string&
|
||||||
detail::quoted_proxy<const Char*, Char>
|
|
||||||
quoted(const Char* s, Char escape='\\', Char delim='\"');
|
|
||||||
|
|
||||||
template <class Char, class Traits, class Alloc>
|
template <class Char, class Traits, class Alloc>
|
||||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||||
quoted(std::basic_string<Char, Traits, Alloc>& s,
|
quoted(std::basic_string<Char, Traits, Alloc>& s,
|
||||||
Char escape='\\', Char delim='\"');
|
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 -------------------------------------------//
|
// ----------- implementation details -------------------------------------------//
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
// proxy used as an argument pack
|
||||||
template <class String, class Char>
|
template <class String, class Char>
|
||||||
struct quoted_proxy
|
struct quoted_proxy
|
||||||
{
|
{
|
||||||
@@ -50,34 +57,45 @@ namespace boost
|
|||||||
: string(s_), escape(escape_), delim(delim_) {}
|
: 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>
|
template <class Char, class Traits, class Alloc>
|
||||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
std::basic_ostream<Char, Traits>&
|
||||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
|
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;
|
os << delim;
|
||||||
std::basic_string<Char, Traits, Alloc>::const_iterator end_it = proxy.string.end();
|
std::basic_string<Char, Traits, Alloc>::const_iterator end_it = string.end();
|
||||||
for (std::basic_string<Char, Traits, Alloc>::const_iterator it = proxy.string.begin();
|
for (std::basic_string<Char, Traits, Alloc>::const_iterator it = string.begin();
|
||||||
it != end_it;
|
it != end_it;
|
||||||
++it )
|
++it )
|
||||||
{
|
{
|
||||||
if (*it == proxy.delim || *it == proxy.escape)
|
if (*it == delim || *it == escape)
|
||||||
os << proxy.escape;
|
os << escape;
|
||||||
os << *it;
|
os << *it;
|
||||||
}
|
}
|
||||||
os << proxy.delim;
|
os << delim;
|
||||||
return os;
|
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>
|
template <class Char, class Traits, class Alloc>
|
||||||
inline
|
inline
|
||||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||||
{
|
{
|
||||||
return os <<
|
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
|
||||||
*reinterpret_cast<const quoted_proxy<std::basic_string
|
|
||||||
<Char, Traits, Alloc> const &, Char>*>(&proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inserter for const C-string* proxies
|
||||||
template <class Char, class Traits>
|
template <class Char, class Traits>
|
||||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||||
const quoted_proxy<const Char*, Char>& proxy)
|
const quoted_proxy<const Char*, Char>& proxy)
|
||||||
@@ -95,6 +113,7 @@ namespace boost
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractor for non-const std::basic_string& proxies
|
||||||
template <class Char, class Traits, class Alloc>
|
template <class Char, class Traits, class Alloc>
|
||||||
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
|
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
|
||||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||||
@@ -126,8 +145,7 @@ namespace boost
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// manipulator implementations
|
// manipulator implementation for const std::basic_string&
|
||||||
|
|
||||||
template <class Char, class Traits, class Alloc>
|
template <class Char, class Traits, class Alloc>
|
||||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
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)
|
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||||
@@ -136,14 +154,7 @@ namespace boost
|
|||||||
(s, escape, delim);
|
(s, escape, delim);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Char>
|
// manipulator implementation for non-const std::basic_string&
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Char, class Traits, class Alloc>
|
template <class Char, class Traits, class Alloc>
|
||||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||||
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||||
@@ -152,7 +163,15 @@ namespace boost
|
|||||||
(s, escape, delim);
|
(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 io
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_QUOTE_MANIP
|
#endif // BOOST_IO_QUOTED_MANIP
|
||||||
|
Reference in New Issue
Block a user