Merge branch 'develop'

This commit is contained in:
Glen Fernandes
2019-12-15 15:12:42 -05:00
17 changed files with 1006 additions and 330 deletions

View File

@ -0,0 +1,5 @@
<style>
.specification {
margin-left: 2em;
}
</style>

View File

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

View File

@ -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
View 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
View 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.

View File

@ -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.

View File

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

View 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

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

View File

@ -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>"
]
}

View File

@ -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 ;

View 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();
}

View 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
View 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();
}

View File

@ -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
View 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();
}