146 lines
4.2 KiB
Plaintext
146 lines
4.2 KiB
Plaintext
////
|
|
Copyright 2019 Glen Joseph Fernandes
|
|
(glenjofe@gmail.com)
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(http://www.boost.org/LICENSE_1_0.txt)
|
|
////
|
|
|
|
# Quoted Manipulators, <boost/io/quoted.hpp>
|
|
:toc:
|
|
:toc-title:
|
|
:idprefix:
|
|
|
|
## 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 roundtrip;
|
|
|
|
ss << original;
|
|
ss >> roundtrip;
|
|
|
|
std::cout << original; // outputs: fooled you
|
|
std::cout << roundtrip; // outputs: fooled
|
|
|
|
assert(original == roundtrip); // assert will fire
|
|
```
|
|
|
|
The Boost quoted 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 roundtrip;
|
|
|
|
ss << quoted(original);
|
|
ss >> quoted(roundtrip);
|
|
|
|
std::cout << quoted(original); // outputs: "fooled you"
|
|
std::cout << roundtrip; // outputs: fooled you
|
|
|
|
assert(original == roundtrip); // assert will not fire
|
|
```
|
|
|
|
If the string contains the delimiter character, on output that character will
|
|
be preceded by an escape character, as will the escape character itself:
|
|
|
|
```
|
|
std::cout << quoted("'Jack & Jill'", '&', '\''); // outputs: '&'Jack && Jill&''
|
|
```
|
|
|
|
## Header synopsis
|
|
|
|
[subs=+quotes]
|
|
```
|
|
namespace boost {
|
|
namespace io {
|
|
|
|
template<class Char, class Traits, class Alloc>
|
|
`unspecified-type1`
|
|
quoted(const std::basic_string<Char, Traits, Alloc>& string,
|
|
Char escape='\\', Char delim='\"');
|
|
|
|
template<class Char>
|
|
`unspecified-type2`
|
|
quoted(const Char* string, Char escape='\\', Char delim='\"');
|
|
|
|
template<class Char, class Traits, class Alloc>
|
|
`unspecified-type3`
|
|
quoted(std::basic_string<Char, Traits, Alloc>& string,
|
|
Char escape='\\', Char delim='\"');
|
|
|
|
} // io
|
|
} // boost
|
|
```
|
|
|
|
*unspecified-type1*, *unspecified-type2*, and *unspecified-type3* are
|
|
implementation supplied types with implementation supplied `operator<<`:
|
|
|
|
[subs=+quotes]
|
|
```
|
|
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`:
|
|
* `delim`
|
|
* Each character in `string`. If the character to be output is equal to
|
|
`escape` or `delim`, as determined by `operator==`, first output `escape`.
|
|
* `delim`
|
|
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>>`:
|
|
|
|
[subs=+quotes]
|
|
```
|
|
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`:
|
|
* If the first character extracted is equal to `delim`, as determined by
|
|
`operator==`, then:
|
|
** Turn off the `skipws` flag.
|
|
** `string.clear()`
|
|
** Until an unescaped `delim` character is reached or `is.not_good()`, extract
|
|
characters from `os` and append them to string, except that if an escape is
|
|
reached, ignore it and append the next character to string.
|
|
** Discard the final `delim` character.
|
|
** Restore the `skipws` flag to its original value.
|
|
* Otherwise, `os >> string`.
|
|
|
|
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.
|
|
|
|
Beman Dawes started the implementation of `quoted()` as a private detail
|
|
header. Glen Fernandes updated the implementation and also made it public.
|
|
|
|
Glen Fernandes corrected the implementation to properly account for stream
|
|
width and fill, and optimized it to write directly to the stream buffer.
|