File indexing completed on 2025-01-18 10:09:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
0015 #define RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
0016
0017 #include <cstddef>
0018 #include <iosfwd>
0019 #include <iterator>
0020 #include <string>
0021 #include <type_traits>
0022 #include <utility>
0023
0024 #include <range/v3/range_fwd.hpp>
0025
0026 #include <range/v3/iterator/concepts.hpp>
0027
0028 #include <range/v3/detail/prologue.hpp>
0029
0030 namespace ranges
0031 {
0032
0033
0034 template<typename T = void, typename Char = char,
0035 typename Traits = std::char_traits<Char>>
0036 struct ostream_iterator
0037 {
0038 private:
0039 template<class U>
0040 using value_t = meta::if_<std::is_void<T>, U, T>;
0041
0042 public:
0043 using difference_type = std::ptrdiff_t;
0044 using char_type = Char;
0045 using traits_type = Traits;
0046 using ostream_type = std::basic_ostream<Char, Traits>;
0047
0048 constexpr ostream_iterator() = default;
0049 ostream_iterator(ostream_type & s, Char const * d = nullptr) noexcept
0050 : sout_(&s)
0051 , delim_(d)
0052 {}
0053 template(typename U)(
0054 requires convertible_to<U, value_t<U> const &>)
0055 ostream_iterator & operator=(U && value)
0056 {
0057 RANGES_EXPECT(sout_);
0058 *sout_ << static_cast<value_t<U> const &>(static_cast<U &&>(value));
0059 if(delim_)
0060 *sout_ << delim_;
0061 return *this;
0062 }
0063 ostream_iterator & operator*()
0064 {
0065 return *this;
0066 }
0067 ostream_iterator & operator++()
0068 {
0069 return *this;
0070 }
0071 ostream_iterator & operator++(int)
0072 {
0073 return *this;
0074 }
0075
0076 private:
0077 ostream_type * sout_;
0078 Char const * delim_;
0079 };
0080
0081 template<typename Delim, typename Char = char,
0082 typename Traits = std::char_traits<Char>>
0083 struct ostream_joiner
0084 {
0085 CPP_assert(semiregular<Delim>);
0086 using difference_type = std::ptrdiff_t;
0087 using char_type = Char;
0088 using traits_type = Traits;
0089 using ostream_type = std::basic_ostream<Char, Traits>;
0090
0091 constexpr ostream_joiner() = default;
0092 ostream_joiner(ostream_type & s, Delim const & d)
0093 : delim_(d)
0094 , sout_(std::addressof(s))
0095 , first_(true)
0096 {}
0097 ostream_joiner(ostream_type & s, Delim && d)
0098 : delim_(std::move(d))
0099 , sout_(std::addressof(s))
0100 , first_(true)
0101 {}
0102 template<typename T>
0103 ostream_joiner & operator=(T const & value)
0104 {
0105 RANGES_EXPECT(sout_);
0106 if(!first_)
0107 *sout_ << delim_;
0108 first_ = false;
0109 *sout_ << value;
0110 return *this;
0111 }
0112 ostream_joiner & operator*() noexcept
0113 {
0114 return *this;
0115 }
0116 ostream_joiner & operator++() noexcept
0117 {
0118 return *this;
0119 }
0120 ostream_joiner & operator++(int) noexcept
0121 {
0122 return *this;
0123 }
0124
0125 private:
0126 Delim delim_;
0127 ostream_type * sout_;
0128 bool first_;
0129 };
0130
0131 struct make_ostream_joiner_fn
0132 {
0133 template(typename Delim, typename Char, typename Traits)(
0134 requires semiregular<detail::decay_t<Delim>>)
0135 ostream_joiner<detail::decay_t<Delim>, Char, Traits>
0136 operator()(std::basic_ostream<Char, Traits> & s, Delim && d) const
0137 {
0138 return {s, std::forward<Delim>(d)};
0139 }
0140 };
0141
0142
0143 RANGES_INLINE_VARIABLE(make_ostream_joiner_fn, make_ostream_joiner)
0144
0145 template<typename Char, typename Traits = std::char_traits<Char>>
0146 struct ostreambuf_iterator
0147 {
0148 public:
0149 typedef ptrdiff_t difference_type;
0150 typedef Char char_type;
0151 typedef Traits traits_type;
0152 typedef std::basic_streambuf<Char, Traits> streambuf_type;
0153 typedef std::basic_ostream<Char, Traits> ostream_type;
0154
0155 constexpr ostreambuf_iterator() = default;
0156 ostreambuf_iterator(ostream_type & s) noexcept
0157 : ostreambuf_iterator(s.rdbuf())
0158 {}
0159 ostreambuf_iterator(streambuf_type * s) noexcept
0160 : sbuf_(s)
0161 {
0162 RANGES_ASSERT(s != nullptr);
0163 }
0164 ostreambuf_iterator & operator=(Char c)
0165 {
0166 RANGES_ASSERT(sbuf_ != nullptr);
0167 if(!failed_)
0168 failed_ = (sbuf_->sputc(c) == Traits::eof());
0169 return *this;
0170 }
0171 ostreambuf_iterator & operator*()
0172 {
0173 return *this;
0174 }
0175 ostreambuf_iterator & operator++()
0176 {
0177 return *this;
0178 }
0179 ostreambuf_iterator & operator++(int)
0180 {
0181 return *this;
0182 }
0183 bool failed() const noexcept
0184 {
0185 return failed_;
0186 }
0187
0188 private:
0189 streambuf_type * sbuf_ = nullptr;
0190 bool failed_ = false;
0191 };
0192
0193 namespace cpp20
0194 {
0195 template<typename T, typename Char = char,
0196 typename Traits = std::char_traits<Char>>
0197 using ostream_iterator = ranges::ostream_iterator<T, Char, Traits>;
0198
0199 using ranges::ostreambuf_iterator;
0200 }
0201
0202
0203
0204
0205
0206 template<typename CharT = char, typename Traits = std::char_traits<CharT>>
0207 class unformatted_ostream_iterator final
0208 {
0209 public:
0210 using iterator_category = std::output_iterator_tag;
0211 using difference_type = std::ptrdiff_t;
0212 using char_type = CharT;
0213 using traits_type = Traits;
0214 using ostream_type = std::basic_ostream<CharT, Traits>;
0215
0216 unformatted_ostream_iterator() = default;
0217
0218 explicit unformatted_ostream_iterator(ostream_type & out) noexcept
0219 : out_(&out)
0220 {}
0221
0222 template<typename T>
0223
0224 unformatted_ostream_iterator & operator=(T const & t)
0225 {
0226 RANGES_EXPECT(out_);
0227 out_->write(reinterpret_cast<char const *>(std::addressof(t)), sizeof(T));
0228 return *this;
0229 }
0230
0231 unformatted_ostream_iterator & operator*() noexcept
0232 {
0233 return *this;
0234 }
0235 unformatted_ostream_iterator & operator++() noexcept
0236 {
0237 return *this;
0238 }
0239 unformatted_ostream_iterator & operator++(int) noexcept
0240 {
0241 return *this;
0242 }
0243
0244 private:
0245 ostream_type * out_ = nullptr;
0246 };
0247
0248 }
0249
0250
0251 RANGES_DIAGNOSTIC_PUSH
0252 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
0253
0254 namespace std
0255 {
0256 template<typename T, typename Char, typename Traits>
0257 struct iterator_traits<::ranges::ostream_iterator<T, Char, Traits>>
0258 : ::ranges::detail::std_output_iterator_traits<>
0259 {};
0260
0261 template<typename Char, typename Traits>
0262 struct iterator_traits<::ranges::ostreambuf_iterator<Char, Traits>>
0263 : ::ranges::detail::std_output_iterator_traits<>
0264 {};
0265 }
0266
0267 RANGES_DIAGNOSTIC_POP
0268
0269
0270 #include <range/v3/detail/epilogue.hpp>
0271
0272 #endif