mirror of
https://github.com/boostorg/io.git
synced 2025-07-29 20:07:13 +02:00
Implement ostream_joiner
This commit is contained in:
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
|
Reference in New Issue
Block a user