|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63082 - in branches/filesystem3: boost/io libs/filesystem/v3/test libs/filesystem/v3/test/msvc/delimit_string_test libs/io/doc
From: bdawes_at_[hidden]
Date: 2010-06-18 12:37:35
Author: bemandawes
Date: 2010-06-18 12:37:34 EDT (Fri, 18 Jun 2010)
New Revision: 63082
URL: http://svn.boost.org/trac/boost/changeset/63082
Log:
Clean up code, add initial documentation draft
Added:
branches/filesystem3/libs/io/doc/quoted_manip.html (contents, props changed)
Text files modified:
branches/filesystem3/boost/io/quoted_manip.hpp | 79 ++++++++++++++++++++++++---------------
branches/filesystem3/libs/filesystem/v3/test/msvc/delimit_string_test/delimit_string_test.vcproj | 4 +-
branches/filesystem3/libs/filesystem/v3/test/quote_string_test.cpp | 27 ++++++-------
3 files changed, 64 insertions(+), 46 deletions(-)
Modified: branches/filesystem3/boost/io/quoted_manip.hpp
==============================================================================
--- branches/filesystem3/boost/io/quoted_manip.hpp (original)
+++ branches/filesystem3/boost/io/quoted_manip.hpp 2010-06-18 12:37:34 EDT (Fri, 18 Jun 2010)
@@ -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 @@
// ------------ 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 @@
: 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>&, Char>& proxy)
+ const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, 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 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 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 @@
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 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 @@
(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 @@
(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
Modified: branches/filesystem3/libs/filesystem/v3/test/msvc/delimit_string_test/delimit_string_test.vcproj
==============================================================================
--- branches/filesystem3/libs/filesystem/v3/test/msvc/delimit_string_test/delimit_string_test.vcproj (original)
+++ branches/filesystem3/libs/filesystem/v3/test/msvc/delimit_string_test/delimit_string_test.vcproj 2010-06-18 12:37:34 EDT (Fri, 18 Jun 2010)
@@ -2,7 +2,7 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
- Name="delimit_string_test"
+ Name="quote_string_test"
ProjectGUID="{2907CBB1-FFA6-49DE-A105-B75236214E1F}"
RootNamespace="delimit_string_test"
Keyword="Win32Proj"
@@ -177,7 +177,7 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
- RelativePath="..\..\delim_string_test.cpp"
+ RelativePath="..\..\quote_string_test.cpp"
>
</File>
</Filter>
Modified: branches/filesystem3/libs/filesystem/v3/test/quote_string_test.cpp
==============================================================================
--- branches/filesystem3/libs/filesystem/v3/test/quote_string_test.cpp (original)
+++ branches/filesystem3/libs/filesystem/v3/test/quote_string_test.cpp 2010-06-18 12:37:34 EDT (Fri, 18 Jun 2010)
@@ -1,31 +1,30 @@
-#include <boost/io/quote_manip.hpp>
+#include <boost/io/quoted_manip.hpp>
#include <iostream>
#include <sstream>
#include <cassert>
-using boost::io::quote;
-using boost::io::unquote;
+using boost::io::quoted;
int main()
{
- std::cout << quote(std::string("foo\\bar, \" *")) << std::endl;
- std::cout << quote("foo\\bar, \" *") << std::endl;
- std::cout << quote("foo & bar, \" *", '&') << std::endl;
- std::cout << quote("foo & bar, * ", '&', '*') << std::endl;
+ std::cout << quoted(std::string("foo\\bar, \" *")) << std::endl;
+ std::cout << quoted("foo\\bar, \" *") << std::endl;
+ std::cout << quoted("foo & bar, \" *", '&') << std::endl;
+ std::cout << quoted("foo & bar, * ", '&', '*') << std::endl;
- std::wcout << quote(L"foo$bar, \" *", L'$') << std::endl;
+ std::wcout << "Wide: " << quoted(L"foo$bar, \" *", L'$') << std::endl;
- std::string non_const_string("non_const_string");
- std::cout << quote(non_const_string) << '\n';
+ std::string non_const_string("non-const string");
+ std::cout << quoted(non_const_string) << '\n';
std::stringstream ss;
const std::string expected("foo\\bar, \" *");
std::string actual;
- ss << quote(expected);
- ss >> unquote(actual);
+ ss << quoted(expected);
+ ss >> quoted(actual);
std::cout << "round trip tests...\n";
std::cout << " expected--: " << expected << '\n';
@@ -34,8 +33,8 @@
assert(expected == actual);
// these should fail to compile because the arguments are non-const:
- // ss >> unquote(expected);
- // ss >> unquote("foo");
+ // ss >> quoted(expected);
+ // ss >> quoted("foo");
return 0;
}
Added: branches/filesystem3/libs/io/doc/quoted_manip.html
==============================================================================
--- (empty file)
+++ branches/filesystem3/libs/io/doc/quoted_manip.html 2010-06-18 12:37:34 EDT (Fri, 18 Jun 2010)
@@ -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>© Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010</p>
+<p>Distributed under the Boost Software License, Version 1.0. See
+www.boost.org/LICENSE_1_0.txt</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>
\ No newline at end of file
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk