Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:50

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //  Copyright Google LLC 2020-present
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-iterator
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     /// \sa `make_ostream_joiner_fn`
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     } // namespace cpp20
0201 
0202     /// \brief Writes to an ostream object using the unformatted
0203     /// `std::basic_ostream::write` operation. This means that `32` will be encoded as
0204     /// `100000` as opposed to the string "32".
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         // requires stream_insertible<T, ostream_type>
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 } // namespace ranges
0249 
0250 /// \cond
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 } // namespace std
0266 
0267 RANGES_DIAGNOSTIC_POP
0268 /// \endcond
0269 
0270 #include <range/v3/detail/epilogue.hpp>
0271 
0272 #endif // RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP