119 lines
2.7 KiB
C++
119 lines
2.7 KiB
C++
|
/*
|
||
|
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
|