• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright 2019 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4 
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #ifndef BOOST_IO_OSTREAM_JOINER_HPP
9 #define BOOST_IO_OSTREAM_JOINER_HPP
10 
11 #include <boost/config.hpp>
12 #include <ostream>
13 #include <string>
14 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
15 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
16 #include <type_traits>
17 #endif
18 #include <utility>
19 #endif
20 
21 namespace boost {
22 namespace io {
23 namespace detail {
24 
25 #if !defined(BOOST_NO_CXX11_ADDRESSOF)
26 template<class T>
27 inline T*
osj_address(T & o)28 osj_address(T& o)
29 {
30     return std::addressof(o);
31 }
32 #else
33 template<class T>
34 inline T*
35 osj_address(T& obj)
36 {
37     return &obj;
38 }
39 #endif
40 
41 } /* detail */
42 
43 template<class Delim, class Char = char,
44     class Traits = std::char_traits<Char> >
45 class ostream_joiner {
46 public:
47     typedef Char char_type;
48     typedef Traits traits_type;
49     typedef std::basic_ostream<Char, Traits> ostream_type;
50     typedef std::output_iterator_tag iterator_category;
51     typedef void value_type;
52     typedef void difference_type;
53     typedef void pointer;
54     typedef void reference;
55 
ostream_joiner(ostream_type & output,const Delim & delim)56     ostream_joiner(ostream_type& output, const Delim& delim)
57         : output_(detail::osj_address(output))
58         , delim_(delim)
59         , first_(true) { }
60 
61 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
ostream_joiner(ostream_type & output,Delim && delim)62     ostream_joiner(ostream_type& output, Delim&& delim)
63         : output_(detail::osj_address(output))
64         , delim_(std::move(delim))
65         , first_(true) { }
66 #endif
67 
68     template<class T>
operator =(const T & value)69     ostream_joiner& operator=(const T& value) {
70         if (!first_) {
71             *output_ << delim_;
72         }
73         first_ = false;
74         *output_ << value;
75         return *this;
76     }
77 
operator *()78     ostream_joiner& operator*() BOOST_NOEXCEPT {
79         return *this;
80     }
81 
operator ++()82     ostream_joiner& operator++() BOOST_NOEXCEPT {
83         return *this;
84     }
85 
operator ++(int)86     ostream_joiner& operator++(int) BOOST_NOEXCEPT {
87         return *this;
88     }
89 
90 private:
91     ostream_type* output_;
92     Delim delim_;
93     bool first_;
94 };
95 
96 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
97     !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
98 template<class Char, class Traits, class Delim>
99 inline ostream_joiner<typename std::decay<Delim>::type, Char, Traits>
make_ostream_joiner(std::basic_ostream<Char,Traits> & output,Delim && delim)100 make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim)
101 {
102     return ostream_joiner<typename std::decay<Delim>::type, Char,
103         Traits>(output, std::forward<Delim>(delim));
104 }
105 #else
106 template<class Char, class Traits, class Delim>
107 inline ostream_joiner<Delim, Char, Traits>
make_ostream_joiner(std::basic_ostream<Char,Traits> & output,const Delim & delim)108 make_ostream_joiner(std::basic_ostream<Char, Traits>& output,
109     const Delim& delim)
110 {
111     return ostream_joiner<Delim, Char, Traits>(output, delim);
112 }
113 #endif
114 
115 } /* io */
116 } /* boost */
117 
118 #endif
119