From cab10052da2e9447542eab097fab4dd6b768894d Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Fri, 18 Jun 2010 16:37:34 +0000 Subject: [PATCH] Clean up code, add initial documentation draft [SVN r63082] --- doc/quoted_manip.html | 145 ++++++++++++++++++++++++++++++ include/boost/io/quoted_manip.hpp | 79 +++++++++------- 2 files changed, 194 insertions(+), 30 deletions(-) create mode 100644 doc/quoted_manip.html diff --git a/doc/quoted_manip.html b/doc/quoted_manip.html new file mode 100644 index 0000000..4391941 --- /dev/null +++ b/doc/quoted_manip.html @@ -0,0 +1,145 @@ + + + + + + Boost quoted string manipulator + + + + + + + + + + + + + +
boost.png (6897 bytes) +

Quoted String
+ Stream + I/O Manipulator

+
+ +

Introduction

+

C++ Standard library stream I/O for strings that contain embedded spaces +can produce unexpected results. For example,

+
+
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
+
+

The Boost quoted string stream I/O manipulator places delimiters, defaulted +to the double-quote ("), around strings on output, and strips off +the delimiters on input. This ensures strings with embedded spaces round-trip as +desired. For example,

+
+
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
+
+

Header <boost/io/quoted_manip.hpp> synopsis

+
namespace boost
+{
+  namespace io
+  {
+    // manipulator for const std::basic_string&
+
+    template <class Char, class Traits, class Alloc>
+    unspecified-type1 quoted(const std::basic_string<Char, Traits, Alloc>& string, Char escape='\\', Char delim='\"');
+
+    // manipulator for const C-string*
+
+    template <class Char>
+    unspecified-type2 quoted(const Char* string, Char escape='\\', Char delim='\"');
+
+    // manipulator for non-const std::basic_string&
+
+    template <class Char, class Traits, class Alloc>
+    unspecified-type3 quoted(std::basic_string<Char, Traits, Alloc>& string, Char escape='\\', Char delim='\"');
+  }
+}
+

unspecified_type1, unspecified_type2, +and unspecified_type3 are implementation supplied +types with implementation supplied operator<<:

+
+
template <class Char, class Traits>
+  std::basic_ostream<Char, Traits>&
+    operator<<(std::basic_ostream<Char, Traits>& os, const unspecified_typeN& proxy);
+

Effects: Inserts characters into os:

+ +

Remarks: string, escape, and delim +have the type and value of the corresponding arguments of the call to the +quoted function that constructed proxy.

+

Returns: os.

+
+

unspecified_type3 is an implementation supplied +type with an implementation supplied operator>>:

+
+
template <class Char, class Traits>
+  std::basic_istream<Char, Traits>&
+    operator>>(std::basic_istream<Char, Traits>& is, const unspecified_type3& proxy);
+

Effects: Extracts characters from os:

+ +

Remarks: string, escape, and delim +have the type and value of the corresponding arguments of the call to the +quoted function that constructed proxy.

+

Returns: is.

+
+

Acknowledgements

+

The quoted() 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.

+
+

© Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010

+

Distributed under the Boost Software License, Version 1.0. See +www.boost.org/LICENSE_1_0.txt

+

Revised +18 June 2010

+ + + \ No newline at end of file diff --git a/include/boost/io/quoted_manip.hpp b/include/boost/io/quoted_manip.hpp index 325f14b..48253d3 100644 --- a/include/boost/io/quoted_manip.hpp +++ b/include/boost/io/quoted_manip.hpp @@ -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 #include @@ -20,25 +24,28 @@ namespace boost // ------------ public interface ------------------------------------------------// + // manipulator for const std::basic_string& template detail::quoted_proxy const &, Char> quoted(const std::basic_string& s, Char escape='\\', Char delim='\"'); - template - detail::quoted_proxy - quoted(const Char* s, Char escape='\\', Char delim='\"'); - + // manipulator for non-const std::basic_string& template detail::quoted_proxy &, Char> quoted(std::basic_string& s, Char escape='\\', Char delim='\"'); + // manipulator for const C-string* + template + detail::quoted_proxy + quoted(const Char* s, Char escape='\\', Char delim='\"'); + // ----------- implementation details -------------------------------------------// namespace detail { - + // proxy used as an argument pack template 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 - std::basic_ostream& operator<<(std::basic_ostream& os, - const quoted_proxy const &, Char>& proxy) + std::basic_ostream& + basic_string_inserter_imp(std::basic_ostream& os, + std::basic_string const & string, Char escape, Char delim) { - os << proxy.delim; - std::basic_string::const_iterator end_it = proxy.string.end(); - for (std::basic_string::const_iterator it = proxy.string.begin(); + os << delim; + std::basic_string::const_iterator end_it = string.end(); + for (std::basic_string::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 + inline + std::basic_ostream& operator<<(std::basic_ostream& os, + const quoted_proxy const &, Char>& proxy) + { + return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); + } + + // inserter for non-const std::basic_string& proxies template inline std::basic_ostream& operator<<(std::basic_ostream& os, const quoted_proxy&, Char>& proxy) { - return os << - *reinterpret_cast const &, Char>*>(&proxy); + return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); } - + + // inserter for const C-string* proxies template std::basic_ostream& operator<<(std::basic_ostream& os, const quoted_proxy& proxy) @@ -95,6 +113,7 @@ namespace boost return os; } + // extractor for non-const std::basic_string& proxies template std::basic_istream& operator>>(std::basic_istream& is, const quoted_proxy&, Char>& proxy) @@ -126,8 +145,7 @@ namespace boost } // namespace detail - // manipulator implementations - + // manipulator implementation for const std::basic_string& template inline detail::quoted_proxy const &, Char> quoted(const std::basic_string& s, Char escape, Char delim) @@ -136,14 +154,7 @@ namespace boost (s, escape, delim); } - template - inline detail::quoted_proxy - quoted(const Char* s, Char escape, Char delim) - { - return detail::quoted_proxy (s, escape, delim); - } - - + // manipulator implementation for non-const std::basic_string& template inline detail::quoted_proxy &, Char> quoted(std::basic_string& s, Char escape, Char delim) @@ -152,7 +163,15 @@ namespace boost (s, escape, delim); } + // manipulator implementation for const C-string* + template + inline detail::quoted_proxy + quoted(const Char* s, Char escape, Char delim) + { + return detail::quoted_proxy (s, escape, delim); + } + } // namespace io } // namespace boost -#endif // BOOST_QUOTE_MANIP +#endif // BOOST_IO_QUOTED_MANIP