Index: uspace/lib/cpp/include/impl/iterator.hpp
===================================================================
--- uspace/lib/cpp/include/impl/iterator.hpp	(revision a57a79cda8ae2a6e9b9e6060a4deaee78e8a1431)
+++ uspace/lib/cpp/include/impl/iterator.hpp	(revision 8cce80b4c1752753474050cdf15448549ce43433)
@@ -31,4 +31,6 @@
 
 #include <cstdlib>
+#include <initializer_list>
+#include <iosfwd>
 #include <memory>
 #include <type_traits>
@@ -658,4 +660,482 @@
         return move_iterator<Iterator>(it);
     }
+
+    /**
+     * 24.6, stream iterators:
+     */
+
+    /**
+     * 24.6.1, class template istream_iterator:
+     */
+
+    template<class T, class Char = char, class Traits = char_traits<Char>,
+             class Distance = ptrdiff_t>
+    class istream_iterator
+        : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
+    {
+        public:
+            using char_type    = Char;
+            using traits_type  = Traits;
+            using istream_type = basic_istream<char_type, traits_type>;
+
+            // TODO: if T is literal, this should be constexpr
+            istream_iterator()
+                : is_{nullptr}, value_{}
+            { /* DUMMY BODY */ }
+
+            istream_iterator(istream_type& is)
+                : is_{&is}, value_{}
+            { /* DUMMY BODY */ }
+
+            istream_iterator(const istream_iterator&) = default;
+
+            ~istream_iterator() = default;
+
+            const T& operator*() const
+            {
+                return value_;
+            }
+
+            const T* operator->() const
+            {
+                return &(operator*());
+            }
+
+            istream_iterator& operator++()
+            {
+                if (is_)
+                    (*is_) >> value_;
+
+                return *this;
+            }
+
+            istream_iterator operator++(int)
+            {
+                auto tmp{*this};
+
+                if (is_)
+                    (*is_) >> value_;
+
+                return tmp;
+            }
+
+        private:
+            basic_istream<char_type, traits_type>* is_;
+
+            T value_;
+
+            friend bool operator==<>(const istream_iterator&,
+                                     const istream_iterator&);
+
+            friend bool operator!=<>(const istream_iterator&,
+                                     const istream_iterator&);
+    };
+
+    template<class T, class Char, class Traits, class Distance>
+    bool operator==(const istream_iterator<T, Char, Traits, Distance>& lhs,
+                    const istream_iterator<T, Char, Traits, Distance>& rhs)
+    {
+        return lhs.is_ == rhs.is_;
+    }
+
+    template<class T, class Char, class Traits, class Distance>
+    bool operator!=(const istream_iterator<T, Char, Traits, Distance>& lhs,
+                    const istream_iterator<T, Char, Traits, Distance>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    /**
+     * 24.6.2, class template ostream_iterator:
+     */
+
+    template<class T, class Char = char, class Traits = char_traits<Char>>
+    class ostream_iterator
+        : public iterator<output_iterator_tag, void, void, void, void>
+    {
+        public:
+            using char_type    = Char;
+            using traits_type  = Traits;
+            using ostream_type = basic_ostream<char_type, traits_type>;
+
+            ostream_iterator(ostream_type& os)
+                : os_{&os}, delim_{nullptr}
+            { /* DUMMY BODY */ }
+
+            ostream_iterator(ostream_type& os, const char_type* delim)
+                : os_{&os}, delim_{delim}
+            { /* DUMMY BODY */ }
+
+            ostream_iterator(const ostream_iterator&) = default;
+
+            ~ostream_iterator() = default;
+
+            ostream_iterator& operator=(const T& value)
+            {
+                os_ << value;
+                if (delim_)
+                    os_ << delim_;
+
+                return *this;
+            }
+
+            ostream_iterator& operator*() const
+            {
+                return *this;
+            }
+
+            ostream_iterator& operator++()
+            {
+                return *this;
+            }
+
+            ostream_iterator& operator++(int)
+            {
+                return *this;
+            }
+
+        private:
+            basic_ostream<char_type, traits_type>* os_;
+
+            const char_type* delim_;
+    };
+
+    /**
+     * 24.6.3, class template istreambuf_iterator:
+     */
+
+    template<class Char, class Traits>
+    class istreambuf_iterator
+        : public iterator<input_iterator_tag, Char, typename Traits::off_type, Char*, Char>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using int_type       = typename traits_type::int_type;
+            using streambuf_type = basic_streambuf<char_type, traits_type>;
+            using istream_type   = basic_istream<char_type, traits_type>;
+
+            class proxy_type
+            {
+                public:
+                    char_type operator*()
+                    {
+                        return char_;
+                    }
+
+                private:
+                    proxy_type(char_type c, streambuf_type sbuf)
+                        : char_{c}, sbuf_{sbuf}
+                    { /* DUMMY BODY */ }
+
+                    char_type char_;
+
+                    streambuf_type* sbuf_;
+            };
+
+            constexpr istreambuf_iterator() noexcept
+                : sbuf_{nullptr}
+            { /* DUMMY BODY */ }
+
+            istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
+
+            ~istreambuf_iterator() = default;
+
+            istreambuf_iterator(istream_type& is) noexcept
+                : sbuf_{is.rdbuf()}
+            { /* DUMMY BODY */ }
+
+            istreambuf_iterator(streambuf_type* sbuf) noexcept
+                : sbuf_{sbuf}
+            { /* DUMMY BODY */ }
+
+            istreambuf_iterator(const proxy_type& proxy) noexcept
+                : sbuf_{proxy.sbuf_}
+            { /* DUMMY BODY */ }
+
+            char_type operator*() const
+            {
+                if (sbuf_)
+                {
+                    auto res = sbuf_->sgetc();
+                    if (res == traits_type::eof())
+                        sbuf_ = nullptr;
+
+                    return res;
+                }
+                else
+                    return traits_type::eof();
+            }
+
+            istreambuf_iterator& operator++()
+            {
+                if (sbuf_)
+                    sbuf_->sbumpc();
+
+                return *this;
+            }
+
+            proxy_type operator++(int)
+            {
+                if (sbuf_)
+                    return proxy_type{sbuf_->sbumpc(), sbuf_};
+                else
+                    return proxy_type{traits_type::eof(), nullptr};
+            }
+
+            bool equal(const istreambuf_iterator& rhs) const
+            {
+                if ((sbuf_ == nullptr && rhs.sbuf_ == nullptr) ||
+                    (sbuf_ != nullptr && rhs.sbuf_ != nullptr))
+                    return true;
+                else
+                    return false;
+            }
+
+        private:
+            streambuf_type* sbuf_;
+    };
+
+    template<class Char, class Traits>
+    bool operator==(const istreambuf_iterator<Char, Traits>& lhs,
+                    const istreambuf_iterator<Char, Traits>& rhs)
+    {
+        return lhs.equal(rhs);
+    }
+
+    template<class Char, class Traits>
+    bool operator!=(const istreambuf_iterator<Char, Traits>& lhs,
+                    const istreambuf_iterator<Char, Traits>& rhs)
+    {
+        return !lhs.equal(rhs);
+    }
+
+    /**
+     * 24.6.4, class template ostreambuf_iterator:
+     */
+
+    template<class Char, class Traits>
+    class ostreambuf_iterator
+        : public iterator<output_iterator_tag, void, void, void, void>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using streambuf_type = basic_streambuf<char_type, traits_type>;
+            using ostream_type   = basic_ostream<char_type, traits_type>;
+
+            ostreambuf_iterator(ostream_type& os) noexcept
+                : sbuf_{os.rdbuf()}
+            { /* DUMMY BODY */ }
+
+            ostreambuf_iterator(streambuf_type* sbuf) noexcept
+                : sbuf_{sbuf}
+            { /* DUMMY BODY */ }
+
+            ostreambuf_iterator& operator=(char_type c)
+            {
+                if (!failed() && sbuf_->sputc(c) == traits_type::eof())
+                    failed_ = true;
+
+                return *this;
+            }
+
+            ostreambuf_iterator& operator*()
+            {
+                return *this;
+            }
+
+            ostreambuf_iterator& operator++()
+            {
+                return *this;
+            }
+
+            ostreambuf_iterator& operator++(int)
+            {
+                return *this;
+            }
+
+            bool failed() const noexcept
+            {
+                return failed_;
+            }
+
+        private:
+            streambuf_type* sbuf_;
+
+            bool failed_{false};
+    };
+
+    /**
+     * 24.7, range access:
+     */
+
+    template<class Container>
+    auto begin(Container& c) -> decltype(c.begin())
+    {
+        return c.begin();
+    }
+
+    template<class Container>
+    auto begin(const Container& c) -> decltype(c.begin())
+    {
+        return c.begin();
+    }
+
+    template<class Container>
+    auto end(Container& c) -> decltype(c.end())
+    {
+        return c.end();
+    }
+
+    template<class Container>
+    auto end(const Container& c) -> decltype(c.end())
+    {
+        return c.end();
+    }
+
+    template<class T, size_t N>
+    constexpr T* begin(T (&array)[N]) noexcept
+    {
+        return array;
+    }
+
+    template<class T, size_t N>
+    constexpr T* end(T (&array)[N]) noexcept
+    {
+        return array + N;
+    }
+
+    template<class Container>
+    constexpr auto cbegin(const Container& c) noexcept(noexcept(std::begin(c)))
+        -> decltype(std::begin(c))
+    {
+        return std::begin(c);
+    }
+
+    template<class Container>
+    constexpr auto cend(const Container& c) noexcept(noexcept(std::end(c)))
+        -> decltype(std::end(c))
+    {
+        return std::end(c);
+    }
+
+    template<class Container>
+    auto rbegin(Container& c) -> decltype(c.rbegin())
+    {
+        return c.rbegin();
+    }
+
+    template<class Container>
+    auto rbegin(const Container& c) -> decltype(c.rbegin())
+    {
+        return c.rbegin();
+    }
+
+    template<class Container>
+    auto rend(Container& c) -> decltype(c.rend())
+    {
+        return c.rend();
+    }
+
+    template<class Container>
+    auto rend(const Container& c) -> decltype(c.rend())
+    {
+        return c.rend();
+    }
+
+    template<class T, size_t N>
+    reverse_iterator<T*> rbegin(T (&array)[N])
+    {
+        return reverse_iterator<T*>{array + N};
+    }
+
+    template<class T, size_t N>
+    reverse_iterator<T*> rend(T (&array)[N])
+    {
+        return reverse_iterator<T*>{array};
+    }
+
+    template<class T>
+    reverse_iterator<const T*> rbegin(initializer_list<T> init)
+    {
+        return reverse_iterator<const T*>{init.end()};
+    }
+
+    template<class T>
+    reverse_iterator<const T*> rend(initializer_list<T> init)
+    {
+        return reverse_iterator<const T*>{init.begin()};
+    }
+
+    template<class Container>
+    auto crbegin(const Container& c) -> decltype(std::rbegin(c))
+    {
+        return std::rbegin(c);
+    }
+
+    template<class Container>
+    auto crend(const Container& c) -> decltype(std::rend(c))
+    {
+        return std::rend(c);
+    }
+
+    /**
+     * 24.8, container access:
+     */
+
+    template<class Container>
+    constexpr auto size(const Container& c) -> decltype(c.size())
+    {
+        return c.size();
+    }
+
+    template<class T, size_t N>
+    constexpr size_t size(T (&array)[N]) noexcept
+    {
+        return N;
+    }
+
+    template<class Container>
+    constexpr auto empty(const Container& c) -> decltype(c.empty())
+    {
+        return c.empty();
+    }
+
+    template<class T, size_t N>
+    constexpr bool empty(T (&array)[N]) noexcept
+    {
+        return false;
+    }
+
+    template<class T>
+    constexpr bool empty(initializer_list<T> init) noexcept
+    {
+        return init.size() == 0;
+    }
+
+    template<class Container>
+    constexpr auto data(Container& c) -> decltype(c.data())
+    {
+        return c.data();
+    }
+
+    template<class Container>
+    constexpr auto data(const Container& c) -> decltype(c.data())
+    {
+        return c.data();
+    }
+
+    template<class T, size_t N>
+    constexpr T* data(T (&array)[N]) noexcept
+    {
+        return array;
+    }
+
+    template<class T>
+    constexpr const T* data(initializer_list<T> init) noexcept
+    {
+        return init.begin();
+    }
 }
 
