mirror of
https://github.com/boostorg/io.git
synced 2025-06-25 03:51:36 +02:00
Merge branch 'develop'
This commit is contained in:
5
doc/io-docinfo-footer.html
Normal file
5
doc/io-docinfo-footer.html
Normal file
@ -0,0 +1,5 @@
|
||||
<style>
|
||||
.specification {
|
||||
margin-left: 2em;
|
||||
}
|
||||
</style>
|
10
doc/io.adoc
10
doc/io.adoc
@ -7,18 +7,20 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
////
|
||||
|
||||
# Boost.IO
|
||||
Daryle Walker, Beman Dawes
|
||||
Daryle Walker, Beman Dawes, Glen Joseph Fernandes <glenjofe@gmail.com>
|
||||
:docinfo: private-footer
|
||||
:idprefix:
|
||||
:source-language: cpp
|
||||
:toc: left
|
||||
|
||||
The I/O sub-library of Boost helps segregate the large number of Boost headers.
|
||||
This sub-library should contain various items to use with/for the standard I/O
|
||||
library.
|
||||
This library contains various utilities for the standard I/O library.
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
include::ios_state.adoc[]
|
||||
include::quoted.adoc[]
|
||||
include::ostream_joiner.adoc[]
|
||||
include::ostream_put.adoc[]
|
||||
|
||||
:leveloffset: -1
|
||||
|
||||
|
@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
# ios_state, <boost/io/ios_state.hpp>
|
||||
# IO State Savers, <boost/io/ios_state.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
143
doc/ostream_joiner.adoc
Normal file
143
doc/ostream_joiner.adoc
Normal file
@ -0,0 +1,143 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Delimited Iterators, <boost/io/ostream_joiner.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/ostream_joiner.hpp>` provides the class template
|
||||
`boost::io::ostream_joiner` which is an output iterator that writes objects to
|
||||
a `std::basic_ostream` separated by a delimiter. It is an implementation of
|
||||
the Library Fundamentals TS `std::ostream_joiner` which supports {cpp}03 and
|
||||
higher.
|
||||
|
||||
## Example
|
||||
|
||||
The following program writes the contents of a vector to standard output, with
|
||||
each element separated by a comma.
|
||||
|
||||
```
|
||||
#include <boost/io/ostream_joiner.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<int> v;
|
||||
v.push_back(2);
|
||||
v.push_back(4);
|
||||
v.push_back(6);
|
||||
v.push_back(8);
|
||||
std::copy(v.begin(), v.end(), boost::make_ostream_joiner(std::cout, ','));
|
||||
}
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class Delim, class Char = char,
|
||||
class Traits = std::char_traits<Char> >
|
||||
class ostream_joiner {
|
||||
public:
|
||||
typedef Char char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef std::basic_ostream<Char, Traits> ostream_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
ostream_joiner(ostream_type& output, const Delim& delim);
|
||||
ostream_joiner(ostream_type& output, Delim&& delim);
|
||||
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value);
|
||||
|
||||
ostream_joiner& operator*() noexcept;
|
||||
ostream_joiner& operator++() noexcept;
|
||||
ostream_joiner& operator++(int) noexcept;
|
||||
};
|
||||
|
||||
template<class Char, class Traits, class Delim>
|
||||
ostream_joiner<std::decay_t<Delim>, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim);
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
### Constructors
|
||||
|
||||
```
|
||||
ostream_joiner(ostream_type& output, const Delim& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
EFfects:: Initializes the stored reference to the stream with
|
||||
`std::addressof(output)` and the stored delimiter with `delim`.
|
||||
|
||||
```
|
||||
ostream_joiner(ostream_type& output, Delim&& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
EFfects:: Initializes the stored reference to the stream with
|
||||
`std::addressof(output)` and the stored delimiter with `std::move(delim)`.
|
||||
|
||||
### Member functions
|
||||
|
||||
```
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Effects::
|
||||
* If the is the first call to this member function, write the stored delimiter
|
||||
to the stored stream reference.
|
||||
* Writes `value` to the stored stream reference.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
ostream_joiner& operator*() noexcept;
|
||||
```
|
||||
```
|
||||
ostream_joiner& operator++() noexcept;
|
||||
```
|
||||
```
|
||||
ostream_joiner& operator++(int) noexcept;
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Returns:: `*this`.
|
||||
|
||||
### Free functions
|
||||
|
||||
```
|
||||
template<class Char, class Traits, class Delim>
|
||||
ostream_joiner<decay_t<Delim>, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Returns:: `ostream_joiner<std::decay_t<Delim>, Char, Traits>(output,
|
||||
std::forward<Delim>(delim))`.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Glen Fernandes implemented `ostream_joiner` and `make_ostream_joiner`.
|
73
doc/ostream_put.adoc
Normal file
73
doc/ostream_put.adoc
Normal file
@ -0,0 +1,73 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Insert Formatted Output, <boost/io/ostream_put.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/ostream_put.hpp>` provides the function template
|
||||
`boost::io::ostream_put` for formatted output that satisfies the requirements
|
||||
of [ostream.formatted.reqmts].
|
||||
|
||||
## Example
|
||||
|
||||
The inserter for class template `basic_string_view` could be implemented as
|
||||
follows:
|
||||
|
||||
```
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os,
|
||||
const basic_string_view<charT, traits>& str)
|
||||
{
|
||||
return boost::io::ostream_put(os, str.data(), str.size());
|
||||
}
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os,
|
||||
const charT* data, std::size_t size);
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
### Free functions
|
||||
|
||||
```
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os,
|
||||
const charT* data, std::size_t size);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Effects:: Behaves like a formatted inserter (as described in
|
||||
[ostream.formatted.reqmts]) of `os`. Creates a character sequence `seq` of size
|
||||
characters starting at `data`, each widened using `os.widen()`
|
||||
([basic.ios.members]). Determines padding for `seq` as described in
|
||||
[ostream.formatted.reqmts]. Inserts `seq` into `os`. Calls `width(0)`.
|
||||
Returns:: `os`.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Glen Fernandes updated the implementation of the `basic_string_ref` and
|
||||
`basic_string_view` stream insertion operators to write directly to the
|
||||
`basic_streambuf` and refactored that functionality into this common utility.
|
@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
# quoted, <boost/io/quoted.hpp>
|
||||
# Quoted Manipulators, <boost/io/quoted.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
@ -137,3 +137,6 @@ 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.
|
||||
|
@ -1,190 +1,18 @@
|
||||
// boost/io/quoted_manip.hpp ---------------------------------------------------------//
|
||||
/*
|
||||
Copyright 2010 Beman Dawes
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_DETAIL_QUOTED_MANIP_HPP
|
||||
#define BOOST_IO_DETAIL_QUOTED_MANIP_HPP
|
||||
|
||||
// Library home page http://www.boost.org/libs/io
|
||||
/*
|
||||
The new implemenation is public in <boost/io/quoted.hpp>
|
||||
*/
|
||||
#include <boost/io/quoted.hpp>
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_IO_QUOTED_MANIP
|
||||
#define BOOST_IO_QUOTED_MANIP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
namespace detail { template <class String, class Char> struct quoted_proxy; }
|
||||
|
||||
// ------------ 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='\"');
|
||||
|
||||
// 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
|
||||
{
|
||||
String string;
|
||||
Char escape;
|
||||
Char delim;
|
||||
|
||||
quoted_proxy(String s_, Char escape_, Char delim_)
|
||||
: string(s_), escape(escape_), delim(delim_) {}
|
||||
private:
|
||||
// String may be a const type, so disable the assignment operator
|
||||
quoted_proxy& operator=(const quoted_proxy&); // = deleted
|
||||
};
|
||||
|
||||
// abstract away difference between proxies with const or non-const basic_strings
|
||||
template <class Char, class Traits, class Alloc>
|
||||
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 << delim;
|
||||
typename std::basic_string<Char, Traits, Alloc>::const_iterator
|
||||
end_it = string.end();
|
||||
for (typename std::basic_string<Char, Traits, Alloc>::const_iterator
|
||||
it = string.begin();
|
||||
it != end_it;
|
||||
++it )
|
||||
{
|
||||
if (*it == delim || *it == escape)
|
||||
os << escape;
|
||||
os << *it;
|
||||
}
|
||||
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 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)
|
||||
{
|
||||
os << proxy.delim;
|
||||
for (const Char* it = proxy.string;
|
||||
*it;
|
||||
++it )
|
||||
{
|
||||
if (*it == proxy.delim || *it == proxy.escape)
|
||||
os << proxy.escape;
|
||||
os << *it;
|
||||
}
|
||||
os << proxy.delim;
|
||||
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)
|
||||
{
|
||||
proxy.string.clear();
|
||||
Char c;
|
||||
is >> c;
|
||||
if (c != proxy.delim)
|
||||
{
|
||||
is.unget();
|
||||
is >> proxy.string;
|
||||
return is;
|
||||
}
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(is);
|
||||
is >> std::noskipws;
|
||||
for (;;)
|
||||
{
|
||||
is >> c;
|
||||
if (!is.good()) // cope with I/O errors or end-of-file
|
||||
break;
|
||||
if (c == proxy.escape)
|
||||
{
|
||||
is >> c;
|
||||
if (!is.good()) // cope with I/O errors or end-of-file
|
||||
break;
|
||||
}
|
||||
else if (c == proxy.delim)
|
||||
break;
|
||||
proxy.string += c;
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// 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)
|
||||
{
|
||||
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, 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)
|
||||
{
|
||||
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>
|
||||
(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_IO_QUOTED_MANIP
|
||||
#endif
|
||||
|
118
include/boost/io/ostream_joiner.hpp
Normal file
118
include/boost/io/ostream_joiner.hpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
#ifndef BOOST_IO_OSTREAM_JOINER_HPP
|
||||
#define BOOST_IO_OSTREAM_JOINER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ADDRESSOF)
|
||||
template<class T>
|
||||
inline T*
|
||||
osj_address(T& o)
|
||||
{
|
||||
return std::addressof(o);
|
||||
}
|
||||
#else
|
||||
template<class T>
|
||||
inline T*
|
||||
osj_address(T& obj)
|
||||
{
|
||||
return &obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class Delim, class Char = char,
|
||||
class Traits = std::char_traits<Char> >
|
||||
class ostream_joiner {
|
||||
public:
|
||||
typedef Char char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef std::basic_ostream<Char, Traits> ostream_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
ostream_joiner(ostream_type& output, const Delim& delim)
|
||||
: output_(detail::osj_address(output))
|
||||
, delim_(delim)
|
||||
, first_(true) { }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
ostream_joiner(ostream_type& output, Delim&& delim)
|
||||
: output_(detail::osj_address(output))
|
||||
, delim_(std::move(delim))
|
||||
, first_(true) { }
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value) {
|
||||
if (!first_) {
|
||||
*output_ << delim_;
|
||||
}
|
||||
first_ = false;
|
||||
*output_ << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator*() BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator++() BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator++(int) BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_type* output_;
|
||||
Delim delim_;
|
||||
bool first_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
template<class Char, class Traits, class Delim>
|
||||
inline ostream_joiner<typename std::decay<Delim>::type, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim)
|
||||
{
|
||||
return ostream_joiner<typename std::decay<Delim>::type, Char,
|
||||
Traits>(output, std::forward<Delim>(delim));
|
||||
}
|
||||
#else
|
||||
template<class Char, class Traits, class Delim>
|
||||
inline ostream_joiner<Delim, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output,
|
||||
const Delim& delim)
|
||||
{
|
||||
return ostream_joiner<Delim, Char, Traits>(output, delim);
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
97
include/boost/io/ostream_put.hpp
Normal file
97
include/boost/io/ostream_put.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
#ifndef BOOST_IO_OSTREAM_PUT_HPP
|
||||
#define BOOST_IO_OSTREAM_PUT_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline std::size_t
|
||||
osp_put(std::basic_ostream<charT, traits>& os, const charT* data,
|
||||
std::size_t size)
|
||||
{
|
||||
return static_cast<std::size_t>(os.rdbuf()->sputn(data, size));
|
||||
}
|
||||
|
||||
template<class charT, class traits>
|
||||
inline bool
|
||||
osp_fill(std::basic_ostream<charT, traits>& os, std::size_t size)
|
||||
{
|
||||
charT c = os.fill();
|
||||
charT fill[] = { c, c, c, c, c, c, c, c };
|
||||
enum {
|
||||
chunk = sizeof fill / sizeof(charT)
|
||||
};
|
||||
for (; size > chunk; size -= chunk) {
|
||||
if (boost::io::detail::osp_put(os, fill, chunk) != chunk) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return boost::io::detail::osp_put(os, fill, size) == size;
|
||||
}
|
||||
|
||||
template<class charT, class traits>
|
||||
class osp_guard {
|
||||
public:
|
||||
explicit osp_guard(std::basic_ostream<charT, traits>& os) BOOST_NOEXCEPT
|
||||
: os_(&os) { }
|
||||
~osp_guard() BOOST_NOEXCEPT_IF(false) {
|
||||
if (os_) {
|
||||
os_->setstate(std::basic_ostream<charT, traits>::badbit);
|
||||
}
|
||||
}
|
||||
void release() BOOST_NOEXCEPT {
|
||||
os_ = 0;
|
||||
}
|
||||
private:
|
||||
osp_guard(const osp_guard&);
|
||||
osp_guard& operator=(const osp_guard&);
|
||||
std::basic_ostream<charT, traits>* os_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os, const charT* data,
|
||||
std::size_t size)
|
||||
{
|
||||
typedef std::basic_ostream<charT, traits> stream;
|
||||
detail::osp_guard<charT, traits> guard(os);
|
||||
typename stream::sentry entry(os);
|
||||
if (entry) {
|
||||
std::size_t width = static_cast<std::size_t>(os.width());
|
||||
if (width <= size) {
|
||||
if (detail::osp_put(os, data, size) != size) {
|
||||
return os;
|
||||
}
|
||||
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||
if (detail::osp_put(os, data, size) != size ||
|
||||
!detail::osp_fill(os, width - size)) {
|
||||
return os;
|
||||
}
|
||||
} else if (!detail::osp_fill(os, width - size) ||
|
||||
detail::osp_put(os, data, size) != size) {
|
||||
return os;
|
||||
}
|
||||
os.width(0);
|
||||
}
|
||||
guard.release();
|
||||
return os;
|
||||
}
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
152
include/boost/io/quoted.hpp
Normal file
152
include/boost/io/quoted.hpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright 2010 Beman Dawes
|
||||
|
||||
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)
|
||||
*/
|
||||
#ifndef BOOST_IO_QUOTED_HPP
|
||||
#define BOOST_IO_QUOTED_HPP
|
||||
|
||||
#include <boost/io/ios_state.hpp>
|
||||
#include <ios>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class String, class Char>
|
||||
class quoted_proxy {
|
||||
public:
|
||||
quoted_proxy(String string_, Char escape_, Char delim_)
|
||||
: string(string_)
|
||||
, escape(escape_)
|
||||
, delim(delim_) { }
|
||||
|
||||
String string;
|
||||
Char escape;
|
||||
Char delim;
|
||||
|
||||
private:
|
||||
quoted_proxy& operator=(const quoted_proxy&);
|
||||
};
|
||||
|
||||
template<class Char, class Traits>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const Char*, Char>& proxy)
|
||||
{
|
||||
os << proxy.delim;
|
||||
for (const Char* it = proxy.string; *it; ++it) {
|
||||
if (*it == proxy.delim || *it == proxy.escape) {
|
||||
os << proxy.escape;
|
||||
}
|
||||
os << *it;
|
||||
}
|
||||
os << proxy.delim;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
quoted_output(std::basic_ostream<Char, Traits>& os,
|
||||
const std::basic_string<Char, Traits, Alloc>& string, Char escape,
|
||||
Char delim)
|
||||
{
|
||||
os << delim;
|
||||
typename std::basic_string<Char, Traits,
|
||||
Alloc>::const_iterator end = string.end();
|
||||
for (typename std::basic_string<Char, Traits,
|
||||
Alloc>::const_iterator it = string.begin(); it != end; ++it) {
|
||||
if (*it == delim || *it == escape) {
|
||||
os << escape;
|
||||
}
|
||||
os << *it;
|
||||
}
|
||||
os << delim;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
|
||||
Char>& proxy)
|
||||
{
|
||||
return boost::io::detail::quoted_output(os, proxy.string, proxy.escape,
|
||||
proxy.delim);
|
||||
}
|
||||
|
||||
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 boost::io::detail::quoted_output(os, proxy.string, proxy.escape,
|
||||
proxy.delim);
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||
{
|
||||
proxy.string.clear();
|
||||
Char ch;
|
||||
if (!(is >> ch).good()) {
|
||||
return is;
|
||||
}
|
||||
if (ch != proxy.delim) {
|
||||
is.unget();
|
||||
is >> proxy.string;
|
||||
return is;
|
||||
}
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(is);
|
||||
std::noskipws(is);
|
||||
while ((is >> ch).good() && ch != proxy.delim) {
|
||||
if (ch == proxy.escape && !(is >> ch).good()) {
|
||||
break;
|
||||
}
|
||||
proxy.string.push_back(ch);
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
|
||||
Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',
|
||||
Char delim='\"')
|
||||
{
|
||||
return detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>&,
|
||||
Char>(s, escape, delim);
|
||||
}
|
||||
|
||||
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='\"')
|
||||
{
|
||||
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&,
|
||||
Char>(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);
|
||||
}
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -1,15 +1,17 @@
|
||||
{
|
||||
"key": "io",
|
||||
"name": "IO State Savers",
|
||||
"name": "IO",
|
||||
"authors": [
|
||||
"Daryle Walker",
|
||||
"Beman Dawes"
|
||||
"Beman Dawes",
|
||||
"Glen Fernandes"
|
||||
],
|
||||
"description": "Utilities for using the standard I/O library.",
|
||||
"description": "Utilities for the standard I/O library.",
|
||||
"documentation": "doc/html/io.html",
|
||||
"category": [
|
||||
"IO"
|
||||
],
|
||||
"maintainers": [
|
||||
"Daryle Walker <darylew -at- hotmail.com>"
|
||||
"Glen Fernandes <glenjofe -at- gmail.com>"
|
||||
]
|
||||
}
|
||||
|
@ -10,4 +10,7 @@ import testing ;
|
||||
|
||||
run ios_state_unit_test.cpp ;
|
||||
run ios_state_test.cpp ;
|
||||
run quoted_manip_test.cpp ;
|
||||
run quoted_test.cpp ;
|
||||
run ostream_joiner_test.cpp ;
|
||||
run make_ostream_joiner_test.cpp ;
|
||||
run ostream_put_test.cpp ;
|
||||
|
21
test/make_ostream_joiner_test.cpp
Normal file
21
test/make_ostream_joiner_test.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/io/ostream_joiner.hpp>
|
||||
#include <sstream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<char> j = boost::io::make_ostream_joiner(o, ',');
|
||||
*j++ = 1;
|
||||
*j++ = '2';
|
||||
*j++ = "3";
|
||||
BOOST_TEST_EQ(o.str(), "1,2,3");
|
||||
return boost::report_errors();
|
||||
}
|
116
test/ostream_joiner_test.cpp
Normal file
116
test/ostream_joiner_test.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/io/ostream_joiner.hpp>
|
||||
#include <sstream>
|
||||
|
||||
void test_char_type()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(char,
|
||||
boost::io::ostream_joiner<const char*>::char_type);
|
||||
}
|
||||
|
||||
void test_traits_type()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(std::char_traits<char>,
|
||||
boost::io::ostream_joiner<const char*>::traits_type);
|
||||
}
|
||||
|
||||
void test_ostream_type()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(std::ostream,
|
||||
boost::io::ostream_joiner<const char*>::ostream_type);
|
||||
}
|
||||
|
||||
void test_iterator_category()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(std::output_iterator_tag,
|
||||
boost::io::ostream_joiner<const char*>::iterator_category);
|
||||
}
|
||||
|
||||
void test_value_type()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(void,
|
||||
boost::io::ostream_joiner<const char*>::value_type);
|
||||
}
|
||||
|
||||
void test_difference_type()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(void,
|
||||
boost::io::ostream_joiner<const char*>::difference_type);
|
||||
}
|
||||
|
||||
void test_pointer()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(void,
|
||||
boost::io::ostream_joiner<const char*>::pointer);
|
||||
}
|
||||
|
||||
void test_reference()
|
||||
{
|
||||
BOOST_TEST_TRAIT_SAME(void,
|
||||
boost::io::ostream_joiner<const char*>::reference);
|
||||
}
|
||||
|
||||
void test_construct()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST(o.str().empty());
|
||||
}
|
||||
|
||||
void test_assign()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
j = 1;
|
||||
BOOST_TEST_EQ(o.str(), "1");
|
||||
j = '2';
|
||||
BOOST_TEST_EQ(o.str(), "1,2");
|
||||
j = "3";
|
||||
BOOST_TEST_EQ(o.str(), "1,2,3");
|
||||
}
|
||||
|
||||
void test_increment()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&++j, &j);
|
||||
}
|
||||
|
||||
void test_post_increment()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&j++, &j);
|
||||
}
|
||||
|
||||
void test_value()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&*j, &j);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_char_type();
|
||||
test_traits_type();
|
||||
test_ostream_type();
|
||||
test_iterator_category();
|
||||
test_value_type();
|
||||
test_difference_type();
|
||||
test_pointer();
|
||||
test_reference();
|
||||
test_construct();
|
||||
test_assign();
|
||||
test_increment();
|
||||
test_post_increment();
|
||||
test_value();
|
||||
return boost::report_errors();
|
||||
}
|
136
test/ostream_put_test.cpp
Normal file
136
test/ostream_put_test.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/io/ostream_put.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(1);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "xy");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(1);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"xy");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(1);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "xy");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(1);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"xy");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(4);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "xy..");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(4);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"xy..");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(4);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "..xy");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(4);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"..xy");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(12);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "xy..........");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(12);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"xy..........");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(12);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, "xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "..........xy");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(12);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"..........xy");
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// libs/io/test/quote_manip_test.cpp ----------------------------------------------- //
|
||||
|
||||
// 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
|
||||
|
||||
// ---------------------------------------------------------------------------------- //
|
||||
|
||||
#include <boost/io/detail/quoted_manip.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using boost::io::quoted;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
std::wstringstream wss;
|
||||
|
||||
string r; // test results
|
||||
|
||||
const string s0("foo");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\"");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "foo");
|
||||
}
|
||||
|
||||
const string s0s("foo bar");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0s);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0s);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "foo bar");
|
||||
}
|
||||
|
||||
const string s1("foo\\bar, \" *");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted("foo\\bar, \" *");
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1.c_str());
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
|
||||
string s2("'Jack & Jill'");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s2, '&', '\'');
|
||||
ss >> quoted(r, '&', '\'');
|
||||
BOOST_TEST(r == s2);
|
||||
}
|
||||
|
||||
wstring ws1(L"foo$bar, \" *");
|
||||
wstring wr; // test results
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << quoted(ws1, L'$');
|
||||
wss >> quoted(wr, L'$');
|
||||
BOOST_TEST(wr == ws1);
|
||||
}
|
||||
|
||||
const string s3("const string");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s3);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s3);
|
||||
}
|
||||
{
|
||||
// missing end delimiter test
|
||||
std::stringstream ss;
|
||||
ss << "\"abc"; // load ss with faulty quoting
|
||||
ss >> quoted(r); // this loops if istream error/eof not detected
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
// no initial delmiter test
|
||||
std::stringstream ss;
|
||||
ss << "abc";
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
// no initial delmiter, space in ss
|
||||
std::stringstream ss;
|
||||
ss << "abc def";
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
|
||||
// these should fail to compile because the arguments are const:
|
||||
// ss >> quoted(s1);
|
||||
// ss >> quoted("foo");
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
110
test/quoted_test.cpp
Normal file
110
test/quoted_test.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright 2010 Beman Dawes
|
||||
|
||||
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)
|
||||
*/
|
||||
#include <boost/io/quoted.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
int main()
|
||||
{
|
||||
const std::string s0("foo");
|
||||
std::string r;
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\"");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "foo");
|
||||
}
|
||||
const std::string s0s("foo bar");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0s);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0s);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "foo bar");
|
||||
}
|
||||
const std::string s1("foo\\bar, \" *");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted("foo\\bar, \" *");
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1.c_str());
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
std::string s2("'Jack & Jill'");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s2, '&', '\'');
|
||||
ss >> boost::io::quoted(r, '&', '\'');
|
||||
BOOST_TEST(r == s2);
|
||||
}
|
||||
const std::wstring ws1(L"foo$bar, \" *");
|
||||
std::wstring wr;
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << boost::io::quoted(ws1, L'$');
|
||||
wss >> boost::io::quoted(wr, L'$');
|
||||
BOOST_TEST(wr == ws1);
|
||||
}
|
||||
const std::string s3("const string");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s3);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s3);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "\"abc";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "abc";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "abc def";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user