Index: uspace/lib/cpp/include/__bits/abi.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/abi.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/abi.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -26,4 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+#ifndef LIBCPP_BITS_ABI
+#define LIBCPP_BITS_ABI
 
 #include <cstddef>
@@ -158,2 +161,4 @@
 
 namespace abi = __cxxabiv1;
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/array.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/array.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/array.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_ARRAY
+#define LIBCPP_BITS_ADT_ARRAY
+
+#include <iterator>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.3.2, class template array:
+     */
+
+    template<class T, size_t N>
+    struct array
+    {
+        using value_type             = T;
+        using reference              = T&;
+        using const_reference        = const T&;
+        using size_type              = size_t;
+        using difference_type        = ptrdiff_t;
+        using pointer                = T*;
+        using const_pointer          = const T*;
+        using iterator               = pointer;
+        using const_iterator         = const_pointer;
+        using reverse_iterator       = std::reverse_iterator<iterator>;
+        using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+        /**
+         * Note: In the case of N == 0 the standard mandates that
+         *       begin() == end() which is achieved by setting the size
+         *       to 1. Return value of data() is unspecified and front()
+         *       and back() cause undefined behavior.
+         */
+        value_type elems[N ? N : 1];
+
+        void fill(const T& x)
+        {
+            fill_n(begin(), N, x);
+        }
+
+        void swap(array& other)
+                // TODO: Does not find declval atm :/
+                /* noexcept(noexcept(swap(declval<T&>(), declval<T&>()))) */
+        {
+            swap_ranges(begin(), end(), other.begin());
+        }
+
+        iterator begin() noexcept
+        {
+            return &elems[0];
+        }
+
+        iterator end() noexcept
+        {
+            return &elems[0] + N;
+        }
+
+        reverse_iterator rbegin() noexcept
+        {
+            return make_reverse_iterator(end());
+        }
+
+        reverse_iterator rend() noexcept
+        {
+            return make_reverse_iterator(begin());
+        }
+
+        const_iterator cbegin() const noexcept
+        {
+            return &elems[0];
+        }
+
+        const_iterator cend() const noexcept
+        {
+            return &elems[0] + N;
+        }
+
+        const_reverse_iterator crbegin() const noexcept
+        {
+            return make_reverse_iterator(end());
+        }
+
+        const_reverse_iterator crend() const noexcept
+        {
+            return make_reverse_iterator(begin());
+        }
+
+        reference operator[](size_type idx)
+        {
+            return elems[idx];
+        }
+
+        constexpr const_reference operator[](size_type idx) const
+        {
+            return elems[idx];
+        }
+
+        reference at(size_type idx)
+        {
+            // TODO: Bounds checking.
+            return elems[idx];
+        }
+
+        constexpr const_reference at(size_type idx) const
+        {
+            // TODO: Bounds checking.
+            return elems[idx];
+        }
+
+        reference front()
+        {
+            return elems[0];
+        }
+
+        constexpr const_reference front() const
+        {
+            return elems[0];
+        }
+
+        reference back()
+        {
+            return elems[N - 1];
+        }
+
+        constexpr const_reference back() const
+        {
+            return elems[N - 1];
+        }
+
+        pointer data() noexcept
+        {
+            return &elems[0];
+        }
+
+        const_pointer data() const noexcept
+        {
+            return &elems[0];
+        }
+
+        size_type size() const noexcept
+        {
+            return N;
+        }
+    };
+
+    template<class T, size_t N>
+    void swap(array<T, N>& lhs, array<T, N>& rhs) noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 23.3.2.9, tuple interface for class template array:
+     */
+
+    template<class>
+    struct tuple_size;
+
+    template<class T, size_t N>
+    struct tuple_size<array<T, N>>
+        : integral_constant<size_t, N>
+    { /* DUMMY BODY */ };
+
+    template<size_t, class>
+    struct tuple_element;
+
+    template<size_t I, class T, size_t N>
+    struct tuple_element<I, array<T, N>>
+        : aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<size_t I, class T, size_t N>
+    constexpr T& get(array<T, N>& arr) noexcept
+    {
+        static_assert(I < N, "index out of bounds");
+
+        return arr[I];
+    }
+
+    template<size_t I, class T, size_t N>
+    constexpr T&& get(array<T, N>&& arr) noexcept
+    {
+        return move(get<I>(arr));
+    }
+
+    template<size_t I, class T, size_t N>
+    constexpr const T& get(const array<T, N>& arr) noexcept
+    {
+        static_assert(I < N, "index out of bounds");
+
+        return arr[I];
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/bitset.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/bitset.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/bitset.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_BITSET
+#define LIBCPP_BITS_ADT_BITSET
+
+#include <iosfwd>
+#include <string>
+
+namespace std
+{
+    /**
+     * 20.6, class template bitset:
+     */
+
+    template<size_t N>
+    class bitset
+    {
+        public:
+            class reference
+            {
+                friend class bitset;
+
+                public:
+                    ~reference() noexcept = default;
+
+                    reference& operator=(bool val) noexcept
+                    {
+                        if (val)
+                            data_ |= mask_;
+                        else
+                            data_ &= ~mask_;
+                    }
+
+                    reference& operator=(const reference& other) noexcept
+                    {
+                        if (other)
+                            data_ |= mask_;
+                        else
+                            data_ &= ~mask_;
+                    }
+
+                    bool operator~() const noexcept
+                    {
+                        return data_ & mask_;
+                    }
+
+                    operator bool() const noexcept
+                    {
+                        return data_ & mask_;
+                    }
+
+                    reference& flip() noexcept
+                    {
+                        data_ ^= mask_;
+
+                        return *this;
+                    }
+
+                private:
+                    reference() noexcept = delete;
+
+                    using data_type = typename bitset::data_type;
+
+                    data_type& data_;
+                    data_type mask_;
+
+                    reference(data_type& data, size_t idx)
+                        : data_{data}, mask_{bitset::one_ << idx}
+                    { /* DUMMY BODY */ }
+            };
+
+            /**
+             * 20.6.1, constructors:
+             */
+
+            constexpr bitset() noexcept
+            {
+                init_(zero_);
+            }
+
+            constexpr bitset(unsigned long long val) noexcept
+            {
+                init_(val);
+            }
+
+            template<class Char, class Traits, class Allocator>
+            explicit bitset(
+                const basic_string<Char, Traits, Allocator>& str,
+                typename basic_string<Char, Traits, Allocator>::size_type pos = 0,
+                typename basic_string<Char, Traits, Allocator>::size_type n =
+                    basic_string<Char, Traits, Allocator>::npos,
+                Char zero = Char('0'), Char one = Char('1')
+            )
+            {
+                // TODO: throw out_of_range if pos > str.size()
+
+                init_(zero_);
+                auto len = n < (str.size() - pos) ? n : (str.size() - pos);
+                len = len < N ? len : N;
+
+                for (size_t i = 0, j = pos + len - 1; i < len; ++i, --j)
+                {
+                    if (Traits::eq(str[j], zero))
+                        set(i, false);
+                    else if (Traits::eq(str[j], one))
+                        set(i, true);
+                    // TODO: else throw invalid_argument
+                }
+            }
+
+            template<class Char>
+            explicit bitset(
+                const Char* str,
+                typename basic_string<Char>::size_type n = basic_string<Char>::npos,
+                Char zero = Char('0'), Char one = Char('1')
+            )
+                : bitset{
+                    n == basic_string<Char>::npos ? basic_string<Char>{str} : basic_string<Char>{str, n},
+                    0, n, zero, one
+                  }
+            { /* DUMMY BODY */ }
+
+            /**
+             * 20.6.2, bitset operations:
+             */
+
+            bitset<N>& operator&=(const bitset<N>& rhs) noexcept
+            {
+                for (size_t i = 0; i < data_size_; ++i)
+                    data_[i] &= rhs.data_[i];
+
+                return *this;
+            }
+
+            bitset<N>& operator|=(const bitset<N>& rhs) noexcept
+            {
+                for (size_t i = 0; i < data_size_; ++i)
+                    data_[i] |= rhs.data_[i];
+
+                return *this;
+            }
+
+            bitset<N>& operator^=(const bitset<N>& rhs) noexcept
+            {
+                for (size_t i = 0; i < data_size_; ++i)
+                    data_[i] ^= rhs.data_[i];
+
+                return *this;
+            }
+
+            bitset<N>& operator<<=(size_t pos) noexcept
+            {
+                for (size_t i = N; i > 1; --i)
+                {
+                    if (i < pos)
+                        set(i - 1, false);
+                    else
+                        set(i - 1, test(i - 1 - pos));
+                }
+
+                return *this;
+            }
+
+            bitset<N>& operator>>=(size_t pos) noexcept
+            {
+                for (size_t i = 0; i < N; ++i)
+                {
+                    if (pos >= N - i)
+                        set(i, false);
+                    else
+                        set(i, test(i + pos));
+                }
+
+                return *this;
+            }
+
+            bitset<N>& set() noexcept
+            {
+                for (size_t i = 0; i < N; ++i)
+                    set(i);
+
+                return *this;
+            }
+
+            bitset<N>& set(size_t pos, bool val = true)
+            {
+                // TODO: throw out_of_range if pos > N
+                set_bit_(get_data_idx_(pos), get_bit_idx_(pos), val);
+
+                return *this;
+            }
+
+            bitset<N>& reset() noexcept
+            {
+                for (size_t i = 0; i < N; ++i)
+                    reset(i);
+
+                return *this;
+            }
+
+            bitset<N>& reset(size_t pos)
+            {
+                set_bit_(get_data_idx_(pos), get_bit_idx_(pos), false);
+
+                return *this;
+            }
+
+            bitset<N> operator~() const noexcept
+            {
+                bitset<N> res{*this};
+
+                return res.flip();
+            }
+
+            bitset<N>& flip() noexcept
+            {
+                for (size_t i = 0; i < N; ++i)
+                    flip(i);
+
+                return *this;
+            }
+
+            bitset<N>& flip(size_t pos)
+            {
+                return set(pos, !test(pos));
+            }
+
+            constexpr bool operator[](size_t pos) const
+            {
+                /**
+                 * Note: The standard doesn't mention any exception
+                 *       here being thrown at any time, so we shouldn't
+                 *       use test().
+                 */
+                return get_bit_(data_[get_data_idx_(pos)], get_bit_idx_(pos));
+            }
+
+            reference operator[](size_t pos)
+            {
+                return reference{data_[get_data_idx_(pos)], get_bit_idx_(pos)};
+            }
+
+            unsigned long to_ulong() const
+            {
+                // TODO: throw overflow_error if N > bits in ulong
+                return static_cast<unsigned long>(data_[0] & (~0UL));
+            }
+
+            unsigned long long to_ullong() const
+            {
+                // TODO: throw overflow_error if N > bits_in_data_type_
+                return data_[0];
+            }
+
+            template<
+                class Char = char,
+                class Traits = char_traits<Char>,
+                class Allocator = allocator<Char>
+            >
+            basic_string<Char, Traits, Allocator> to_string(Char zero = Char('0'),
+                                                            Char one = Char('1')) const
+            {
+                basic_string<Char, Traits, Allocator> res{};
+                res.reserve(N);
+                for (size_t i = N; i > 0; --i)
+                {
+                    if (test(i - 1))
+                        res.push_back(one);
+                    else
+                        res.push_back(zero);
+                }
+
+                return res;
+            }
+
+            size_t count() const noexcept
+            {
+                size_t res{};
+                for (size_t i = 0; i < N; ++i)
+                {
+                    if (test(i))
+                        ++res;
+                }
+
+                return res;
+            }
+
+            constexpr size_t size() const noexcept
+            {
+                return N;
+            }
+
+            bool operator==(const bitset<N>& rhs) const noexcept
+            {
+                for (size_t i = 0; i < data_size_; ++i)
+                {
+                    if (data_[i] != rhs.data_[i])
+                        return false;
+                }
+
+                return true;
+            }
+
+            bool operator!=(const bitset<N>& rhs) const noexcept
+            {
+                return !(*this == rhs);
+            }
+
+            bool test(size_t pos) const
+            {
+                // TODO: throw out of range if pos > N
+                return get_bit_(data_[get_data_idx_(pos)], get_bit_idx_(pos));
+            }
+
+            bool all() const noexcept
+            {
+                return count() == size();
+            }
+
+            bool any() const noexcept
+            {
+                return count() != 0;
+            }
+
+            bool none() const noexcept
+            {
+                return count() == 0;
+            }
+
+            bitset<N> operator<<(size_t pos) const noexcept
+            {
+                return bitset<N>{*this} <<= pos;
+            }
+
+            bitset<N> operator>>(size_t pos) const noexcept
+            {
+                return bitset<N>{*this} >>= pos;
+            }
+
+        private:
+            /**
+             * While this might be a bit more wasteful
+             * than using unsigned or unsigned long,
+             * it will make parts of out code easier
+             * to read.
+             */
+            using data_type = unsigned long long;
+
+            static constexpr size_t bits_in_data_type_ = sizeof(data_type) * 8;
+            static constexpr size_t data_size_ = N / bits_in_data_type_ + 1;
+
+            /**
+             * These are useful for masks, if we use literals
+             * then forgetting to add ULL or changing the data
+             * type could result in wrong indices being computed.
+             */
+            static constexpr data_type zero_ = data_type{0};
+            static constexpr data_type one_ = data_type{1};
+
+            data_type data_[data_size_];
+
+            void init_(data_type val)
+            {
+                data_type mask{~zero_};
+                if (N < bits_in_data_type_)
+                    mask >>= N;
+                data_[0] = val & mask;
+
+                for (size_t i = 1; i < data_size_; ++i)
+                    data_[i] = data_type{};
+            }
+
+            size_t get_data_idx_(size_t pos) const
+            {
+                return pos / bits_in_data_type_;
+            }
+
+            size_t get_bit_idx_(size_t pos) const
+            {
+                return pos % bits_in_data_type_;
+            }
+
+            bool get_bit_(data_type data, size_t bit_idx) const
+            {
+                return data & (one_ << bit_idx);
+            }
+
+            void set_bit_(size_t data_idx, size_t bit_idx, bool val)
+            {
+                if (val)
+                    data_[data_idx] |= (one_ << bit_idx);
+                else
+                    data_[data_idx] &= ~(one_ << bit_idx);
+            }
+    };
+
+    /**
+     * 20.6.3 hash support:
+     */
+
+    template<class T>
+    struct hash;
+
+    template<size_t N>
+    struct hash<bitset<N>>
+    {
+        size_t operator()(const bitset<N>& set) const noexcept
+        {
+            return hash<unsigned long long>{}(set.to_ullong());
+        }
+
+        using argument_type = bitset<N>;
+        using result_type   = size_t;
+    };
+
+    /**
+     * 20.6.4, bitset operators:
+     */
+
+    template<size_t N>
+    bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
+    {
+        return bitset<N>{lhs} &= rhs;
+    }
+
+    template<size_t N>
+    bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
+    {
+        return bitset<N>{lhs} |= rhs;
+    }
+
+    template<size_t N>
+    bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
+    {
+        return bitset<N>{lhs} ^= rhs;
+    }
+
+    template<class Char, class Traits, size_t N>
+    basic_istream<Char, Traits>&
+    operator>>(basic_istream<Char, Traits>& is, bitset<N>& set)
+    {
+        size_t i{};
+        Char c{};
+        Char zero{is.widen('0')};
+        Char one{is.widen('1')};
+
+        basic_string<Char, Traits> str{};
+        while (i < N)
+        {
+            if (is.eof())
+                break;
+
+            is.get(c);
+
+            if (!Traits::eq(c, one) && !Traits::eq(c, zero))
+            {
+                is.putback(c);
+                break;
+            }
+
+            str.push_back(c);
+            ++i;
+        }
+
+        if (i == 0)
+            is.setstate(ios_base::failbit);
+
+        set = bitset<N>{str};
+
+        return is;
+    }
+
+    template<class Char, class Traits, size_t N>
+    basic_ostream<Char, Traits>&
+    operator<<(basic_ostream<Char, Traits>& os, const bitset<N>& set)
+    {
+        return os << set.template to_string<Char, Traits, allocator<Char>>(
+            use_facet<ctype<Char>>(os.getloc()).widen('0'),
+            use_facet<ctype<Char>>(os.getloc()).widen('1')
+        );
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/deque.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/deque.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/deque.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1218 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_DEQUE
+#define LIBCPP_BITS_ADT_DEQUE
+
+#include <__bits/insert_iterator.hpp>
+#include <algorithm>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
+
+namespace std
+{
+    template<class T, class Allocator = allocator<T>>
+    class deque;
+
+    namespace aux
+    {
+        /**
+         * Note: We decided that these iterators contain a
+         *       reference to the container and an index, which
+         *       allows us to use the already implemented operator[]
+         *       on deque and also allows us to conform to the requirement
+         *       of the standard that functions such as push_back
+         *       invalidate the .end() iterator.
+         */
+
+        template<class T, class Allocator>
+        class deque_iterator;
+
+        template<class T, class Allocator>
+        class deque_const_iterator
+        {
+            public:
+                using size_type         = typename deque<T, Allocator>::size_type;
+                using value_type        = typename deque<T, Allocator>::value_type;
+                using reference         = typename deque<T, Allocator>::const_reference;
+                using difference_type   = size_type;
+                using pointer           = const value_type*;
+                using iterator_category = random_access_iterator_tag;
+
+                deque_const_iterator(const deque<T, Allocator>& deq, size_type idx)
+                    : deq_{deq}, idx_{idx}
+                { /* DUMMY BODY */ }
+
+                deque_const_iterator(const deque_const_iterator& other)
+                    : deq_{other.deq_}, idx_{other.idx_}
+                { /* DUMMY BODY */ }
+
+                deque_const_iterator& operator=(const deque_const_iterator& other)
+                {
+                    deq_ = other.deq_;
+                    idx_ = other.idx_;
+
+                    return *this;
+                }
+
+                reference operator*() const
+                {
+                    return deq_[idx_];
+                }
+
+                pointer operator->() const
+                {
+                    return addressof(deq_[idx_]);
+                }
+
+                deque_const_iterator& operator++()
+                {
+                    ++idx_;
+
+                    return *this;
+                }
+
+                deque_const_iterator operator++(int)
+                {
+                    return deque_const_iterator{deq_, idx_++};
+                }
+
+                deque_const_iterator& operator--()
+                {
+                    --idx_;
+
+                    return *this;
+                }
+
+                deque_const_iterator operator--(int)
+                {
+                    return deque_const_iterator{deq_, idx_--};
+                }
+
+                deque_const_iterator operator+(difference_type n)
+                {
+                    return deque_const_iterator{deq_, idx_ + n};
+                }
+
+                deque_const_iterator& operator+=(difference_type n)
+                {
+                    idx_ += n;
+
+                    return *this;
+                }
+
+                deque_const_iterator operator-(difference_type n)
+                {
+                    return deque_const_iterator{deq_, idx_ - n};
+                }
+
+                deque_const_iterator& operator-=(difference_type n)
+                {
+                    idx_ -= n;
+
+                    return *this;
+                }
+
+                reference operator[](difference_type n) const
+                {
+                    return deq_[idx_ + n];
+                }
+
+                difference_type operator-(const deque_const_iterator& rhs)
+                {
+                    return idx_ - rhs.idx_;
+                }
+
+                size_type idx() const
+                {
+                    return idx_;
+                }
+
+                operator deque_iterator<T, Allocator>()
+                {
+                    return deque_iterator{
+                        const_cast<deque<T, Allocator>&>(deq_), idx_
+                    };
+                }
+
+            private:
+                const deque<T, Allocator>& deq_;
+                size_type idx_;
+        };
+
+        template<class T, class Allocator>
+        bool operator==(const deque_const_iterator<T, Allocator>& lhs,
+                        const deque_const_iterator<T, Allocator>& rhs)
+        {
+            return lhs.idx() == rhs.idx();
+        }
+
+        template<class T, class Allocator>
+        bool operator!=(const deque_const_iterator<T, Allocator>& lhs,
+                        const deque_const_iterator<T, Allocator>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template<class T, class Allocator>
+        class deque_iterator
+        {
+            public:
+                using size_type         = typename deque<T, Allocator>::size_type;
+                using value_type        = typename deque<T, Allocator>::value_type;
+                using reference         = typename deque<T, Allocator>::reference;
+                using difference_type   = size_type;
+                using pointer           = value_type*;
+                using iterator_category = random_access_iterator_tag;
+
+                deque_iterator(deque<T, Allocator>& deq, size_type idx)
+                    : deq_{deq}, idx_{idx}
+                { /* DUMMY BODY */ }
+
+                deque_iterator(const deque_iterator& other)
+                    : deq_{other.deq_}, idx_{other.idx_}
+                { /* DUMMY BODY */ }
+
+                deque_iterator(const deque_const_iterator<T, Allocator>& other)
+                    : deq_{other.deq_}, idx_{other.idx_}
+                { /* DUMMY BODY */ }
+
+                deque_iterator& operator=(const deque_iterator& other)
+                {
+                    deq_ = other.deq_;
+                    idx_ = other.idx_;
+
+                    return *this;
+                }
+
+                deque_iterator& operator=(const deque_const_iterator<T, Allocator>& other)
+                {
+                    deq_ = other.deq_;
+                    idx_ = other.idx_;
+
+                    return *this;
+                }
+
+                reference operator*()
+                {
+                    return deq_[idx_];
+                }
+
+                pointer operator->()
+                {
+                    return addressof(deq_[idx_]);
+                }
+
+                deque_iterator& operator++()
+                {
+                    ++idx_;
+
+                    return *this;
+                }
+
+                deque_iterator operator++(int)
+                {
+                    return deque_iterator{deq_, idx_++};
+                }
+
+                deque_iterator& operator--()
+                {
+                    --idx_;
+
+                    return *this;
+                }
+
+                deque_iterator operator--(int)
+                {
+                    return deque_iterator{deq_, idx_--};
+                }
+
+                deque_iterator operator+(difference_type n)
+                {
+                    return deque_iterator{deq_, idx_ + n};
+                }
+
+                deque_iterator& operator+=(difference_type n)
+                {
+                    idx_ += n;
+
+                    return *this;
+                }
+
+                deque_iterator operator-(difference_type n)
+                {
+                    return deque_iterator{deq_, idx_ - n};
+                }
+
+                deque_iterator& operator-=(difference_type n)
+                {
+                    idx_ -= n;
+
+                    return *this;
+                }
+
+                reference operator[](difference_type n) const
+                {
+                    return deq_[idx_ + n];
+                }
+
+                difference_type operator-(const deque_iterator& rhs)
+                {
+                    return idx_ - rhs.idx_;
+                }
+
+                size_type idx() const
+                {
+                    return idx_;
+                }
+
+                operator deque_const_iterator<T, Allocator>()
+                {
+                    return deque_const_iterator{deq_, idx_};
+                }
+
+            private:
+                deque<T, Allocator>& deq_;
+                size_type idx_;
+        };
+
+        template<class T, class Allocator>
+        bool operator==(const deque_iterator<T, Allocator>& lhs,
+                        const deque_iterator<T, Allocator>& rhs)
+        {
+            return lhs.idx() == rhs.idx();
+        }
+
+        template<class T, class Allocator>
+        bool operator!=(const deque_iterator<T, Allocator>& lhs,
+                        const deque_iterator<T, Allocator>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+    }
+
+    /**
+     * 23.3.3 deque:
+     */
+
+    template<class T, class Allocator>
+    class deque
+    {
+        public:
+            using allocator_type  = Allocator;
+            using value_type      = T;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+
+            using iterator               = aux::deque_iterator<T, Allocator>;
+            using const_iterator         = aux::deque_const_iterator<T, Allocator>;
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            using size_type       = typename allocator_traits<allocator_type>::size_type;
+            using difference_type = typename allocator_traits<allocator_type>::difference_type;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+
+            /**
+             * 23.3.3.2, construct/copy/destroy:
+             */
+
+            deque()
+                : deque{allocator_type{}}
+            { /* DUMMY BODY */ }
+
+            explicit deque(const allocator_type& alloc)
+                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
+                  back_bucket_idx_{0}, front_bucket_{default_front_},
+                  back_bucket_{default_back_}, bucket_count_{default_bucket_count_},
+                  bucket_capacity_{default_bucket_capacity_}, size_{}, data_{}
+            {
+                init_();
+            }
+
+            explicit deque(size_type n, const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, front_bucket_idx_{bucket_size_}, back_bucket_idx_{},
+                  front_bucket_{}, back_bucket_{}, bucket_count_{},
+                  bucket_capacity_{}, size_{n}, data_{}
+            {
+                prepare_for_size_(n);
+                init_();
+
+                for (size_type i = 0; i < size_; ++i)
+                    allocator_.construct(&(*this)[i]);
+                back_bucket_idx_ = size_ % bucket_size_;
+            }
+
+            deque(size_type n, const value_type& value, const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, front_bucket_idx_{bucket_size_}, back_bucket_idx_{},
+                  front_bucket_{}, back_bucket_{}, bucket_count_{},
+                  bucket_capacity_{}, size_{n}, data_{}
+            {
+                prepare_for_size_(n);
+                init_();
+
+                for (size_type i = 0; i < size_; ++i)
+                    (*this)[i] = value;
+                back_bucket_idx_ = size_ % bucket_size_;
+            }
+
+            template<class InputIterator>
+            deque(InputIterator first, InputIterator last,
+                  const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
+                  back_bucket_idx_{}, front_bucket_{}, back_bucket_{},
+                  bucket_count_{}, bucket_capacity_{}, size_{},
+                  data_{}
+            {
+                copy_from_range_(first, last);
+            }
+
+            deque(const deque& other)
+                : deque{other.begin(), other.end(), other.allocator_}
+            { /* DUMMY BODY */ }
+
+            deque(deque&& other)
+                : allocator_{move(other.allocator_)},
+                  front_bucket_idx_{other.front_bucket_idx_},
+                  back_bucket_idx_{other.back_bucket_idx_},
+                  front_bucket_{other.front_bucket_},
+                  back_bucket_{other.back_bucket_},
+                  bucket_count_{other.bucket_count_},
+                  bucket_capacity_{other.bucket_capacity_},
+                  size_{other.size_}, data_{other.data_}
+            {
+                other.data_ = nullptr;
+                other.clear();
+            }
+
+            deque(const deque& other, const allocator_type& alloc)
+                : deque{other.begin(), other.end(), alloc}
+            { /* DUMMY BODY */ }
+
+            deque(deque&& other, const allocator_type& alloc)
+                : allocator_{alloc},
+                  front_bucket_idx_{other.front_bucket_idx_},
+                  back_bucket_idx_{other.front_bucket_idx_},
+                  front_bucket_{other.front_bucket_},
+                  back_bucket_{other.back_bucket_},
+                  bucket_count_{other.bucket_count_},
+                  bucket_capacity_{other.bucket_capacity_},
+                  size_{other.size_}, data_{other.data_}
+            {
+                other.data_ = nullptr;
+                other.clear();
+            }
+
+            deque(initializer_list<T> init, const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
+                  back_bucket_idx_{}, front_bucket_{}, back_bucket_{},
+                  bucket_count_{}, bucket_capacity_{}, size_{},
+                  data_{}
+            {
+                copy_from_range_(init.begin(), init.end());
+            }
+
+            ~deque()
+            {
+                fini_();
+            }
+
+            deque& operator=(const deque& other)
+            {
+                if (data_)
+                    fini_();
+
+                copy_from_range_(other.begin(), other.end());
+
+                return *this;
+            }
+
+            deque& operator=(deque&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                swap(other);
+                other.clear();
+
+                return *this;
+            }
+
+            deque& operator=(initializer_list<T> init)
+            {
+                if (data_)
+                    fini_();
+
+                copy_from_range_(init.begin(), init.end());
+
+                return *this;
+            }
+
+            template<class InputIterator>
+            void assign(InputIterator first, InputIterator last)
+            {
+                copy_from_range_(first, last);
+            }
+
+            void assign(size_type n, const T& value)
+            {
+                prepare_for_size_(n);
+                init_();
+                size_ = n;
+
+                auto it = begin();
+                for (size_type i = size_type{}; i < n; ++i)
+                    *it++ = value;
+            }
+
+            void assign(initializer_list<T> init)
+            {
+                copy_from_range_(init.begin(), init.end());
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return aux::deque_iterator{*this, 0};
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return aux::deque_const_iterator{*this, 0};
+            }
+
+            iterator end() noexcept
+            {
+                return aux::deque_iterator{*this, size_};
+            }
+
+            const_iterator end() const noexcept
+            {
+                return aux::deque_const_iterator{*this, size_};
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return make_reverse_iterator(end());
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return make_reverse_iterator(begin());
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return aux::deque_const_iterator{*this, 0};
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return aux::deque_const_iterator{*this, size_};
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            /**
+             * 23.3.3.3, capacity:
+             */
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type max_size() const noexcept
+            {
+                return allocator_traits<allocator_type>::max_size(allocator_);
+            }
+
+            void resize(size_type sz)
+            {
+                if (sz <= size_)
+                {
+                    auto count = size_ - sz;
+                    for (size_type i = 0; i < count; ++i)
+                        pop_back();
+                }
+                else
+                {
+                    value_type value{};
+                    auto count = sz - size_;
+                    for (size_type i = 0; i < count; ++i)
+                        push_back(value);
+                }
+            }
+
+            void resize(size_type sz, const value_type& value)
+            {
+                if (sz <= size_)
+                {
+                    auto count = size_ - sz;
+                    for (size_type i = 0; i < count; ++i)
+                        pop_back();
+                }
+                else
+                {
+                    auto count = sz - size_;
+                    for (size_type i = 0; i < count; ++i)
+                        push_back(value);
+                }
+            }
+
+            void shrink_to_fit()
+            {
+                /**
+                 * We lazily allocate buckets and eagerily deallocate them.
+                 * We cannot go into smaller pieces as buckets have fixed size.
+                 * Because of this, shrink_to_fit has no effect (as permitted
+                 * by the standard).
+                 */
+            }
+
+            bool empty() const noexcept
+            {
+                return size_ == size_type{};
+            }
+
+            reference operator[](size_type idx)
+            {
+                return data_[get_bucket_index_(idx)][get_element_index_(idx)];
+            }
+
+            const_reference operator[](size_type idx) const
+            {
+                return data_[get_bucket_index_(idx)][get_element_index_(idx)];
+            }
+
+            reference at(size_type idx)
+            {
+                // TODO: bounds checking
+                return operator[](idx);
+            }
+
+            const_reference at(size_type idx) const
+            {
+                // TODO: bounds checking
+                return operator[](idx);
+            }
+
+            reference front()
+            {
+                return *begin();
+            }
+
+            const_reference front() const
+            {
+                return *cbegin();
+            }
+
+            reference back()
+            {
+                auto tmp = end();
+
+                return *(--tmp);
+            }
+
+            const_reference back() const
+            {
+                auto tmp = cend();
+
+                return *(--tmp);
+            }
+
+            /**
+             * 23.3.3.4, modifiers:
+             */
+
+            template<class... Args>
+            void emplace_front(Args&&... args)
+            {
+                if (front_bucket_idx_ == 0)
+                    add_new_bucket_front_();
+
+                allocator_traits<allocator_type>::construct(
+                    allocator_,
+                    &data_[front_bucket_][--front_bucket_idx_],
+                    forward<Args>(args)...
+                );
+
+                ++size_;
+            }
+
+            template<class... Args>
+            void emplace_back(Args&&... args)
+            {
+                allocator_traits<allocator_type>::construct(
+                    allocator_,
+                    &data_[back_bucket_][back_bucket_idx_++],
+                    forward<Args>(args)...
+                );
+
+                ++size_;
+
+                if (back_bucket_idx_ >= bucket_size_)
+                    add_new_bucket_back_();
+            }
+
+            template<class... Args>
+            iterator emplace(const_iterator position, Args&&... args)
+            {
+                auto idx = position.idx();
+                shift_right_(idx, 1);
+
+                allocator_traits<allocator_type>::construct(
+                    allocator_,
+                    &data_[get_bucket_index_(idx)][get_element_index_(idx)],
+                    forward<Args>(args)...
+                );
+                ++size_;
+
+                return iterator{*this, idx};
+            }
+
+            void push_front(const value_type& value)
+            {
+                if (front_bucket_idx_ == 0)
+                    add_new_bucket_front_();
+
+                data_[front_bucket_][--front_bucket_idx_] = value;
+                ++size_;
+            }
+
+            void push_front(value_type&& value)
+            {
+                if (front_bucket_idx_ == 0)
+                    add_new_bucket_front_();
+
+                data_[front_bucket_][--front_bucket_idx_] = forward<value_type>(value);
+                ++size_;
+            }
+
+            void push_back(const value_type& value)
+            {
+                data_[back_bucket_][back_bucket_idx_++] = value;
+                ++size_;
+
+                if (back_bucket_idx_ >= bucket_size_)
+                    add_new_bucket_back_();
+            }
+
+            void push_back(value_type&& value)
+            {
+                data_[back_bucket_][back_bucket_idx_++] = forward<value_type>(value);
+                ++size_;
+
+                if (back_bucket_idx_ >= bucket_size_)
+                    add_new_bucket_back_();
+            }
+
+            iterator insert(const_iterator position, const value_type& value)
+            {
+                auto idx = position.idx();
+                shift_right_(idx, 1);
+
+                /**
+                 * Note: One may notice that when working with the deque
+                 *       iterator, we use its index without any checks.
+                 *       This is because a valid iterator will always have
+                 *       a valid index as functions like pop_back or erase
+                 *       invalidate iterators.
+                 */
+                data_[get_bucket_index_(idx)][get_element_index_(idx)] = value;
+                ++size_;
+
+                return iterator{*this, idx};
+            }
+
+            iterator insert(const_iterator position, value_type&& value)
+            {
+                auto idx = position.idx();
+                shift_right_(idx, 1);
+
+                data_[get_bucket_index_(idx)][get_element_index_(idx)] = forward<value_type>(value);
+                ++size_;
+
+                return iterator{*this, idx};
+            }
+
+            iterator insert(const_iterator position, size_type n, const value_type& value)
+            {
+                return insert(
+                    position,
+                    aux::insert_iterator<int>{0u, value},
+                    aux::insert_iterator<int>{n}
+                );
+            }
+
+            template<class InputIterator>
+            iterator insert(const_iterator position, InputIterator first, InputIterator last)
+            {
+                auto idx = position.idx();
+                auto count = distance(first, last);
+
+                if (idx < size_ / 2)
+                {
+                    shift_left_(idx, count);
+
+                    iterator it{*this, idx - 1};
+                    while (first != last)
+                        *it++ = *first++;
+                }
+                else
+                {
+                    shift_right_(idx, count);
+
+                    iterator it{*this, idx};
+                    while (first != last)
+                        *it++ = *first++;
+                }
+
+                size_ += count;
+
+                return iterator{*this, idx};
+            }
+
+            iterator insert(const_iterator position, initializer_list<value_type> init)
+            {
+                return insert(position, init.begin(), init.end());
+            }
+
+            void pop_back()
+            {
+                if (empty())
+                    return;
+
+                if (back_bucket_idx_ == 0)
+                { // Means we gotta pop data_[back_bucket_ - 1][bucket_size_ - 1]!
+                    if (data_[back_bucket_])
+                        allocator_.deallocate(data_[back_bucket_], bucket_size_);
+
+                    --back_bucket_;
+                    back_bucket_idx_ = bucket_size_ - 1;
+                }
+                else
+                    --back_bucket_idx_;
+
+                allocator_.destroy(&data_[back_bucket_][back_bucket_idx_]);
+                --size_;
+            }
+
+            void pop_front()
+            {
+                if (empty())
+                    return;
+
+                if (front_bucket_idx_ >= bucket_size_)
+                { // Means we gotta pop data_[front_bucket_ + 1][0]!
+                    if (data_[front_bucket_])
+                        allocator_.deallocate(data_[front_bucket_], bucket_size_);
+
+                    ++front_bucket_;
+                    front_bucket_idx_ = 1;
+
+                    allocator_.destroy(&data_[front_bucket_][0]);
+                }
+                else
+                {
+                    allocator_.destroy(&data_[front_bucket_][front_bucket_idx_]);
+
+                    ++front_bucket_idx_;
+                }
+
+                --size_;
+            }
+
+            iterator erase(const_iterator position)
+            {
+                auto idx = position.idx();
+                copy(
+                    iterator{*this, idx + 1},
+                    end(),
+                    iterator{*this, idx}
+                );
+
+                /**
+                 * Note: We need to not only decrement size,
+                 *       but also take care of any issues caused
+                 *       by decrement bucket indices, which pop_back
+                 *       does for us.
+                 */
+                pop_back();
+
+                return iterator{*this, idx};
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                if (first == last)
+                    return first;
+
+                auto first_idx = first.idx();
+                auto last_idx = last.idx();
+                auto count = distance(first, last);
+
+                copy(
+                    iterator{*this, last_idx},
+                    end(),
+                    iterator{*this, first_idx}
+                );
+
+                for (size_type i = 0; i < count; ++i)
+                    pop_back();
+
+                return iterator{*this, first_idx};
+            }
+
+            void swap(deque& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                std::swap(allocator_, other.allocator_);
+                std::swap(front_bucket_idx_, other.front_bucket_idx_);
+                std::swap(back_bucket_idx_, other.back_bucket_idx_);
+                std::swap(front_bucket_, other.front_bucket_);
+                std::swap(back_bucket_, other.back_bucket_);
+                std::swap(bucket_count_, other.bucket_count_);
+                std::swap(bucket_capacity_, other.bucket_capacity_);
+                std::swap(size_, other.size_);
+                std::swap(data_, other.data_);
+            }
+
+            void clear() noexcept
+            {
+                if (data_)
+                    fini_();
+
+                front_bucket_ = default_front_;
+                back_bucket_ = default_back_;
+                bucket_count_ = default_bucket_count_;
+                bucket_capacity_ = default_bucket_capacity_;
+                size_ = size_type{};
+
+                init_();
+            }
+
+        private:
+            allocator_type allocator_;
+
+            /**
+             * Note: In our implementation, front_bucket_idx_
+             *       points at the first element and back_bucket_idx_
+             *       points at the one past last element. Because of this,
+             *       some operations may be done in inverse order
+             *       depending on the side they are applied to.
+             */
+            size_type front_bucket_idx_;
+            size_type back_bucket_idx_;
+            size_type front_bucket_;
+            size_type back_bucket_;
+
+            static constexpr size_type bucket_size_{16};
+            static constexpr size_type default_bucket_count_{2};
+            static constexpr size_type default_bucket_capacity_{4};
+            static constexpr size_type default_front_{1};
+            static constexpr size_type default_back_{2};
+
+            size_type bucket_count_;
+            size_type bucket_capacity_;
+            size_type size_{};
+
+            value_type** data_;
+
+            void init_()
+            {
+                data_ = new value_type*[bucket_capacity_];
+
+                for (size_type i = front_bucket_; i <= back_bucket_; ++i)
+                    data_[i] = allocator_.allocate(bucket_size_);
+            }
+
+            void prepare_for_size_(size_type size)
+            {
+                if (data_)
+                    fini_();
+
+                bucket_count_ = bucket_capacity_ = size / bucket_size_ + 2;
+
+                front_bucket_ = 0;
+                back_bucket_ = bucket_capacity_ - 1;
+
+                front_bucket_idx_ = bucket_size_;
+                back_bucket_idx_ = size % bucket_size_;
+            }
+
+            template<class Iterator>
+            void copy_from_range_(Iterator first, Iterator last)
+            {
+                size_ = distance(first, last);
+                prepare_for_size_(size_);
+                init_();
+
+                auto it = begin();
+                while (first != last)
+                    *it++ = *first++;
+            }
+
+            void ensure_space_front_(size_type idx, size_type count)
+            {
+                auto free_space = bucket_size_ - elements_in_front_bucket_();
+                if (front_bucket_idx_ == 0)
+                    free_space = 0;
+
+                if (count <= free_space)
+                {
+                    front_bucket_idx_ -= count;
+                    return;
+                }
+
+                count -= free_space;
+
+                auto buckets_needed = count / bucket_size_;
+                if (count % bucket_size_ != 0)
+                    ++buckets_needed;
+
+                for (size_type i = size_type{}; i < buckets_needed; ++i)
+                    add_new_bucket_front_();
+
+                front_bucket_idx_ = bucket_size_ - (count % bucket_size_);
+            }
+
+            void ensure_space_back_(size_type idx, size_type count)
+            {
+                auto free_space = bucket_size_ - back_bucket_idx_;
+                if (count < free_space)
+                    return;
+
+                count -= free_space;
+                auto buckets_needed = count / bucket_size_;
+                if (count % bucket_size_ != 0)
+                    ++buckets_needed;
+
+                for (size_type i = size_type{}; i < buckets_needed; ++i)
+                    add_new_bucket_back_();
+
+                back_bucket_idx_ = (back_bucket_idx_ + count) % bucket_size_;
+            }
+
+            void shift_right_(size_type idx, size_type count)
+            {
+                ensure_space_back_(idx, count);
+
+                iterator it{*this, idx};
+                copy_backward(it, end(), end() + count - 1);
+
+            }
+
+            void shift_left_(size_type idx, size_type count)
+            {
+                ensure_space_front_(idx, count);
+
+                copy(
+                    iterator{*this, count},
+                    iterator{*this, idx + count - 1},
+                    iterator{*this, 0}
+                );
+            }
+
+            void fini_()
+            {
+                for (size_type i = front_bucket_; i <= back_bucket_; ++i)
+                    allocator_.deallocate(data_[i], bucket_size_);
+
+                delete[] data_;
+                data_ = nullptr;
+            }
+
+            bool has_bucket_space_back_() const
+            {
+                return back_bucket_ < bucket_capacity_ - 1;
+            }
+
+            bool has_bucket_space_front_() const
+            {
+                return front_bucket_ > 0;
+            }
+
+            void add_new_bucket_back_()
+            {
+                if (!has_bucket_space_back_())
+                    expand_();
+
+                ++back_bucket_;
+                ++bucket_count_;
+                data_[back_bucket_] = allocator_.allocate(bucket_size_);
+                back_bucket_idx_ = size_type{};
+            }
+
+            void add_new_bucket_front_()
+            {
+                if (!has_bucket_space_front_())
+                    expand_();
+
+                --front_bucket_;
+                ++bucket_count_;
+                data_[front_bucket_] = allocator_.allocate(bucket_size_);
+                front_bucket_idx_ = bucket_size_;
+            }
+
+            void expand_()
+            {
+                bucket_capacity_ *= 2;
+                value_type** new_data = new value_type*[bucket_capacity_];
+
+                /**
+                 * Note: This currently expands both sides whenever one reaches
+                 *       its limit. Might be better to expand only one (or both when
+                 *       the other is near its limit)?
+                 */
+                size_type new_front = bucket_capacity_ / 4;
+                size_type new_back = new_front + bucket_count_ - 1;
+
+                for (size_type i = new_front, j = front_bucket_; i <= new_back; ++i, ++j)
+                    new_data[i] = move(data_[j]);
+                std::swap(data_, new_data);
+
+                delete[] new_data;
+                front_bucket_ = new_front;
+                back_bucket_ = new_back;
+            }
+
+            size_type get_bucket_index_(size_type idx) const
+            {
+                if (idx < elements_in_front_bucket_())
+                    return front_bucket_;
+
+                idx -= elements_in_front_bucket_();
+                return idx / bucket_size_ + front_bucket_ + 1;
+            }
+
+            size_type get_element_index_(size_type idx) const
+            {
+                if (idx < elements_in_front_bucket_())
+                    return bucket_size_ - elements_in_front_bucket_() + idx;
+
+                idx -= elements_in_front_bucket_();
+                return idx % bucket_size_;
+            }
+
+            size_type elements_in_front_bucket_() const
+            {
+                return bucket_size_ - front_bucket_idx_;
+            }
+    };
+
+    template<class T, class Allocator>
+    bool operator==(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        if (lhs.size() != rhs.size())
+            return false;
+
+        for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i)
+        {
+            if (lhs[i] != rhs[i])
+                return false;
+        }
+
+        return true;
+    }
+
+    template<class T, class Allocator>
+    bool operator<(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        auto min_size = min(lhs.size(), rhs.size());
+        for (decltype(lhs.size()) i = 0; i < min_size; ++i)
+        {
+            if (lhs[i] >= rhs[i])
+                return false;
+        }
+
+        if (lhs.size() == rhs.size())
+            return true;
+        else
+            return lhs.size() < rhs.size();
+    }
+
+    template<class T, class Allocator>
+    bool operator!=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class T, class Allocator>
+    bool operator>(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class T, class Allocator>
+    bool operator<=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class T, class Allocator>
+    bool operator>=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    /**
+     * 23.3.3.5, deque specialized algorithms:
+     */
+
+    template<class T, class Allocator>
+    void swap(deque<T, Allocator>& lhs, deque<T, Allocator>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/forward_list.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/forward_list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/forward_list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_FORWARD_LIST
+#define LIBCPP_BITS_ADT_FORWARD_LIST
+
+#error "<forward_list> is not implemented"
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/hash_table.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/hash_table.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/hash_table.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_HASH_TABLE
+#define LIBCPP_BITS_ADT_HASH_TABLE
+
+#include <__bits/adt/list_node.hpp>
+#include <__bits/adt/key_extractors.hpp>
+#include <__bits/adt/hash_table_iterators.hpp>
+#include <__bits/adt/hash_table_policies.hpp>
+#include <cstdlib>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <tuple>
+#include <utility>
+
+namespace std::aux
+{
+    /**
+     * To save code, we're going to implement one hash table
+     * for both unordered_map and unordered_set. To do this,
+     * we create one inner hash table that is oblivious to its
+     * held type (and uses a key extractor to get the key from it)
+     * and two proxies that either use plain Key type or a pair
+     * of a key and a value.
+     * Additionally, we will use policies to represent both single
+     * and multi variants of these containers at once.
+     * Note: I am aware the naming is very unimaginative here,
+     *       not my strong side :)
+     */
+
+    template<
+        class Value, class Key, class KeyExtractor,
+        class Hasher, class KeyEq,
+        class Alloc, class Size,
+        class Iterator, class ConstIterator,
+        class LocalIterator, class ConstLocalIterator,
+        class Policy
+    >
+    class hash_table
+    {
+        public:
+            using value_type     = Value;
+            using key_type       = Key;
+            using size_type      = Size;
+            using allocator_type = Alloc;
+            using key_equal      = KeyEq;
+            using hasher         = Hasher;
+            using key_extract    = KeyExtractor;
+
+            using iterator             = Iterator;
+            using const_iterator       = ConstIterator;
+            using local_iterator       = LocalIterator;
+            using const_local_iterator = ConstLocalIterator;
+
+            using node_type = list_node<value_type>;
+
+            using place_type = tuple<
+                hash_table_bucket<value_type, size_type>*,
+                list_node<value_type>*, size_type
+            >;
+
+            hash_table(size_type buckets, float max_load_factor = 1.f)
+                : table_{new hash_table_bucket<value_type, size_type>[buckets]()},
+                  bucket_count_{buckets}, size_{}, hasher_{}, key_eq_{},
+                  key_extractor_{}, max_load_factor_{max_load_factor}
+            { /* DUMMY BODY */ }
+
+            hash_table(size_type buckets, const hasher& hf, const key_equal& eql,
+                       float max_load_factor = 1.f)
+                : table_{new hash_table_bucket<value_type, size_type>[buckets]()},
+                  bucket_count_{buckets}, size_{}, hasher_{hf}, key_eq_{eql},
+                  key_extractor_{}, max_load_factor_{max_load_factor}
+            { /* DUMMY BODY */ }
+
+            hash_table(const hash_table& other)
+                : hash_table{other.bucket_count_, other.hasher_, other.key_eq_,
+                             other.max_load_factor_}
+            {
+                for (const auto& x: other)
+                    insert(x);
+            }
+
+            hash_table(hash_table&& other)
+                : table_{other.table_}, bucket_count_{other.bucket_count_},
+                  size_{other.size_}, hasher_{move(other.hasher_)},
+                  key_eq_{move(other.key_eq_)}, key_extractor_{move(other.key_extractor_)},
+                  max_load_factor_{other.max_load_factor_}
+            {
+                other.table_ = nullptr;
+                other.bucket_count_ = size_type{};
+                other.size_ = size_type{};
+                other.max_load_factor_ = 1.f;
+            }
+
+            hash_table& operator=(const hash_table& other)
+            {
+                hash_table tmp{other};
+                tmp.swap(*this);
+
+                return *this;
+            }
+
+            hash_table& operator=(hash_table&& other)
+            {
+                hash_table tmp{move(other)};
+                tmp.swap(*this);
+
+                return *this;
+            }
+
+            bool empty() const noexcept
+            {
+                return size_ == 0;
+            }
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type max_size(allocator_type& alloc)
+            {
+                return allocator_traits<allocator_type>::max_size(alloc);
+            }
+
+            iterator begin() noexcept
+            {
+                auto idx = first_filled_bucket_();
+                return iterator{
+                    table_, idx, bucket_count_,
+                    table_[idx].head
+                };
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return iterator{};
+            }
+
+            const_iterator end() const noexcept
+            {
+                return cend();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                auto idx = first_filled_bucket_();
+                return const_iterator{
+                    table_, idx, bucket_count_,
+                    table_[idx].head
+                };
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return const_iterator{};
+            }
+
+            template<class... Args>
+            auto emplace(Args&&... args)
+            {
+                return Policy::emplace(*this, forward<Args>(args)...);
+            }
+
+            auto insert(const value_type& val)
+            {
+                return Policy::insert(*this, val);
+            }
+
+            auto insert(value_type&& val)
+            {
+                return Policy::insert(*this, forward<value_type>(val));
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return Policy::erase(*this, key);
+            }
+
+            iterator erase(const_iterator it)
+            {
+                auto node = it.node();
+                auto idx = it.idx();
+
+                /**
+                 * Note: This way we will continue on the next bucket
+                 *       if this is the last element in its bucket.
+                 */
+                iterator res{table_, idx, size_, node};
+                ++res;
+
+                if (table_[idx].head == node)
+                {
+                    if (node->next != node)
+                        table_[idx].head = node->next;
+                    else
+                        table_[idx].head = nullptr;
+                }
+                --size_;
+
+                node->unlink();
+                delete node;
+
+                return res;
+            }
+
+            void clear() noexcept
+            {
+                for (size_type i = 0; i < bucket_count_; ++i)
+                    table_[i].clear();
+                size_ = size_type{};
+            }
+
+            void swap(hash_table& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(swap(declval<Hasher&>(), declval<Hasher&>())) &&
+                         noexcept(swap(declval<KeyEq&>(), declval<KeyEq&>())))
+            {
+                std::swap(table_, other.table_);
+                std::swap(bucket_count_, other.bucket_count_);
+                std::swap(size_, other.size_);
+                std::swap(hasher_, other.hasher_);
+                std::swap(key_eq_, other.key_eq_);
+                std::swap(max_load_factor_, other.max_load_factor_);
+            }
+
+            hasher hash_function() const
+            {
+                return hasher_;
+            }
+
+            key_equal key_eq() const
+            {
+                return key_eq_;
+            }
+
+            iterator find(const key_type& key)
+            {
+                auto idx = get_bucket_idx_(key);
+                auto head = table_[idx].head;
+
+                if (!head)
+                    return end();
+
+                auto current = head;
+                do
+                {
+                    if (key_eq_(key, key_extractor_(current->value)))
+                        return iterator{table_, idx, size_, current};
+                    current = current->next;
+                }
+                while (current != head);
+
+                return end();
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                auto idx = get_bucket_idx_(key);
+                auto head = table_[idx].head;
+
+                if (!head)
+                    return end();
+
+                auto current = head;
+                do
+                {
+                    if (key_eq_(key, key_extractor_(current->value)))
+                        return iterator{table_, idx, size_, current};
+                    current = current->next;
+                }
+                while (current != head);
+
+                return end();
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return Policy::count(*this, key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return Policy::equal_range(*this, key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return Policy::equal_range_const(*this, key);
+            }
+
+            size_type bucket_count() const noexcept
+            {
+                return bucket_count_;
+            }
+
+            size_type max_bucket_count() const noexcept
+            {
+                return numeric_limits<size_type>::max() /
+                       sizeof(hash_table_bucket<value_type, size_type>);
+            }
+
+            size_type bucket_size(size_type n) const
+            {
+                return table_[n].size();
+            }
+
+            size_type bucket(const key_type& key) const
+            {
+                return get_bucket_idx_(key);
+            }
+
+            local_iterator begin(size_type n)
+            {
+                return local_iterator{table_[n].head, table_[n].head};
+            }
+
+            const_local_iterator begin(size_type n) const
+            {
+                return cbegin(n);
+            }
+
+            local_iterator end(size_type n)
+            {
+                return local_iterator{};
+            }
+
+            const_local_iterator end(size_type n) const
+            {
+                return cend(n);
+            }
+
+            const_local_iterator cbegin(size_type n) const
+            {
+                return const_local_iterator{table_[n].head, table_[n].head};
+            }
+
+            const_local_iterator cend(size_type n) const
+            {
+                return const_local_iterator{};
+            }
+
+            float load_factor() const noexcept
+            {
+                return size_ / static_cast<float>(bucket_count_);
+            }
+
+            float max_load_factor() const noexcept
+            {
+                return max_load_factor_;
+            }
+
+            void max_load_factor(float factor)
+            {
+                if (factor > 0.f)
+                    max_load_factor_ = factor;
+
+                rehash_if_needed();
+            }
+
+            void rehash(size_type count)
+            {
+                if (count < size_ / max_load_factor_)
+                    count = size_ / max_load_factor_;
+
+                /**
+                 * Note: If an exception is thrown, there
+                 *       is no effect. Since this is the only
+                 *       place where an exception (no mem) can
+                 *       be thrown and no changes to this have been
+                 *       made, we're ok.
+                 */
+                hash_table new_table{count, max_load_factor_};
+
+                for (std::size_t i = 0; i < bucket_count_; ++i)
+                {
+                    auto head = table_[i].head;
+                    if (!head)
+                        continue;
+
+                    auto current = head;
+
+                    do
+                    {
+                        auto next = current->next;
+
+                        current->next = current;
+                        current->prev = current;
+
+                        auto where = Policy::find_insertion_spot(
+                            new_table, key_extractor_(current->value)
+                        );
+
+                        /**
+                         * Note: We're rehashing, so we know each
+                         *       key can be inserted.
+                         */
+                        auto new_bucket = get<0>(where);
+                        auto new_successor = get<1>(where);
+
+                        if (new_successor)
+                            new_successor->append(current);
+                        else
+                            new_bucket->append(current);
+
+                        current = next;
+                    } while (current != head);
+
+                    table_[i].head = nullptr;
+                }
+
+                new_table.size_ = size_;
+                swap(new_table);
+
+                delete[] new_table.table_;
+                new_table.table_ = nullptr;
+            }
+
+            void reserve(size_type count)
+            {
+                rehash(count / max_load_factor_ + 1);
+            }
+
+            bool is_eq_to(const hash_table& other) const
+            {
+                if (size() != other.size())
+                    return false;
+
+                auto it = begin();
+                while (it != end())
+                {
+                    /**
+                     * For each key K we will check how many
+                     * instances of K are there in the table.
+                     * Then we will check if the count for K
+                     * is equal to that amount.
+                     */
+
+                    size_type cnt{};
+                    auto tmp = it;
+
+                    while (key_eq_(key_extractor_(*it), key_extractor_(*tmp)))
+                    {
+                        ++cnt;
+                        if (++tmp == end())
+                            break;
+                    }
+
+                    auto other_cnt = other.count(key_extractor_(*it));
+                    if (cnt != other_cnt)
+                        return false;
+
+                    it = tmp; // tmp  is one past *it's key.
+                }
+
+                return true;
+            }
+
+            ~hash_table()
+            {
+                // Lists are deleted in ~hash_table_bucket.
+                if (table_)
+                    delete[] table_;
+            }
+
+            place_type find_insertion_spot(const key_type& key) const
+            {
+                return Policy::find_insertion_spot(*this, key);
+            }
+
+            place_type find_insertion_spot(key_type&& key) const
+            {
+                return Policy::find_insertion_spot(*this, key);
+            }
+
+            const key_type& get_key(const value_type& val) const
+            {
+                return key_extractor_(val);
+            }
+
+            bool keys_equal(const key_type& key, const value_type& val)
+            {
+                return key_eq_(key, key_extractor_(val));
+            }
+
+            bool keys_equal(const key_type& key, const value_type& val) const
+            {
+                return key_eq_(key, key_extractor_(val));
+            }
+
+            hash_table_bucket<value_type, size_type>* table()
+            {
+                return table_;
+            }
+
+            hash_table_bucket<value_type, size_type>* head(size_type idx)
+            {
+                if (idx < bucket_count_)
+                    return table_[idx]->head;
+                else
+                    return nullptr;
+            }
+
+            void rehash_if_needed()
+            {
+                if (size_ > max_load_factor_ * bucket_count_)
+                    rehash(bucket_count_ * bucket_count_growth_factor_);
+            }
+
+            void increment_size()
+            {
+                ++size_;
+
+                rehash_if_needed();
+            }
+
+            void decrement_size()
+            {
+                --size_;
+            }
+
+        private:
+            hash_table_bucket<value_type, size_type>* table_;
+            size_type bucket_count_;
+            size_type size_;
+            hasher hasher_;
+            key_equal key_eq_;
+            key_extract key_extractor_;
+            float max_load_factor_;
+
+            static constexpr float bucket_count_growth_factor_{1.25};
+
+            size_type get_bucket_idx_(const key_type& key) const
+            {
+                return hasher_(key) % bucket_count_;
+            }
+
+            size_type first_filled_bucket_() const
+            {
+                size_type res{};
+                while (res < bucket_count_)
+                {
+                    if (table_[res].head)
+                        return res;
+                    ++res;
+                }
+
+                /**
+                 * Note: This is used for iterators,
+                 *       so we need to return a valid index.
+                 *       But since table_[0].head is nullptr
+                 *       we know that if we return 0 the
+                 *       created iterator will test as equal
+                 *       to end().
+                 */
+                return 0;
+            }
+
+            friend Policy;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/hash_table_bucket.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/hash_table_bucket.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/hash_table_bucket.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_HASH_TABLE_BUCKET
+#define LIBCPP_BITS_ADT_HASH_TABLE_BUCKET
+
+#include <__bits/adt/list_node.hpp>
+
+namespace std::aux
+{
+    template<class Value, class Size>
+    struct hash_table_bucket
+    {
+        /**
+         * Note: We use a doubly linked list because
+         *       we need to use hints, which point to the
+         *       element after the hinted spot.
+         */
+
+        list_node<Value>* head;
+
+        hash_table_bucket()
+            : head{}
+        { /* DUMMY BODY */ }
+
+        Size size() const noexcept
+        {
+            auto current = head;
+            Size res{};
+
+            do
+            {
+                ++res;
+                current = current->next;
+            }
+            while (current != head);
+
+            return res;
+        }
+
+        void append(list_node<Value>* node)
+        {
+            if (!head)
+                head = node;
+            else
+                head->append(node);
+        }
+
+        void prepend(list_node<Value>* node)
+        {
+            if (!head)
+                head = node;
+            else
+                head->prepend(node);
+        }
+
+        void clear()
+        {
+            if (!head)
+                return;
+
+            auto current = head;
+            do
+            {
+                auto tmp = current;
+                current = current->next;
+                delete tmp;
+            }
+            while (current != head);
+
+            head = nullptr;
+        }
+
+        ~hash_table_bucket()
+        {
+            clear();
+        }
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/hash_table_iterators.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/hash_table_iterators.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/hash_table_iterators.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_HASH_TABLE_ITERATORS
+#define LIBCPP_BITS_ADT_HASH_TABLE_ITERATORS
+
+#include <__bits/adt/list_node.hpp>
+#include <__bits/adt/hash_table_bucket.hpp>
+#include <__bits/iterator_helpers.hpp>
+#include <iterator>
+
+namespace std::aux
+{
+    template<class Value, class Reference, class Pointer, class Size>
+    class hash_table_iterator
+    {
+        public:
+            using value_type      = Value;
+            using size_type       = Size;
+            using reference       = Reference;
+            using pointer         = Pointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = forward_iterator_tag;
+
+            hash_table_iterator(hash_table_bucket<value_type, size_type>* table = nullptr,
+                                size_type idx = size_type{}, size_type max_idx = size_type{},
+                                list_node<value_type>* current = nullptr)
+                : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
+            { /* DUMMY BODY */ }
+
+            hash_table_iterator(const hash_table_iterator&) = default;
+            hash_table_iterator& operator=(const hash_table_iterator&) = default;
+
+            reference operator*()
+            {
+                return current_->value;
+            }
+
+            pointer operator->()
+            {
+                return &current_->value;
+            }
+
+            hash_table_iterator& operator++()
+            {
+                current_ = current_->next;
+                if (current_ == table_[idx_].head)
+                {
+                    if (idx_ < max_idx_)
+                    {
+                        while (!table_[++idx_].head && idx_ < max_idx_)
+                        { /* DUMMY BODY */ }
+
+                        if (idx_ < max_idx_)
+                            current_ = table_[idx_].head;
+                        else
+                            current_ = nullptr;
+                    }
+                    else
+                        current_ = nullptr;
+                }
+
+                return *this;
+            }
+
+            hash_table_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+            list_node<value_type>* node()
+            {
+                return current_;
+            }
+
+            const list_node<value_type>* node() const
+            {
+                return current_;
+            }
+
+            size_type idx() const
+            {
+                return idx_;
+            }
+
+        private:
+            hash_table_bucket<value_type, size_type>* table_;
+            size_type idx_;
+            size_type max_idx_;
+            list_node<value_type>* current_;
+
+            template<class V, class CR, class CP, class S>
+            friend class hash_table_const_iterator;
+    };
+
+    template<class Value, class Ref, class Ptr, class Size>
+    bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
+                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class Ref, class Ptr, class Size>
+    bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
+                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class ConstReference, class ConstPointer, class Size>
+    class hash_table_const_iterator
+    {
+        using non_const_iterator_type = hash_table_iterator<
+            Value, get_non_const_ref_t<ConstReference>,
+            get_non_const_ptr_t<ConstPointer>, Size
+        >;
+
+        public:
+            using value_type      = Value;
+            using size_type       = Size;
+            using const_reference = ConstReference;
+            using const_pointer   = ConstPointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = forward_iterator_tag;
+
+            hash_table_const_iterator(const hash_table_bucket<value_type, size_type>* table = nullptr,
+                                      size_type idx = size_type{}, size_type max_idx = size_type{},
+                                      const list_node<value_type>* current = nullptr)
+                : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
+            { /* DUMMY BODY */ }
+
+            hash_table_const_iterator(const hash_table_const_iterator&) = default;
+            hash_table_const_iterator& operator=(const hash_table_const_iterator&) = default;
+
+            hash_table_const_iterator(const non_const_iterator_type& other)
+                : table_{other.table_}, idx_{other.idx_}, max_idx_{other.max_idx_},
+                  current_{other.current_}
+            { /* DUMMY BODY */ }
+
+            hash_table_const_iterator& operator=(const non_const_iterator_type& other)
+            {
+                table_ = other.table_;
+                idx_ = other.idx_;
+                max_idx_ = other.max_idx_;
+                current_ = other.current_;
+
+                return *this;
+            }
+
+            const_reference operator*() const
+            {
+                return current_->value;
+            }
+
+            const_pointer operator->() const
+            {
+                return &current_->value;
+            }
+
+            hash_table_const_iterator& operator++()
+            {
+                current_ = current_->next;
+                if (current_ == table_[idx_].head)
+                {
+                    if (idx_ < max_idx_)
+                    {
+                        while (!table_[++idx_].head && idx_ < max_idx_)
+                        { /* DUMMY BODY */ }
+
+                        if (idx_ < max_idx_)
+                            current_ = table_[idx_].head;
+                        else
+                            current_ = nullptr;
+                    }
+                    else
+                        current_ = nullptr;
+                }
+
+                return *this;
+            }
+
+            hash_table_const_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+            list_node<value_type>* node()
+            {
+                return const_cast<list_node<value_type>*>(current_);
+            }
+
+            const list_node<value_type>* node() const
+            {
+                return current_;
+            }
+
+            size_type idx() const
+            {
+                return idx_;
+            }
+
+        private:
+            const hash_table_bucket<value_type, size_type>* table_;
+            size_type idx_;
+            size_type max_idx_;
+            const list_node<value_type>* current_;
+    };
+
+    template<class Value, class CRef, class CPtr, class Size>
+    bool operator==(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
+                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class CRef, class CPtr, class Size>
+    bool operator!=(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
+                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class Ref, class Ptr, class CRef, class CPtr, class Size>
+    bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
+                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class Ref, class Ptr, class CRef, class CPtr, class Size>
+    bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
+                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class CRef, class CPtr, class Ref, class Ptr, class Size>
+    bool operator==(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
+                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class CRef, class CPtr, class Ref, class Ptr, class Size>
+    bool operator!=(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
+                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class Reference, class Pointer>
+    class hash_table_local_iterator
+    {
+        public:
+            using value_type      = Value;
+            using reference       = Reference;
+            using pointer         = Pointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = forward_iterator_tag;
+
+            hash_table_local_iterator(list_node<value_type>* head = nullptr,
+                                      list_node<value_type>* current = nullptr)
+                : head_{head}, current_{current}
+            { /* DUMMY BODY */ }
+
+            hash_table_local_iterator(const hash_table_local_iterator&) = default;
+            hash_table_local_iterator& operator=(const hash_table_local_iterator&) = default;
+
+            reference operator*()
+            {
+                return current_->value;
+            }
+
+            pointer operator->()
+            {
+                return &current_->value;
+            }
+
+            hash_table_local_iterator& operator++()
+            {
+                current_ = current_->next;
+                if (current_ == head_)
+                    current_ = nullptr;
+
+                return *this;
+            }
+
+            hash_table_local_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+            list_node<value_type>* node()
+            {
+                return current_;
+            }
+
+            const list_node<value_type>* node() const
+            {
+                return current_;
+            }
+
+        private:
+            list_node<value_type>* head_;
+            list_node<value_type>* current_;
+
+            template<class V, class CR, class CP>
+            friend class hash_table_const_local_iterator;
+    };
+
+    template<class Value, class Ref, class Ptr>
+    bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
+                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class Ref, class Ptr>
+    bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
+                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class ConstReference, class ConstPointer>
+    class hash_table_const_local_iterator
+    {
+        using non_const_iterator_type = hash_table_local_iterator<
+            Value, get_non_const_ref_t<ConstReference>,
+            get_non_const_ptr_t<ConstPointer>
+        >;
+
+        public:
+            using value_type      = Value;
+            using const_reference = ConstReference;
+            using const_pointer   = ConstPointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = forward_iterator_tag;
+
+            // TODO: requirement for forward iterator is default constructibility, fix others!
+            hash_table_const_local_iterator(const list_node<value_type>* head = nullptr,
+                                            const list_node<value_type>* current = nullptr)
+                : head_{head}, current_{current}
+            { /* DUMMY BODY */ }
+
+            hash_table_const_local_iterator(const hash_table_const_local_iterator&) = default;
+            hash_table_const_local_iterator& operator=(const hash_table_const_local_iterator&) = default;
+
+            hash_table_const_local_iterator(const non_const_iterator_type& other)
+                : head_{other.head_}, current_{other.current_}
+            { /* DUMMY BODY */ }
+
+            hash_table_const_local_iterator& operator=(const non_const_iterator_type& other)
+            {
+                head_ = other.head_;
+                current_ = other.current_;
+
+                return *this;
+            }
+
+            const_reference operator*() const
+            {
+                return current_->value;
+            }
+
+            const_pointer operator->() const
+            {
+                return &current_->value;
+            }
+
+            hash_table_const_local_iterator& operator++()
+            {
+                current_ = current_->next;
+                if (current_ == head_)
+                    current_ = nullptr;
+
+                return *this;
+            }
+
+            hash_table_const_local_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+
+            list_node<value_type>* node()
+            {
+                return const_cast<list_node<value_type>*>(current_);
+            }
+
+            const list_node<value_type>* node() const
+            {
+                return current_;
+            }
+
+        private:
+            const list_node<value_type>* head_;
+            const list_node<value_type>* current_;
+    };
+
+    template<class Value, class CRef, class CPtr>
+    bool operator==(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
+                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class CRef, class CPtr>
+    bool operator!=(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
+                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class Ref, class Ptr, class CRef, class CPtr>
+    bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
+                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class Ref, class Ptr, class CRef, class CPtr>
+    bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
+                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class CRef, class CPtr, class Ref, class Ptr>
+    bool operator==(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
+                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
+    {
+        return lhs.node() == rhs.node();
+    }
+
+    template<class Value, class CRef, class CPtr, class Ref, class Ptr>
+    bool operator!=(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
+                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/hash_table_policies.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/hash_table_policies.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/hash_table_policies.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_HASH_TABLE_POLICIES
+#define LIBCPP_BITS_ADT_HASH_TABLE_POLICIES
+
+#include <tuple>
+#include <utility>
+
+namespace std::aux
+{
+    struct hash_single_policy
+    {
+        template<class Table, class Key>
+        static typename Table::size_type count(const Table& table, const Key& key)
+        {
+            return table.find(key) == table.end() ? 0 : 1;
+        }
+
+        template<class Table, class Key>
+        static typename Table::place_type find_insertion_spot(const Table& table, const Key& key)
+        {
+            auto idx = table.get_bucket_idx_(key);
+            return make_tuple(
+                &table.table_[idx],
+                table.table_[idx].head,
+                idx
+            );
+        }
+
+        template<class Table, class Key>
+        static typename Table::size_type erase(Table& table, const Key& key)
+        {
+            auto idx = table.get_bucket_idx_(key);
+            auto head = table.table_[idx].head;
+            auto current = head;
+
+            if (!current)
+                return 0;
+
+            do
+            {
+                if (table.keys_equal(key, current->value))
+                {
+                    --table.size_;
+
+                    if (current == head)
+                    {
+                        if (current->next != head)
+                            table.table_[idx].head = current->next;
+                        else
+                            table.table_[idx].head = nullptr;
+                    }
+
+                    current->unlink();
+                    delete current;
+
+                    return 1;
+                }
+                else
+                    current = current->next;
+            }
+            while (current != head);
+
+            return 0;
+        }
+
+        template<class Table, class Key>
+        static pair<
+            typename Table::iterator,
+            typename Table::iterator
+        > equal_range(Table& table, const Key& key)
+        {
+            auto it = table.find(key);
+            return make_pair(it, ++it);
+        }
+
+        template<class Table, class Key>
+        static pair<
+            typename Table::const_iterator,
+            typename Table::const_iterator
+        > equal_range_const(const Table& table, const Key& key)
+        { // Note: We cannot overload by return type, so we use a different name.
+            auto it = table.find(key);
+            return make_pair(it, ++it);
+        }
+
+        /**
+         * Note: We have to duplicate code for emplace, insert(const&)
+         *       and insert(&&) here, because the node (which makes distinction
+         *       between the arguments) is only created if the value isn't
+         *       in the table already.
+         */
+
+        template<class Table, class... Args>
+        static pair<
+            typename Table::iterator, bool
+        > emplace(Table& table, Args&&... args)
+        {
+            using value_type = typename Table::value_type;
+            using node_type  = typename Table::node_type;
+            using iterator   = typename Table::iterator;
+
+            table.increment_size();
+
+            auto val = value_type{forward<Args>(args)...};
+            const auto& key = table.get_key(val);
+            auto [bucket, target, idx] = table.find_insertion_spot(key);
+
+            if (!bucket)
+                return make_pair(table.end(), false);
+
+            if (target && table.keys_equal(key, target->value))
+            {
+                table.decrement_size();
+
+                return make_pair(
+                    iterator{
+                        table.table(), idx, table.bucket_count(),
+                        target
+                    },
+                    false
+                );
+            }
+            else
+            {
+                auto node = new node_type{move(val)};
+                bucket->prepend(node);
+
+                return make_pair(iterator{
+                    table.table(), idx,
+                    table.bucket_count(),
+                    node
+                }, true);
+            }
+        }
+
+        template<class Table, class Value>
+        static pair<
+            typename Table::iterator, bool
+        > insert(Table& table, const Value& val)
+        {
+            using node_type  = typename Table::node_type;
+            using iterator   = typename Table::iterator;
+
+            table.increment_size();
+
+            const auto& key = table.get_key(val);
+            auto [bucket, target, idx] = table.find_insertion_spot(key);
+
+            if (!bucket)
+                return make_pair(table.end(), false);
+
+            if (target && table.keys_equal(key, target->value))
+            {
+                table.decrement_size();
+
+                return make_pair(
+                    iterator{
+                        table.table(), idx, table.bucket_count(),
+                        target
+                    },
+                    false
+                );
+            }
+            else
+            {
+                auto node = new node_type{val};
+                bucket->prepend(node);
+
+                return make_pair(iterator{
+                    table.table(), idx,
+                    table.bucket_count(),
+                    node
+                }, true);
+            }
+        }
+
+        template<class Table, class Value>
+        static pair<
+            typename Table::iterator, bool
+        > insert(Table& table, Value&& val)
+        {
+            using value_type = typename Table::value_type;
+            using node_type  = typename Table::node_type;
+            using iterator   = typename Table::iterator;
+
+            table.increment_size();
+
+            const auto& key = table.get_key(val);
+            auto [bucket, target, idx] = table.find_insertion_spot(key);
+
+            if (!bucket)
+                return make_pair(table.end(), false);
+
+            if (target && table.keys_equal(key, target->value))
+            {
+                table.decrement_size();
+
+                return make_pair(
+                    iterator{
+                        table.table(), idx, table.bucket_count(),
+                        target
+                    },
+                    false
+                );
+            }
+            else
+            {
+                auto node = new node_type{forward<value_type>(val)};
+                bucket->prepend(node);
+
+                return make_pair(iterator{
+                    table.table(), idx,
+                    table.bucket_count(),
+                    node
+                }, true);
+            }
+        }
+    };
+
+    struct hash_multi_policy
+    {
+        template<class Table, class Key>
+        static typename Table::size_type count(const Table& table, const Key& key)
+        {
+            auto head = table.table_[table.get_bucket_idx_(key)].head;
+            if (!head)
+                return 0;
+
+            auto current = head;
+            typename Table::size_type res = 0;
+            do
+            {
+                if (table.keys_equal(key, current->value))
+                    ++res;
+
+                current = current->next;
+            }
+            while (current != head);
+
+            return res;
+        }
+
+        template<class Table, class Key>
+        static typename Table::place_type find_insertion_spot(const Table& table, const Key& key)
+        {
+            auto idx = table.get_bucket_idx_(key);
+            auto head = table.table_[idx].head;
+
+            if (head)
+            {
+                auto current = head;
+                do
+                {
+                    if (table.keys_equal(key, current->value))
+                    {
+                        return make_tuple(
+                            &table.table_[idx],
+                            current,
+                            idx
+                        );
+                    }
+
+                    current = current->next;
+                } while (current != head);
+            }
+
+            return make_tuple(
+                &table.table_[idx],
+                table.table_[idx].head,
+                idx
+            );
+        }
+
+        template<class Table, class Key>
+        static typename Table::size_type erase(Table& table, const Key& key)
+        {
+            auto idx = table.get_bucket_idx_(key);
+            auto head = table.table_[idx].head;
+            auto current = head;
+            table.table_[idx].head = nullptr;
+
+            if (!current)
+                return 0;
+
+            /**
+             * We traverse the list and delete if the keys
+             * equal, if they don't we append the nodes back
+             * to the bucket.
+             */
+            typename Table::size_type res{};
+
+            do
+            {
+                auto tmp = current;
+                current = current->next;
+
+                if (!table.keys_equal(key, tmp->value))
+                    table.table_[idx].append(tmp);
+                else
+                {
+                    ++res;
+                    --table.size_;
+
+                    delete tmp;
+                }
+            }
+            while (current != head);
+
+            return res;
+        }
+
+        template<class Table, class Key>
+        static pair<
+            typename Table::iterator,
+            typename Table::iterator
+        > equal_range(Table& table, const Key& key)
+        {
+            auto first = table.find(key);
+            if (first == table.end())
+                return make_pair(table.end(), table.end());
+
+            auto last = first;
+            do
+            {
+                ++last;
+            } while (table.keys_equal(key, *last));
+
+            return make_pair(first, last);
+        }
+
+        template<class Table, class Key>
+        static pair<
+            typename Table::const_iterator,
+            typename Table::const_iterator
+        > equal_range_const(const Table& table, const Key& key)
+        {
+            auto first = table.find(key);
+            if (first == table.end())
+                return make_pair(table.end(), table.end());
+
+            auto last = first;
+            do
+            {
+                ++last;
+            } while (table.keys_equal(key, *last));
+
+            return make_pair(first, last);
+        }
+
+        template<class Table, class... Args>
+        static typename Table::iterator emplace(Table& table, Args&&... args)
+        {
+            using node_type  = typename Table::node_type;
+
+            auto node = new node_type{forward<Args>(args)...};
+
+            return insert(table, node);
+        }
+
+        template<class Table, class Value>
+        static typename Table::iterator insert(Table& table, const Value& val)
+        {
+            using node_type  = typename Table::node_type;
+
+            auto node = new node_type{val};
+
+            return insert(table, node);
+        }
+
+        template<class Table, class Value>
+        static typename Table::iterator insert(Table& table, Value&& val)
+        {
+            using value_type = typename Table::value_type;
+            using node_type  = typename Table::node_type;
+
+            auto node = new node_type{forward<value_type>(val)};
+
+            return insert(table, node);
+        }
+
+        template<class Table>
+        static typename Table::iterator insert(Table& table, typename Table::node_type* node)
+        {
+            using iterator   = typename Table::iterator;
+
+            table.increment_size();
+
+            const auto& key = table.get_key(node->value);
+            auto [bucket, target, idx] = table.find_insertion_spot(key);
+
+            if (!bucket)
+                table.end();
+
+            if (target && table.keys_equal(key, target->value))
+                target->append(node);
+            else
+                bucket->prepend(node);
+
+            return iterator{
+                table.table(), idx,
+                table.bucket_count(),
+                node
+            };
+        }
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/initializer_list.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/initializer_list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/initializer_list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_INITIALIZER_LIST
+#define LIBCPP_BITS_ADT_INITIALIZER_LIST
+
+#include <cstdlib>
+
+namespace std
+{
+    /**
+     * 18.9, initializer lists:
+     */
+
+    template<class T>
+    class initializer_list
+    {
+        public:
+            using value_type      = T;
+            using const_reference = const T&;
+            using reference       = const_reference;
+            using size_type       = size_t;
+            using const_iterator  = const T*;
+            using iterator        = const_iterator;
+
+            constexpr initializer_list() noexcept
+                : begin_{nullptr}, size_{0}
+            { /* DUMMY BODY */ }
+
+            constexpr size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            constexpr iterator begin() const noexcept
+            {
+                return begin_;
+            }
+
+            constexpr iterator end() const noexcept
+            {
+                return begin_ + size_;
+            }
+
+        private:
+            iterator begin_;
+            size_type size_;
+
+            constexpr initializer_list(iterator begin, size_type size)
+                : begin_{begin}, size_{size}
+            { /* DUMMY BODY */ }
+    };
+
+    /**
+     * 18.9.3, initializer list range access:
+     */
+
+    template<class T>
+    constexpr auto begin(initializer_list<T> init)
+    {
+        return init.begin();
+    }
+
+    template<class T>
+    constexpr auto end(initializer_list<T> init)
+    {
+        return init.end();
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/key_extractors.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/key_extractors.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/key_extractors.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_KEY_EXTRACTORS
+#define LIBCPP_BITS_ADT_KEY_EXTRACTORS
+
+#include <utility>
+
+namespace std::aux
+{
+    template<class Key, class Value>
+    struct key_value_key_extractor
+    {
+        const Key& operator()(const pair<const Key, Value>& p) const noexcept
+        {
+            return p.first;
+        }
+    };
+
+    template<class Key>
+    struct key_no_value_key_extractor
+    {
+        Key& operator()(Key& k) const noexcept
+        {
+            return k;
+        }
+
+        const Key& operator()(const Key& k) const noexcept
+        {
+            return k;
+        }
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/list.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/list.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1195 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_LIST
+#define LIBCPP_BITS_ADT_LIST
+
+#include <__bits/adt/list_node.hpp>
+#include <__bits/insert_iterator.hpp>
+#include <cstdlib>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+namespace std
+{
+    template<class T, class Allocator = allocator<T>>
+    class list;
+
+    namespace aux
+    {
+        template<class T>
+        class list_iterator;
+
+        template<class T>
+        class list_const_iterator
+        {
+            public:
+                using value_type      = typename list<T>::value_type;
+                using reference       = typename list<T>::const_reference;
+                using pointer         = typename list<T>::const_pointer;
+                using difference_type = typename list<T>::difference_type;
+                using size_type       = typename list<T>::size_type;
+
+                using iterator_category = bidirectional_iterator_tag;
+
+                list_const_iterator(list_node<value_type>* node = nullptr,
+                                    list_node<value_type>* head = nullptr,
+                                    bool end = true)
+                    : current_{node}, head_{head}, end_{end}
+                { /* DUMMY BODY */ }
+
+                list_const_iterator(const list_const_iterator&) = default;
+                list_const_iterator& operator=(const list_const_iterator&) = default;
+                list_const_iterator(list_const_iterator&&) = default;
+                list_const_iterator& operator=(list_const_iterator&&) = default;
+
+                list_const_iterator(const list_iterator<T>& other)
+                    : current_{other.node()}, head_{other.head()}, end_{other.end()}
+                { /* DUMMY BODY */ }
+
+                reference operator*() const
+                {
+                    return current_->value;
+                }
+
+                list_const_iterator& operator++()
+                {
+                    if (!end_ && current_)
+                    {
+                        if (current_->next == head_)
+                            end_ = true;
+                        else
+                            current_ = current_->next;
+                    }
+
+                    return *this;
+                }
+
+                list_const_iterator operator++(int)
+                {
+                    auto old = *this;
+                    ++(*this);
+
+                    return old;
+                }
+
+                list_const_iterator& operator--()
+                {
+                    if (end_)
+                        end_ = false;
+                    else if (current_)
+                    {
+                        if (current_ != head_)
+                            current_ = current_->prev;
+                        else
+                            end_ = true;
+                    }
+
+                    return *this;
+                }
+
+                list_const_iterator operator--(int)
+                {
+                    auto old = *this;
+                    --(*this);
+
+                    return old;
+                }
+
+                list_node<value_type>* node()
+                {
+                    return const_cast<list_node<value_type>*>(current_);
+                }
+
+                const list_node<value_type>* node() const
+                {
+                    return current_;
+                }
+
+                list_node<value_type>* head()
+                {
+                    return const_cast<list_node<value_type>*>(head_);
+                }
+
+                const list_node<value_type>* head() const
+                {
+                    return head_;
+                }
+
+                list_const_iterator operator-(difference_type n) const
+                {
+                    /**
+                     * Note: This operator is for internal purposes only,
+                     *       so we do not provide inverse operator or shortcut
+                     *       -= operator.
+                     */
+                    auto tmp = current_;
+
+                    for (difference_type i = 0; i < n; ++i)
+                        tmp = tmp->prev;
+
+                    return list_const_iterator{tmp};
+                }
+
+                bool end() const
+                {
+                    return end_;
+                }
+
+            private:
+                const list_node<value_type>* current_;
+                const list_node<value_type>* head_;
+                bool end_;
+        };
+
+        template<class T>
+        bool operator==(const list_const_iterator<T>& lhs, const list_const_iterator<T>& rhs)
+        {
+            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+        }
+
+        template<class T>
+        bool operator!=(const list_const_iterator<T>& lhs, const list_const_iterator<T>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template<class T>
+        class list_iterator
+        {
+            public:
+                using value_type      = typename list<T>::value_type;
+                using reference       = typename list<T>::reference;
+                using pointer         = typename list<T>::pointer;
+                using difference_type = typename list<T>::difference_type;
+                using size_type       = typename list<T>::size_type;
+
+                using iterator_category = bidirectional_iterator_tag;
+
+                list_iterator(list_node<value_type>* node = nullptr,
+                              list_node<value_type>* head = nullptr,
+                              bool end = true)
+                    : current_{node}, head_{head}, end_{end}
+                { /* DUMMY BODY */ }
+
+                list_iterator(const list_iterator&) = default;
+                list_iterator& operator=(const list_iterator&) = default;
+                list_iterator(list_iterator&&) = default;
+                list_iterator& operator=(list_iterator&&) = default;
+
+                reference operator*() const
+                {
+                    return current_->value;
+                }
+
+                list_iterator& operator++()
+                {
+                    if (!end_ && current_)
+                    {
+                        if (current_->next == head_)
+                            end_ = true;
+                        else
+                            current_ = current_->next;
+                    }
+
+                    return *this;
+                }
+
+                list_iterator operator++(int)
+                {
+                    auto old = *this;
+                    ++(*this);
+
+                    return old;
+                }
+
+                list_iterator& operator--()
+                {
+                    if (end_)
+                        end_ = false;
+                    else if (current_)
+                    {
+                        if (current_ != head_)
+                            current_ = current_->prev;
+                        else
+                            end_ = true;
+                    }
+
+                    return *this;
+                }
+
+                list_iterator operator--(int)
+                {
+                    auto old = *this;
+                    --(*this);
+
+                    return old;
+                }
+
+                list_node<value_type>* node()
+                {
+                    return current_;
+                }
+
+                const list_node<value_type>* node() const
+                {
+                    return current_;
+                }
+
+                list_node<value_type>* head()
+                {
+                    return head_;
+                }
+
+                const list_node<value_type>* head() const
+                {
+                    return head_;
+                }
+
+                list_iterator operator-(difference_type n) const
+                {
+                    /**
+                     * Note: This operator is for internal purposes only,
+                     *       so we do not provide inverse operator or shortcut
+                     *       -= operator.
+                     */
+                    auto tmp = current_;
+
+                    for (difference_type i = 0; i < n; ++i)
+                        tmp = tmp->prev;
+
+                    return list_iterator{tmp};
+                }
+
+                bool end() const
+                {
+                    return end_;
+                }
+
+            private:
+                list_node<value_type>* current_;
+                list_node<value_type>* head_;
+                bool end_;
+        };
+
+        template<class T>
+        bool operator==(const list_iterator<T>& lhs, const list_iterator<T>& rhs)
+        {
+            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+        }
+
+        template<class T>
+        bool operator!=(const list_iterator<T>& lhs, const list_iterator<T>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template<class T>
+        bool operator==(const list_const_iterator<T>& lhs, const list_iterator<T>& rhs)
+        {
+            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+        }
+
+        template<class T>
+        bool operator!=(const list_const_iterator<T>& lhs, const list_iterator<T>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template<class T>
+        bool operator==(const list_iterator<T>& lhs, const list_const_iterator<T>& rhs)
+        {
+            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+        }
+
+        template<class T>
+        bool operator!=(const list_iterator<T>& lhs, const list_const_iterator<T>& rhs)
+        {
+            return !(lhs == rhs);
+        }
+    }
+
+    /**
+     * 23.3.5, class template list:
+     */
+
+    template<class T, class Allocator>
+    class list
+    {
+        public:
+            using value_type      = T;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using allocator_type  = Allocator;
+
+            using iterator        = aux::list_iterator<value_type>;
+            using const_iterator  = aux::list_const_iterator<value_type>;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using pointer       = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer = typename allocator_traits<allocator_type>::const_pointer;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            /**
+             * 23.3.5.2, construct/copy/destroy:
+             */
+
+            list()
+                : list{allocator_type{}}
+            { /* DUMMY BODY */ }
+
+            explicit list(const allocator_type& alloc)
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            { /* DUMMY BODY */ }
+
+            explicit list(size_type n, const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            {
+                init_(
+                    aux::insert_iterator<value_type>{size_type{}, value_type{}},
+                    aux::insert_iterator<value_type>{size_, value_type{}}
+                );
+            }
+
+            list(size_type n, const value_type& val,
+                 const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            {
+                init_(
+                    aux::insert_iterator<value_type>{size_type{}, val},
+                    aux::insert_iterator<value_type>{n, value_type{}}
+                );
+            }
+
+            template<class InputIterator>
+            list(InputIterator first, InputIterator last,
+                 const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            {
+                init_(first, last);
+            }
+
+            list(const list& other)
+                : list{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            list(list&& other)
+                : allocator_{move(other.allocator_)},
+                  head_{move(other.head_)},
+                  size_{move(other.size_)}
+            {
+                other.head_ = nullptr;
+                other.size_ = size_type{};
+            }
+
+            list(const list& other, const allocator_type alloc)
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            { // Size is set in init_.
+                init_(other.begin(), other.end());
+            }
+
+            list(list&& other, const allocator_type& alloc)
+                : allocator_{alloc},
+                  head_{move(other.head_)},
+                  size_{move(other.size_)}
+            {
+                other.head_ = nullptr;
+                other.size_ = size_type{};
+            }
+
+            list(initializer_list<value_type> init, const allocator_type& alloc = allocator_type{})
+                : allocator_{alloc}, head_{nullptr}, size_{}
+            {
+                init_(init.begin(), init.end());
+            }
+
+            ~list()
+            {
+                fini_();
+            }
+
+            list& operator=(const list& other)
+            {
+                fini_();
+
+                allocator_ = other.allocator_;
+
+                init_(other.begin(), other.end());
+
+                return *this;
+            }
+
+            list& operator=(list&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                fini_();
+
+                head_ = move(other.head_);
+                size_ = move(other.size_);
+                allocator_ = move(other.allocator_);
+
+                other.head_ = nullptr;
+                other.size_ = size_type{};
+
+                return *this;
+            }
+
+            list& operator=(initializer_list<value_type> init)
+            {
+                fini_();
+
+                init_(init.begin(), init.end());
+
+                return *this;
+            }
+
+            template<class InputIterator>
+            void assign(InputIterator first, InputIterator last)
+            {
+                fini_();
+
+                init_(first, last);
+            }
+
+            void assign(size_type n, const value_type& val)
+            {
+                fini_();
+
+                init_(
+                    aux::insert_iterator<value_type>{size_type{}, val},
+                    aux::insert_iterator<value_type>{n, value_type{}}
+                );
+            }
+
+            void assign(initializer_list<value_type> init)
+            {
+                fini_();
+
+                init_(init.begin(), init.end());
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return iterator{head_, head_, size_ == 0U};
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return iterator{get_last_(), head_, true};
+            }
+
+            const_iterator end() const noexcept
+            {
+                return cend();
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return make_reverse_iterator(end());
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return make_reverse_iterator(begin());
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return const_iterator{head_, head_, size_ == 0U};
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return const_iterator{get_last_(), head_, true};
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return rbegin();
+            }
+
+            /**
+             * 23.3.5.3, capacity:
+             */
+
+            bool empty() const noexcept
+            {
+                return size_ == 0;
+            }
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type max_size() const noexcept
+            {
+                return allocator_traits<allocator_type>::max_size(allocator_);
+            }
+
+            void resize(size_type sz)
+            {
+                // TODO: implement
+            }
+
+            void resize(size_type sz, const value_type& val)
+            {
+                // TODO: implement
+            }
+
+            reference front()
+            {
+                // TODO: bounds checking
+                return head_->value;
+            }
+
+            const_reference front() const
+            {
+                // TODO: bounds checking
+                return head_->value;
+            }
+
+            reference back()
+            {
+                // TODO: bounds checking
+                return head_->prev->value;
+            }
+
+            const_reference back() const
+            {
+                // TODO: bounds checking
+                return head_->prev->value;
+            }
+
+            /**
+             * 23.3.5.4, modifiers:
+             * Note: These should have no effect when an exception
+             *       is thrown while inserting, but since the only
+             *       functions that can throw are the constructors,
+             *       creating the node before any modifications to the
+             *       list itself will satisfy this requirement.
+             */
+
+            template<class... Args>
+            void emplace_front(Args&&... args)
+            {
+                prepend_new_(forward<Args>(args)...);
+            }
+
+            void pop_front()
+            {
+                if (head_)
+                {
+                    --size_;
+
+                    if (head_->next == head_)
+                    {
+                        delete head_;
+                        head_ = nullptr;
+                    }
+                    else
+                    {
+                        auto tmp = head_;
+                        head_->prev->next = head_->next;
+                        head_->next->prev = head_->prev;
+                        head_ = head_->next;
+
+                        delete tmp;
+                    }
+                }
+            }
+
+            template<class... Args>
+            void emplace_back(Args&&... args)
+            {
+                append_new_(forward<Args>(args)...);
+            }
+
+            void push_front(const value_type& value)
+            {
+                prepend_new_(value);
+            }
+
+            void push_front(value_type&& value)
+            {
+                prepend_new_(forward<value_type>(value));
+            }
+
+            void push_back(const value_type& value)
+            {
+                append_new_(value);
+            }
+
+            void push_back(value_type&& value)
+            {
+                append_new_(forward<value_type>(value));
+            }
+
+            void pop_back()
+            {
+                if (head_)
+                {
+                    --size_;
+                    auto target = head_->prev;
+
+                    if (!target)
+                    {
+                        delete head_;
+                        head_ = nullptr;
+                    }
+                    else
+                    {
+                        auto tmp = target;
+                        target->prev->next = target->next;
+                        target->next->prev = target->prev;
+                        target = target->next;
+
+                        delete tmp;
+                    }
+                }
+            }
+
+            template<class... Args>
+            iterator emplace(const_iterator position, Args&&... args)
+            {
+                auto node = position.node();
+                node->prepend(new aux::list_node<value_type>{forward<Args>(args)...});
+                ++size_;
+
+                if (node == head_)
+                    head_ = head_->prev;
+
+                return iterator{node->prev, head_, false};
+            }
+
+            iterator insert(const_iterator position, const value_type& val)
+            {
+                return emplace(position, val);
+            }
+
+            iterator insert(const_iterator position, value_type&& val)
+            {
+                return emplace(position, forward<value_type>(val));
+            }
+
+            iterator insert(const_iterator position, size_type n, const value_type& val)
+            {
+                return insert(
+                    position,
+                    aux::insert_iterator<value_type>{size_type{}, val},
+                    aux::insert_iterator<value_type>{n, value_type{}}
+                );
+            }
+
+            template<class InputIterator>
+            iterator insert(const_iterator position, InputIterator first, InputIterator last)
+            {
+                auto node = position.node()->prev;
+
+                while (first != last)
+                {
+                    node->append(new aux::list_node<value_type>{*first++});
+                    node = node->next;
+                    ++size_;
+                }
+
+                return iterator{position.node()->next, head_, false};
+            }
+
+            iterator insert(const_iterator position, initializer_list<value_type> init)
+            {
+                return insert(position, init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                auto node = position.node();
+
+                if (node == head_)
+                {
+                    if (size_ == 1)
+                    {
+                        delete head_;
+                        head_ = nullptr;
+                        size_ = 0;
+
+                        return end();
+                    }
+                    else
+                        head_ = node->next;
+                }
+
+                auto next = node->next;
+
+                --size_;
+
+                node->unlink();
+                delete node;
+
+                return iterator{next, head_, size_ == 0U};
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                if (first == last)
+                    return end();
+
+                auto first_node = first.node();
+                auto last_node = last.node()->prev;
+                auto prev = first_node->prev;
+                auto next = last_node->next;
+
+                first_node->prev = nullptr;
+                last_node->next = nullptr;
+                prev->next = next;
+                next->prev = prev;
+
+                while (first_node)
+                {
+                    if (first_node == head_)
+                    {
+                        head_ = next;
+                        head_->prev = prev;
+                    }
+
+                    auto tmp = first_node;
+                    first_node = first_node->next;
+                    --size_;
+
+                    delete tmp;
+                }
+
+                return iterator{next, head_, size_ == 0U};
+            }
+
+            void swap(list& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                std::swap(allocator_, other.allocator_);
+                std::swap(head_, other.head_);
+                std::swap(size_, other.size_);
+            }
+
+            void clear() noexcept
+            {
+                fini_();
+            }
+
+            /**
+             * 23.3.5.5, list operations:
+             */
+
+            void splice(const_iterator position, list& other)
+            {
+                if (!head_)
+                {
+                    swap(other);
+                    return;
+                }
+
+                auto other_first = other.head_;
+                auto other_last = other.get_last_();
+                auto node = position.node();
+                auto prev = node->prev;
+
+                // Insert a link range.
+                prev->next = other_first;
+                other_first->prev = prev;
+                node->prev = other_last;
+                other_last->next = node;
+
+                size_ += other.size_;
+
+                if (node == head_)
+                    head_ = other_first;
+                other.head_ = nullptr;
+                other.size_ = 0;
+            }
+
+            void splice(const_iterator position, list&& other)
+            {
+                splice(position, other);
+            }
+
+            void splice(const_iterator position, list& other, const_iterator it)
+            {
+                if (&other == this)
+                    return;
+
+                auto node = position.node();
+                auto target = it.node();
+
+                // Unlink from other.
+                target->prev->next = target->next;
+                target->next->prev = target->prev;
+
+                // Link to us.
+                node->prev->next = target;
+                target->prev = node->prev;
+
+                node->prev = target;
+                target->next = node;
+
+                --other.size_;
+                ++size_;
+
+                if (it.node() == other.head_)
+                    other.advance_head_();
+            }
+
+            void splice(const_iterator position, list&& other, const_iterator it)
+            {
+                splice(position, other, it);
+            }
+
+            void splice(const_iterator position, list& other,
+                        const_iterator first, const_iterator last)
+            {
+                if (&other == this || other.empty())
+                    return;
+
+                if (first == other.begin() && last == other.end())
+                { // [first, last) is everything in other.
+                    splice(position, other);
+                    return;
+                }
+
+                // [first_node, last_node] is the inserted range.
+                aux::list_node<value_type>* first_node{};
+                aux::list_node<value_type>* last_node{};
+
+                if (first == other.begin())
+                { // The range is a prefix of other.
+                    other.head_ = last.node();
+                    other.head_->prev = first.node()->prev;
+                    first.node()->prev->next = last.node();
+
+                    first_node = first.node();
+                    last_node = last.node()->prev;
+                }
+                else if (last == other.end())
+                { // The range is a suffix of other.
+                    auto new_last = first.node()->prev;
+                    auto old_last = other.head_->prev;
+                    other.head_->prev = new_last;
+                    new_last->next = other.head_;
+
+                    first_node = first.node();
+                    last_node = old_last;
+                }
+                else
+                { // The range is a subrange of other.
+                    first_node = first.node();
+                    last_node = last.node()->prev;
+
+                    first_node->prev->next = last.node();
+                    last.node()->prev = first_node->prev;
+                }
+
+                if (!head_)
+                { // Assimilate the range.
+                    head_ = first_node;
+                    first_node->prev = last_node;
+                    last_node->next = first_node;
+                }
+                else
+                {
+                    auto target = position.node();
+                    target->prev->next = first_node;
+                    first_node->prev = target->prev;
+
+                    target->prev = last_node;
+                    last_node->next = target;
+                }
+
+                auto count = distance(
+                    iterator{first_node, nullptr, false},
+                    iterator{last_node, nullptr, false}
+                );
+                ++count;
+
+                size_ += count;
+                other.size_ -= count;
+            }
+
+            void splice(const_iterator position, list&& other,
+                        const_iterator first, const_iterator last)
+            {
+                splice(position, other, first, last);
+            }
+
+            void remove(const value_type& val)
+            {
+                if (!head_)
+                    return;
+
+                auto it = begin();
+                while (it != end())
+                {
+                    if (*it == val)
+                        it = erase(it);
+                    else
+                        ++it;
+                }
+            }
+
+            template<class Predicate>
+            void remove_if(Predicate pred)
+            {
+                if (!head_)
+                    return;
+
+                auto it = begin();
+                while (it != end())
+                {
+                    if (pred(*it))
+                        it = erase(it);
+                    else
+                        ++it;
+                }
+            }
+
+            void unique()
+            {
+                if (!head_)
+                    return;
+
+                auto it = begin();
+                ++it;
+
+                while (it != end())
+                {
+                    if (*it == *(it - 1))
+                        it = erase(it);
+                    else
+                        ++it;
+                }
+            }
+
+            template<class BinaryPredicate>
+            void unique(BinaryPredicate pred)
+            {
+                if (!head_)
+                    return;
+
+                auto it = begin();
+                ++it;
+
+                while (it != end())
+                {
+                    if (pred(*it, *(it - 1)))
+                        it = erase(it);
+                    else
+                        ++it;
+                }
+            }
+
+            // TODO: make a generic base for algorithms like merge
+            //       and quicksort that uses a swapper (the <algorithm>
+            //       versions would use std::swap and list versions would
+            //       use a swapper that swaps list nodes)
+
+            void merge(list& other)
+            {
+                // TODO: implement
+            }
+
+            void merge(list&& other)
+            {
+                merge(other);
+            }
+
+            template<class Compare>
+            void merge(list& other, Compare comp)
+            {
+                // TODO: implement
+            }
+
+            template<class Compare>
+            void merge(list&& other, Compare comp)
+            {
+                merge(other, comp);
+            }
+
+            void reverse() noexcept
+            {
+                // TODO: implement
+            }
+
+            void sort()
+            {
+                // TODO: implement
+            }
+
+            template<class Compare>
+            void sort(Compare comp)
+            {
+                // TODO: implement
+            }
+
+        private:
+            allocator_type allocator_;
+            aux::list_node<value_type>* head_;
+            size_type size_;
+
+            template<class InputIterator>
+            void init_(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                {
+                    auto node = append_new_();
+                    allocator_.construct(&node->value, *first++);
+                }
+            }
+
+            void fini_()
+            {
+                if (!head_)
+                    return;
+
+                head_->prev->next = nullptr;
+                while (head_)
+                {
+                    auto tmp = head_;
+                    head_ = head_->next;
+
+                    delete tmp;
+                }
+
+                head_ = nullptr;
+                size_ = size_type{};
+            }
+
+            template<class... Args>
+            aux::list_node<value_type>* append_new_(Args&&... args)
+            {
+                auto node = new aux::list_node<value_type>{forward<Args>(args)...};
+                auto last = get_last_();
+
+                if (!last)
+                    head_ = node;
+                else
+                    last->append(node);
+
+                ++size_;
+
+                return node;
+            }
+
+            template<class... Args>
+            aux::list_node<value_type>* prepend_new_(Args&&... args)
+            {
+                auto node = new aux::list_node<value_type>{forward<Args>(args)...};
+
+                if (!head_)
+                    head_ = node;
+                else
+                {
+                    head_->prepend(node);
+                    head_ = head_->prev;
+                }
+
+                ++size_;
+
+                return node;
+            }
+
+            aux::list_node<value_type>* get_last_() const
+            {
+                if (!head_)
+                    return nullptr;
+
+                return head_->prev;
+            }
+
+            template<class InputIterator>
+            void insert_range_(InputIterator first, InputIterator last,
+                               aux::list_node<value_type>* where = nullptr)
+            {
+                if (first == last)
+                    return;
+
+                if (!where)
+                    where = get_last_();
+
+                while (first != last)
+                {
+                    where->append(new aux::list_node<value_type>{*first++});
+                    where = where->next;
+                }
+            }
+
+            void advance_head_()
+            {
+                if (size_ == 1)
+                {
+                    head_ = nullptr;
+                    size_ = 0;
+                }
+                else
+                { // The head_ is deleted outside.
+                    head_->next->prev = head_->prev;
+                    head_->prev->next = head_->next;
+                    head_ = head_->next;
+                }
+            }
+    };
+
+    template<class T, class Allocator>
+    void swap(list<T, Allocator>& lhs, list<T, Allocator>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/list_node.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/list_node.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/list_node.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_LIST_NODE
+#define LIBCPP_BITS_ADT_LIST_NODE
+
+namespace std::aux
+{
+    template<class T>
+    struct list_node
+    {
+        T value;
+        list_node* next;
+        list_node* prev;
+
+        template<class... Args>
+        list_node(Args&&... args)
+            : value{forward<Args>(args)...},
+              next{}, prev{}
+        {
+            next = this;
+            prev = this;
+        }
+
+        list_node(const T& val)
+            : value{val}, next{}, prev{}
+        {
+            next = this;
+            prev = this;
+        }
+
+        list_node(T&& val)
+            : value{forward<T>(val)}, next{}, prev{}
+        {
+            next = this;
+            prev = this;
+        }
+
+        void append(list_node* node)
+        {
+            node->next = next;
+            node->prev = this;
+            next->prev = node;
+            next = node;
+        }
+
+        void prepend(list_node* node)
+        {
+            node->next = this;
+            node->prev = prev;
+            prev->next = node;
+            prev = node;
+        }
+
+        void unlink()
+        {
+            prev->next = next;
+            next->prev = prev;
+            next = this;
+            prev = this;
+        }
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/map.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/map.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/map.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1224 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_MAP
+#define LIBCPP_BITS_ADT_MAP
+
+#include <__bits/adt/rbtree.hpp>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <utility>
+#include <type_traits>
+
+namespace std
+{
+    /**
+     * 23.4.4, class template map:
+     */
+
+    template<
+        class Key, class Value,
+        class Compare = less<Key>,
+        class Alloc = allocator<pair<const Key, Value>>
+    >
+    class map
+    {
+        public:
+            using key_type        = Key;
+            using mapped_type     = Value;
+            using value_type      = pair<const key_type, mapped_type>;
+            using key_compare     = Compare;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using node_type = aux::rbtree_single_node<value_type>;
+
+            using iterator             = aux::rbtree_iterator<
+                value_type, reference, pointer, size_type, node_type
+            >;
+            using const_iterator       = aux::rbtree_const_iterator<
+                value_type, const_reference, const_pointer, size_type, node_type
+            >;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            class value_compare
+            {
+                friend class map;
+
+                protected:
+                    key_compare comp;
+
+                    value_compare(key_compare c)
+                        : comp{c}
+                    { /* DUMMY BODY */ }
+
+                public:
+                    using result_type          = bool;
+                    using first_argument_type  = value_type;
+                    using second_argument_type = value_type;
+
+                    bool operator()(const value_type& lhs, const value_type& rhs) const
+                    {
+                        return comp(lhs.first, rhs.first);
+                    }
+            };
+
+            /**
+             * 24.4.4.2, construct/copy/destroy:
+             */
+
+            map()
+                : map{key_compare{}}
+            { /* DUMMY BODY */ }
+
+            explicit map(const key_compare& comp,
+                         const allocator_type& alloc = allocator_type{})
+                : tree_{comp}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            map(InputIterator first, InputIterator last,
+                const key_compare& comp = key_compare{},
+                const allocator_type& alloc = allocator_type{})
+                : map{comp, alloc}
+            {
+                insert(first, last);
+            }
+
+            map(const map& other)
+                : map{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            map(map&& other)
+                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit map(const allocator_type& alloc)
+                : tree_{}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            map(const map& other, const allocator_type& alloc)
+                : tree_{other.tree_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            map(map&& other, const allocator_type& alloc)
+                : tree_{move(other.tree_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            map(initializer_list<value_type> init,
+                const key_compare& comp = key_compare{},
+                const allocator_type& alloc = allocator_type{})
+                : map{comp, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class InputIterator>
+            map(InputIterator first, InputIterator last,
+                const allocator_type& alloc)
+                : map{first, last, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            map(initializer_list<value_type> init,
+                const allocator_type& alloc)
+                : map{init, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~map()
+            { /* DUMMY BODY */ }
+
+            map& operator=(const map& other)
+            {
+                tree_ = other.tree_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            map& operator=(map&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<key_compare>::value)
+            {
+                tree_ = move(other.tree_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            map& operator=(initializer_list<value_type>& init)
+            {
+                tree_.clear();
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return tree_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return tree_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return tree_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return tree_.end();
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return tree_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return tree_.cend();
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return tree_.crbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return tree_.crend();
+            }
+
+            bool empty() const noexcept
+            {
+                return tree_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return tree_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return tree_.max_size(allocator_);
+            }
+
+            /**
+             * 23.4.4.3, element access:
+             */
+
+            mapped_type& operator[](const key_type& key)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                    return parent->value.second;
+
+                auto node = new node_type{value_type{key, mapped_type{}}};
+                tree_.insert_node(node, parent);
+
+                return node->value.second;
+            }
+
+            mapped_type& operator[](key_type&& key)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                    return parent->value.second;
+
+                auto node = new node_type{value_type{move(key), mapped_type{}}};
+                tree_.insert_node(node, parent);
+
+                return node->value.second;
+            }
+
+            mapped_type& at(const key_type& key)
+            {
+                auto it = find(key);
+
+                // TODO: throw out_of_range if it == end()
+                return it->second;
+            }
+
+            const mapped_type& at(const key_type& key) const
+            {
+                auto it = find(key);
+
+                // TODO: throw out_of_range if it == end()
+                return it->second;
+            }
+
+            /**
+             * 23.4.4.4, modifiers:
+             */
+
+            template<class... Args>
+            pair<iterator, bool> emplace(Args&&... args)
+            {
+                return tree_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...).first;
+            }
+
+            pair<iterator, bool> insert(const value_type& val)
+            {
+                return tree_.insert(val);
+            }
+
+            pair<iterator, bool> insert(value_type&& val)
+            {
+                return tree_.insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            pair<iterator, bool> insert(
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace(forward<T>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val).first;
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val)).first;
+            }
+
+            template<class T>
+            iterator insert(
+                const_iterator hint,
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace_hint(hint, forward<T>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class... Args>
+            pair<iterator, bool> try_emplace(const key_type& key, Args&&... args)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                    return make_pair(iterator{parent, false}, false);
+                else
+                {
+                    auto node = new node_type{value_type{key, forward<Args>(args)...}};
+                    tree_.insert_node(node, parent);
+
+                    return make_pair(iterator{node, false}, true);
+                }
+            }
+
+            template<class... Args>
+            pair<iterator, bool> try_emplace(key_type&& key, Args&&... args)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                    return make_pair(iterator{parent, false}, false);
+                else
+                {
+                    auto node = new node_type{value_type{move(key), forward<Args>(args)...}};
+                    tree_.insert_node(node, parent);
+
+                    return make_pair(iterator{node, false}, true);
+                }
+            }
+
+            template<class... Args>
+            iterator try_emplace(const_iterator, const key_type& key, Args&&... args)
+            {
+                return try_emplace(key, forward<Args>(args)...).first;
+            }
+
+            template<class... Args>
+            iterator try_emplace(const_iterator, key_type&& key, Args&&... args)
+            {
+                return try_emplace(move(key), forward<Args>(args)...).first;
+            }
+
+            template<class T>
+            pair<iterator, bool> insert_or_assign(const key_type& key, T&& val)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                {
+                    parent->value.second = forward<T>(val);
+
+                    return make_pair(iterator{parent, false}, false);
+                }
+                else
+                {
+                    auto node = new node_type{value_type{key, forward<T>(val)}};
+                    tree_.insert_node(node, parent);
+
+                    return make_pair(iterator{node, false}, true);
+                }
+            }
+
+            template<class T>
+            pair<iterator, bool> insert_or_assign(key_type&& key, T&& val)
+            {
+                auto parent = tree_.find_parent_for_insertion(key);
+                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
+                {
+                    parent->value.second = forward<T>(val);
+
+                    return make_pair(iterator{parent, false}, false);
+                }
+                else
+                {
+                    auto node = new node_type{value_type{move(key), forward<T>(val)}};
+                    tree_.insert_node(node, parent);
+
+                    return make_pair(iterator{node, false}, true);
+                }
+            }
+
+            template<class T>
+            iterator insert_or_assign(const_iterator, const key_type& key, T&& val)
+            {
+                return insert_or_assign(key, forward<T>(val)).first;
+            }
+
+            template<class T>
+            iterator insert_or_assign(const_iterator, key_type&& key, T&& val)
+            {
+                return insert_or_assign(move(key), forward<T>(val)).first;
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return tree_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return tree_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    first.node(), first.end()
+                };
+            }
+
+            void swap(map& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
+            {
+                tree_.swap(other.tree_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            void clear() noexcept
+            {
+                tree_.clear();
+            }
+
+            key_compare key_comp() const
+            {
+                return tree_.key_comp();
+            }
+
+            value_compare value_comp() const
+            {
+                return value_compare{tree_.key_comp()};
+            }
+
+            iterator find(const key_type& key)
+            {
+                return tree_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            const_iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return tree_.count(key);
+            }
+
+            template<class K>
+            size_type count(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.count(key);
+            }
+
+            iterator lower_bound(const key_type& key)
+            {
+                return tree_.lower_bound(key);
+            }
+
+            const_iterator lower_bound(const key_type& key) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            const_iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            iterator upper_bound(const key_type& key)
+            {
+                return tree_.upper_bound(key);
+            }
+
+            const_iterator upper_bound(const key_type& key) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            const_iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return tree_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<iterator, iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<const_iterator, const_iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.equal_range(key);
+            }
+
+        private:
+            using tree_type = aux::rbtree<
+                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
+                key_compare, allocator_type, size_type,
+                iterator, const_iterator,
+                aux::rbtree_single_policy, node_type
+            >;
+
+            tree_type tree_;
+            allocator_type allocator_;
+
+            template<class K, class C, class A>
+            friend bool operator==(const map<K, C, A>&,
+                                   const map<K, C, A>&);
+    };
+
+    template<class Key, class Compare, class Allocator>
+    bool operator==(const map<Key, Compare, Allocator>& lhs,
+                    const map<Key, Compare, Allocator>& rhs)
+    {
+        return lhs.tree_.is_eq_to(rhs.tree_);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<(const map<Key, Compare, Allocator>& lhs,
+                   const map<Key, Compare, Allocator>& rhs)
+    {
+        return lexicographical_compare(
+            lhs.begin(), lhs.end(),
+            rhs.begin(), rhs.end(),
+            lhs.value_comp()
+        );
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator!=(const map<Key, Compare, Allocator>& lhs,
+                    const map<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>(const map<Key, Compare, Allocator>& lhs,
+                   const map<Key, Compare, Allocator>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>=(const map<Key, Compare, Allocator>& lhs,
+                    const map<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<=(const map<Key, Compare, Allocator>& lhs,
+                    const map<Key, Compare, Allocator>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    /**
+     * 23.4.5, class template multimap:
+     */
+
+    template<
+        class Key, class Value,
+        class Compare = less<Key>,
+        class Alloc = allocator<pair<const Key, Value>>
+    >
+    class multimap
+    {
+        public:
+            using key_type        = Key;
+            using mapped_type     = Value;
+            using value_type      = pair<const key_type, mapped_type>;
+            using key_compare     = Compare;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using node_type = aux::rbtree_multi_node<value_type>;
+
+            class value_compare
+            {
+                friend class multimap;
+
+                protected:
+                    key_compare comp;
+
+                    value_compare(key_compare c)
+                        : comp{c}
+                    { /* DUMMY BODY */ }
+
+                public:
+                    using result_type          = bool;
+                    using first_argument_type  = value_type;
+                    using second_argument_type = value_type;
+
+                    bool operator()(const value_type& lhs, const value_type& rhs) const
+                    {
+                        return comp(lhs.first, rhs.first);
+                    }
+            };
+
+            using iterator             = aux::rbtree_iterator<
+                value_type, reference, pointer, size_type, node_type
+            >;
+            using const_iterator       = aux::rbtree_const_iterator<
+                value_type, const_reference, const_pointer, size_type, node_type
+            >;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            multimap()
+                : multimap{key_compare{}}
+            { /* DUMMY BODY */ }
+
+            explicit multimap(const key_compare& comp,
+                              const allocator_type& alloc = allocator_type{})
+                : tree_{comp}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            multimap(InputIterator first, InputIterator last,
+                     const key_compare& comp = key_compare{},
+                     const allocator_type& alloc = allocator_type{})
+                : multimap{comp, alloc}
+            {
+                insert(first, last);
+            }
+
+            multimap(const multimap& other)
+                : multimap{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            multimap(multimap&& other)
+                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit multimap(const allocator_type& alloc)
+                : tree_{}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multimap(const multimap& other, const allocator_type& alloc)
+                : tree_{other.tree_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multimap(multimap&& other, const allocator_type& alloc)
+                : tree_{move(other.tree_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multimap(initializer_list<value_type> init,
+                     const key_compare& comp = key_compare{},
+                     const allocator_type& alloc = allocator_type{})
+                : multimap{comp, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class InputIterator>
+            multimap(InputIterator first, InputIterator last,
+                     const allocator_type& alloc)
+                : multimap{first, last, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            multimap(initializer_list<value_type> init,
+                     const allocator_type& alloc)
+                : multimap{init, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~multimap()
+            { /* DUMMY BODY */ }
+
+            multimap& operator=(const multimap& other)
+            {
+                tree_ = other.tree_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            multimap& operator=(multimap&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<key_compare>::value)
+            {
+                tree_ = move(other.tree_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            multimap& operator=(initializer_list<value_type>& init)
+            {
+                tree_.clear();
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return tree_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return tree_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return tree_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return tree_.end();
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return tree_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return tree_.cend();
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return tree_.crbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return tree_.crend();
+            }
+
+            bool empty() const noexcept
+            {
+                return tree_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return tree_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return tree_.max_size(allocator_);
+            }
+
+            template<class... Args>
+            iterator emplace(Args&&... args)
+            {
+                return tree_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...);
+            }
+
+            iterator insert(const value_type& val)
+            {
+                return tree_.insert(val);
+            }
+
+            iterator insert(value_type&& val)
+            {
+                return tree_.insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            iterator insert(
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace(forward<T>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val);
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            iterator insert(
+                const_iterator hint,
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace_hint(hint, forward<T>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return tree_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return tree_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    first.node(), first.end()
+                };
+            }
+
+            void swap(multimap& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
+            {
+                tree_.swap(other.tree_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            void clear() noexcept
+            {
+                tree_.clear();
+            }
+
+            key_compare key_comp() const
+            {
+                return tree_.key_comp();
+            }
+
+            value_compare value_comp() const
+            {
+                return value_compare{tree_.key_comp()};
+            }
+
+            iterator find(const key_type& key)
+            {
+                return tree_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            const_iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return tree_.count(key);
+            }
+
+            template<class K>
+            size_type count(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.count(key);
+            }
+
+            iterator lower_bound(const key_type& key)
+            {
+                return tree_.lower_bound(key);
+            }
+
+            const_iterator lower_bound(const key_type& key) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            const_iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            iterator upper_bound(const key_type& key)
+            {
+                return tree_.upper_bound(key);
+            }
+
+            const_iterator upper_bound(const key_type& key) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            const_iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return tree_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<iterator, iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<const_iterator, const_iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.equal_range(key);
+            }
+
+        private:
+            using tree_type = aux::rbtree<
+                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
+                key_compare, allocator_type, size_type,
+                iterator, const_iterator,
+                aux::rbtree_multi_policy, node_type
+            >;
+
+            tree_type tree_;
+            allocator_type allocator_;
+
+            template<class K, class C, class A>
+            friend bool operator==(const multimap<K, C, A>&,
+                                   const multimap<K, C, A>&);
+    };
+
+    template<class Key, class Compare, class Allocator>
+    bool operator==(const multimap<Key, Compare, Allocator>& lhs,
+                    const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return lhs.tree_.is_eq_to(rhs.tree_);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<(const multimap<Key, Compare, Allocator>& lhs,
+                   const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return lexicographical_compare(
+            lhs.begin(), lhs.end(),
+            rhs.begin(), rhs.end(),
+            lhs.value_comp()
+        );
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator!=(const multimap<Key, Compare, Allocator>& lhs,
+                    const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>(const multimap<Key, Compare, Allocator>& lhs,
+                   const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>=(const multimap<Key, Compare, Allocator>& lhs,
+                    const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<=(const multimap<Key, Compare, Allocator>& lhs,
+                    const multimap<Key, Compare, Allocator>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/queue.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/queue.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/queue.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_QUEUE
+#define LIBCPP_BITS_ADT_QUEUE
+
+#include <algorithm>
+#include <deque>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace std
+{
+    /**
+     * 23.6.3, class template queue:
+     */
+
+    template<class T, class Container = deque<T>>
+    class queue
+    {
+        public:
+            using value_type      = typename Container::value_type;
+            using reference       = typename Container::reference;
+            using const_reference = typename Container::const_reference;
+            using size_type       = typename Container::size_type;
+            using container_type  = Container;
+
+        protected:
+            container_type c;
+
+        public:
+            explicit queue(const container_type& cc)
+                : c{cc}
+            { /* DUMMY BODY */ }
+
+            explicit queue(container_type&& cc = container_type{})
+                : c{move(cc)}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            explicit queue(const Alloc& alloc)
+                : c{alloc}
+            { /* DUMMY BODY */}
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            queue(const container_type& cc, const Alloc& alloc)
+                : c{cc, alloc}
+            { /* DUMMY BODY */}
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            queue(container_type&& cc, const Alloc& alloc)
+                : c{move(cc), alloc}
+            { /* DUMMY BODY */}
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            queue(const queue& other, const Alloc& alloc)
+                : c{other.c, alloc}
+            { /* DUMMY BODY */}
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            queue(queue&& other, const Alloc& alloc)
+                : c{move(other.c), alloc}
+            { /* DUMMY BODY */}
+
+            bool empty() const
+            {
+                return c.empty();
+            }
+
+            size_type size() const
+            {
+                return c.size();
+            }
+
+            reference front()
+            {
+                return c.front();
+            }
+
+            const_reference front() const
+            {
+                return c.front();
+            }
+
+            reference back()
+            {
+                return c.back();
+            }
+
+            const_reference back() const
+            {
+                return c.back();
+            }
+
+            void push(const value_type& val)
+            {
+                c.push_back(val);
+            }
+
+            void push(value_type&& val)
+            {
+                c.push_back(forward<value_type>(val));
+            }
+
+            template<class... Args>
+            void emplace(Args&&... args)
+            {
+                c.emplace_back(forward<Args>(args)...);
+            }
+
+            void pop()
+            {
+                c.pop_front();
+            }
+
+            void swap(queue& other)
+                noexcept(noexcept(swap(c, other.c)))
+            {
+                std::swap(c, other.c);
+            }
+
+        private:
+            template<class U, class C>
+            friend bool operator==(const queue<U, C>&, const queue<U, C>&);
+
+            template<class U, class C>
+            friend bool operator<(const queue<U, C>&, const queue<U, C>&);
+
+            template<class U, class C>
+            friend bool operator!=(const queue<U, C>&, const queue<U, C>&);
+
+            template<class U, class C>
+            friend bool operator>(const queue<U, C>&, const queue<U, C>&);
+
+            template<class U, class C>
+            friend bool operator>=(const queue<U, C>&, const queue<U, C>&);
+
+            template<class U, class C>
+            friend bool operator<=(const queue<U, C>&, const queue<U, C>&);
+    };
+
+    template<class T, class Container, class Alloc>
+    struct uses_allocator<queue<T, Container>, Alloc>
+        : uses_allocator<Container, Alloc>
+    { /* DUMMY BODY */ };
+
+    /**
+     * 23.6.4, class template priority_queue:
+     */
+
+    template<
+        class T, class Container = vector<T>,
+        class Compare = less<typename Container::value_type>
+    >
+    class priority_queue
+    {
+        public:
+            using value_type      = typename Container::value_type;
+            using reference       = typename Container::reference;
+            using const_reference = typename Container::const_reference;
+            using size_type       = typename Container::size_type;
+            using container_type  = Container;
+
+        protected:
+            using compare_type = Compare;
+
+            compare_type comp;
+            container_type c;
+
+        public:
+            priority_queue(const compare_type& cmp, const container_type& cc)
+                : comp{cmp}, c{cc}
+            {
+                make_heap(c.begin(), c.end(), comp);
+            }
+
+            explicit priority_queue(const compare_type& cmp = compare_type{},
+                                    container_type&& cc = container_type{})
+                : comp{cmp}, c{move(cc)}
+            {
+                make_heap(c.begin(), c.end(), comp);
+            }
+
+            template<class InputIterator>
+            priority_queue(InputIterator first, InputIterator last,
+                           const compare_type& cmp,
+                           const container_type& cc)
+                : comp{cmp}, c{cc}
+            {
+                c.insert(c.end(), first, last);
+                make_heap(c.begin(), c.end(), comp);
+            }
+
+            template<class InputIterator>
+            priority_queue(InputIterator first, InputIterator last,
+                           const compare_type& cmp = compare_type{},
+                           container_type&& cc = container_type{})
+                : comp{cmp}, c{move(cc)}
+            {
+                c.insert(c.end(), first, last);
+                make_heap(c.begin(), c.end(), comp);
+            }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            explicit priority_queue(const Alloc& alloc)
+                : comp{}, c{alloc}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            priority_queue(const compare_type& cmp, const Alloc& alloc)
+                : comp{cmp}, c{alloc}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            priority_queue(const compare_type& cmp, const container_type& cc,
+                           const Alloc& alloc)
+                : comp{cmp}, c{cc, alloc}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            priority_queue(const compare_type& cmp, container_type&& cc,
+                           const Alloc& alloc)
+                : comp{cmp}, c{move(cc), alloc}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            priority_queue(const priority_queue& other, const Alloc& alloc)
+                : comp{other.comp}, c{other.c, alloc}
+            { /* DUMMY BODY */ }
+
+            template<
+                class Alloc,
+                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
+            >
+            priority_queue(priority_queue&& other, const Alloc& alloc)
+                : comp{move(other.comp)}, c{move(other.c), alloc}
+            { /* DUMMY BODY */ }
+
+            bool empty() const
+            {
+                return c.empty();
+            }
+
+            size_type size() const
+            {
+                return c.size();
+            }
+
+            const_reference top() const
+            {
+                return c.front();
+            }
+
+            void push(const value_type& val)
+            {
+                c.push_back(val);
+                push_heap(c.begin(), c.end(), comp);
+            }
+
+            void push(value_type&& val)
+            {
+                c.push_back(forward<value_type>(val));
+                push_heap(c.begin(), c.end(), comp);
+            }
+
+            template<class... Args>
+            void emplace(Args&&... args)
+            {
+                c.emplace_back(forward<Args>(args)...);
+                push_heap(c.begin(), c.end(), comp);
+            }
+
+            void pop()
+            {
+                pop_heap(c.begin(), c.end(), comp);
+                c.pop_back();
+            }
+
+            void swap(priority_queue& other)
+                noexcept(noexcept(swap(c, other.c)) && noexcept(swap(comp, other.comp)))
+            {
+                std::swap(c, other.c);
+                std::swap(comp, other.comp);
+            }
+    };
+
+    template<class T, class Container, class Compare, class Alloc>
+    struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
+        : uses_allocator<Container, Alloc>
+    { /* DUMMY BODY */ };
+
+    template<class T, class Container>
+    bool operator==(const queue<T, Container>& lhs,
+                    const queue<T, Container>& rhs)
+    {
+        return lhs.c == rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator<(const queue<T, Container>& lhs,
+                   const queue<T, Container>& rhs)
+    {
+        return lhs.c < rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator!=(const queue<T, Container>& lhs,
+                    const queue<T, Container>& rhs)
+    {
+        return lhs.c != rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator>(const queue<T, Container>& lhs,
+                   const queue<T, Container>& rhs)
+    {
+        return lhs.c > rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator>=(const queue<T, Container>& lhs,
+                    const queue<T, Container>& rhs)
+    {
+        return lhs.c >= rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator<=(const queue<T, Container>& lhs,
+                    const queue<T, Container>& rhs)
+    {
+        return lhs.c <= rhs.c;
+    }
+
+    template<class T, class Container>
+    void swap(queue<T, Container>& lhs, queue<T, Container>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class T, class Container, class Compare>
+    void swap(priority_queue<T, Container, Compare>& lhs,
+              priority_queue<T, Container, Compare>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/rbtree.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/rbtree.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/rbtree.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_RBTREE
+#define LIBCPP_BITS_ADT_RBTREE
+
+#include <__bits/adt/key_extractors.hpp>
+#include <__bits/adt/rbtree_iterators.hpp>
+#include <__bits/adt/rbtree_node.hpp>
+#include <__bits/adt/rbtree_policies.hpp>
+
+namespace std::aux
+{
+    template<
+        class Value, class Key, class KeyExtractor,
+        class KeyComp, class Alloc, class Size,
+        class Iterator, class ConstIterator,
+        class Policy, class Node
+    >
+    class rbtree
+    {
+        public:
+            using value_type     = Value;
+            using key_type       = Key;
+            using size_type      = Size;
+            using allocator_type = Alloc;
+            using key_compare    = KeyComp;
+            using key_extract    = KeyExtractor;
+
+            using iterator       = Iterator;
+            using const_iterator = ConstIterator;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            using node_type = Node;
+
+            rbtree(const key_compare& kcmp = key_compare{})
+                : root_{nullptr}, size_{}, key_compare_{},
+                  key_extractor_{}
+            { /* DUMMY BODY */ }
+
+            rbtree(const rbtree& other)
+                : rbtree{other.key_compare_}
+            {
+                for (const auto& x: other)
+                    insert(x);
+            }
+
+            rbtree(rbtree&& other)
+                : root_{other.root_}, size_{other.size_},
+                  key_compare_{move(other.key_compare_)},
+                  key_extractor_{move(other.key_extractor_)}
+            {
+                other.root_ = nullptr;
+                other.size_ = size_type{};
+            }
+
+            rbtree& operator=(const rbtree& other)
+            {
+                auto tmp{other};
+                tmp.swap(*this);
+
+                return *this;
+            }
+
+            rbtree& operator=(rbtree&& other)
+            {
+                rbtree tmp{move(other)};
+                tmp.swap(*this);
+
+                return *this;
+            }
+
+            bool empty() const noexcept
+            {
+                return size_ == 0U;
+            }
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type max_size(allocator_type& alloc)
+            {
+                return allocator_traits<allocator_type>::max_size(alloc);
+            }
+
+            iterator begin()
+            {
+                return iterator{find_smallest_(), false};
+            }
+
+            const_iterator begin() const
+            {
+                return cbegin();
+            }
+
+            iterator end()
+            {
+                /**
+                 * In case we have lists of nodes
+                 * we need to get the actual end
+                 * from the largest node.
+                 */
+                auto res = find_largest_();
+                if (res)
+                    return iterator{res->get_end(), true};
+                else
+                    return iterator{res, true};
+            }
+
+            const_iterator end() const
+            {
+                return cend();
+            }
+
+            reverse_iterator rbegin()
+            {
+                return make_reverse_iterator(end());
+            }
+
+            const_reverse_iterator rbegin() const
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            reverse_iterator rend()
+            {
+                return make_reverse_iterator(begin());
+            }
+
+            const_reverse_iterator rend() const
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            const_iterator cbegin() const
+            {
+                return const_iterator{find_smallest_(), false};
+            }
+
+            const_iterator cend() const
+            {
+                auto res = find_largest_();
+                if (res)
+                    return const_iterator{res->get_end(), true};
+                else
+                    return const_iterator{res, true};
+            }
+
+            const_reverse_iterator crbegin() const
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            const_reverse_iterator crend() const
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            template<class... Args>
+            auto emplace(Args&&... args)
+            {
+                return Policy::emplace(*this, forward<Args>(args)...);
+            }
+
+            auto insert(const value_type& val)
+            {
+                return Policy::insert(*this, val);
+            }
+
+            auto insert(value_type&& val)
+            {
+                return Policy::insert(*this, forward<value_type>(val));
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return Policy::erase(*this, key);
+            }
+
+            iterator erase(const_iterator it)
+            {
+                if (it == cend())
+                    return end();
+
+                auto node = const_cast<node_type*>(it.node());
+
+                node = delete_node(node);
+                if (!node)
+                    return iterator{find_largest_(), true};
+                else
+                    return iterator{const_cast<node_type*>(node), false};
+            }
+
+            void clear() noexcept
+            {
+                if (root_)
+                {
+                    delete root_;
+                    root_ = nullptr;
+                    size_ = size_type{};
+                }
+            }
+
+            void swap(rbtree& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(swap(declval<KeyComp&>(), declval<KeyComp&>())))
+            {
+                std::swap(root_, other.root_);
+                std::swap(size_, other.size_);
+                std::swap(key_compare_, other.key_compare_);
+                std::swap(key_extractor_, other.key_extractor_);
+            }
+
+            key_compare key_comp() const
+            {
+                return key_compare_;
+            }
+
+            iterator find(const key_type& key)
+            {
+                auto node = find_(key);
+                if (node)
+                    return iterator{node, false};
+                else
+                    return end();
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                auto node = find_(key);
+                if (node)
+                    return const_iterator{node, false};
+                else
+                    return end();
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return Policy::count(*this, key);
+            }
+
+            iterator upper_bound(const key_type& key)
+            {
+                return Policy::upper_bound(*this, key);
+            }
+
+            const_iterator upper_bound(const key_type& key) const
+            {
+                return Policy::upper_bound_const(*this, key);
+            }
+
+            iterator lower_bound(const key_type& key)
+            {
+                return Policy::lower_bound(*this, key);
+            }
+
+            const_iterator lower_bound(const key_type& key) const
+            {
+                return Policy::lower_bound_const(*this, key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return Policy::equal_range(*this, key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return Policy::equal_range_const(*this, key);
+            }
+
+            bool is_eq_to(const rbtree& other) const
+            {
+                if (size_ != other.size())
+                    return false;
+
+                auto it1 = begin();
+                auto it2 = other.begin();
+
+                // TODO: this doesn't compare values :/
+                while (keys_equal(*it1++, *it2++))
+                { /* DUMMY BODY */ }
+
+                return (it1 == end()) && (it2 == other.end());
+            }
+
+            const key_type& get_key(const value_type& val) const
+            {
+                return key_extractor_(val);
+            }
+
+            bool keys_comp(const key_type& key, const value_type& val) const
+            {
+                return key_compare_(key, key_extractor_(val));
+            }
+
+            bool keys_equal(const key_type& k1, const key_type& k2) const
+            {
+                return !key_compare_(k1, k2) && !key_compare_(k2, k1);
+            }
+
+            node_type* find_parent_for_insertion(const key_type& key) const
+            {
+                auto current = root_;
+                auto parent = current;
+
+                while (current)
+                {
+                    parent = current;
+                    if (key_compare_(key, key_extractor_(current->value)))
+                        current = current->left();
+                    else if (key_compare_(key_extractor_(current->value), key))
+                        current = current->right();
+                    else
+                        return current;
+                }
+
+                return parent;
+            }
+
+            node_type* delete_node(const node_type* n)
+            {
+                auto node = const_cast<node_type*>(n);
+                if (!node)
+                    return nullptr;
+
+                --size_;
+
+                auto succ = node->successor();
+                if (auto tmp = node->get_node_for_deletion(); tmp != nullptr)
+                {
+                    /**
+                     * This will kick in multi containers,
+                     * we popped one node from a list of nodes
+                     * with equivalent keys and we can delete it
+                     * and return the successor which was the next
+                     * in the list.
+                     */
+                    delete tmp;
+
+                    update_root_(succ); // Incase the first in list was root.
+                    return succ;
+                }
+                else if (node == root_)
+                { // Only executed if root_ is unique.
+                    root_ = nullptr;
+                    delete node;
+
+                    return nullptr;
+                }
+
+                if (node->left() && node->right())
+                {
+                    node->swap(succ);
+                    if (succ && !succ->parent())
+                        root_ = succ;
+
+                    // Node now has at most one child.
+                    // Also: If succ was nullptr, the swap
+                    //       didn't do anything and we can
+                    //       safely delete node.
+                    return delete_node(node);
+                }
+
+                auto child = node->right() ? node->right() : node->left();
+                if (!child)
+                {
+                    // Simply remove the node.
+                    // TODO: repair here too?
+                    node->unlink();
+                    delete node;
+                }
+                else
+                {
+                    // Replace with the child.
+                    child->parent(node->parent());
+                    if (node->is_left_child())
+                        child->parent()->left(child);
+                    else if (node->is_right_child())
+                        child->parent()->right(child);
+                    node->parent(nullptr);
+                    node->left(nullptr);
+                    node->right(nullptr);
+
+                    // Repair if needed.
+                    repair_after_erase_(node, child);
+                    update_root_(child);
+
+                    delete node;
+                }
+
+                return succ;
+            }
+
+            void insert_node(node_type* node, node_type* parent)
+            {
+                Policy::insert(*this, node, parent);
+            }
+
+        private:
+            node_type* root_;
+            size_type size_;
+            key_compare key_compare_;
+            key_extract key_extractor_;
+
+            node_type* find_(const key_type& key) const
+            {
+                auto current = root_;
+                while (current != nullptr)
+                {
+                    if (key_compare_(key, key_extractor_(current->value)))
+                        current = current->left();
+                    else if (key_compare_(key_extractor_(current->value), key))
+                        current = current->right();
+                    else
+                        return current;
+                }
+
+                return nullptr;
+            }
+
+            node_type* find_smallest_() const
+            {
+                if (root_)
+                    return root_->find_smallest();
+                else
+                    return nullptr;
+            }
+
+            node_type* find_largest_() const
+            {
+                if (root_)
+                    return root_->find_largest();
+                else
+                    return nullptr;
+            }
+
+            void update_root_(const node_type* node)
+            {
+                if (!node)
+                    return;
+
+                root_ = const_cast<node_type*>(node);
+                while (root_->parent())
+                    root_ = root_->parent();
+            }
+
+            void repair_after_insert_(const node_type* node)
+            {
+                // TODO: implement
+            }
+
+            void repair_after_erase_(const node_type* node, const node_type* child)
+            {
+                // TODO: implement
+            }
+
+            friend Policy;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/rbtree_iterators.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/rbtree_iterators.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/rbtree_iterators.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_RBTREE_ITERATORS
+#define LIBCPP_BITS_ADT_RBTREE_ITERATORS
+
+#include <__bits/adt/rbtree_node.hpp>
+#include <__bits/iterator_helpers.hpp>
+#include <iterator>
+
+namespace std::aux
+{
+    /**
+     * Note: In order for these iterators to be reversible,
+     *       the end state of an iterator is represented by a flag
+     *       which can be set from true to false in operator--
+     *       (i.e. decrementing end iterator) or set from false to
+     *       true in operator++ (i.e. incrementing last before end
+     *       iterator).
+     */
+
+    template<class Value, class Reference, class Pointer, class Size, class Node>
+    class rbtree_iterator
+    {
+        public:
+            using value_type      = Value;
+            using size_type       = Size;
+            using reference       = Reference;
+            using pointer         = Pointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = bidirectional_iterator_tag;
+
+            using node_type = Node;
+
+            rbtree_iterator(node_type* current = nullptr, bool end = true)
+                : current_{current}, end_{end}
+            { /* DUMMY BODY */ }
+
+            rbtree_iterator(const rbtree_iterator&) = default;
+            rbtree_iterator& operator=(const rbtree_iterator&) = default;
+
+            reference operator*() const
+            {
+                return current_->value;
+            }
+
+            pointer operator->() const
+            {
+                return &current_->value;
+            }
+
+            rbtree_iterator& operator++()
+            {
+                if (end_)
+                    return *this;
+
+                if (current_)
+                {
+                    auto next = current_->successor();
+                    if (next)
+                        current_ = next;
+                    else
+                        end_ = true;
+                }
+
+                return *this;
+            }
+
+            rbtree_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+            rbtree_iterator& operator--()
+            {
+                if (end_)
+                {
+                    end_ = false;
+
+                    return *this;
+                }
+
+                if (current_)
+                {
+                    auto next = current_->predecessor();
+                    if (next)
+                        current_ = next;
+                    else
+                        end_ = true;
+                }
+
+                return *this;
+            }
+
+            rbtree_iterator operator--(int)
+            {
+                auto tmp = *this;
+                --(*this);
+
+                return tmp;
+            }
+
+            const node_type* node() const
+            {
+                return current_;
+            }
+
+            node_type* node()
+            {
+                return current_;
+            }
+
+            bool end() const
+            {
+                return end_;
+            }
+
+        private:
+            node_type* current_;
+            bool end_;
+    };
+
+    template<class Val, class Ref, class Ptr, class Sz, class N>
+    bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
+                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
+    {
+        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+    }
+
+    template<class Val, class Ref, class Ptr, class Sz, class N>
+    bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
+                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Value, class ConstReference, class ConstPointer, class Size, class Node>
+    class rbtree_const_iterator
+    {
+        using non_const_iterator_type = rbtree_iterator<
+            Value, get_non_const_ref_t<ConstReference>,
+            get_non_const_ptr_t<ConstPointer>, Size, Node
+        >;
+
+        public:
+            using value_type      = Value;
+            using size_type       = Size;
+            using const_reference = ConstReference;
+            using const_pointer   = ConstPointer;
+            using difference_type = ptrdiff_t;
+
+            using iterator_category = bidirectional_iterator_tag;
+
+            // For iterator_traits.
+            using reference = ConstReference;
+            using pointer   = ConstPointer;
+
+            using node_type = Node;
+
+            rbtree_const_iterator(const node_type* current = nullptr, bool end = true)
+                : current_{current}, end_{end}
+            { /* DUMMY BODY */ }
+
+            rbtree_const_iterator(const rbtree_const_iterator&) = default;
+            rbtree_const_iterator& operator=(const rbtree_const_iterator&) = default;
+
+            rbtree_const_iterator(const non_const_iterator_type& other)
+                : current_{other.node()}, end_{other.end()}
+            { /* DUMMY BODY */ }
+
+            rbtree_const_iterator& operator=(const non_const_iterator_type& other)
+            {
+                current_ = other.node();
+                end_ = other.end();
+
+                return *this;
+            }
+
+            const_reference operator*() const
+            {
+                return current_->value;
+            }
+
+            const_pointer operator->() const
+            {
+                return &current_->value;
+            }
+
+            rbtree_const_iterator& operator++()
+            {
+                if (end_)
+                    return *this;
+
+                if (current_)
+                {
+                    auto next = current_->successor();
+                    if (next)
+                        current_ = next;
+                    else
+                        end_ = true;
+                }
+
+                return *this;
+            }
+
+            rbtree_const_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++(*this);
+
+                return tmp;
+            }
+
+            rbtree_const_iterator& operator--()
+            {
+                if (end_)
+                {
+                    end_ = false;
+
+                    return *this;
+                }
+
+                if (current_)
+                {
+                    auto next = current_->predecessor();
+                    if (next)
+                        current_ = next;
+                    else
+                        end_ = true;
+                }
+
+                return *this;
+            }
+
+            rbtree_const_iterator operator--(int)
+            {
+                auto tmp = *this;
+                --(*this);
+
+                return tmp;
+            }
+
+            const node_type* node() const
+            {
+                return current_;
+            }
+
+            bool end() const
+            {
+                return end_;
+            }
+
+        private:
+            const node_type* current_;
+            bool end_;
+    };
+
+    template<class Val, class CRef, class CPtr, class Sz, class N>
+    bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
+                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
+    {
+        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+    }
+
+    template<class Val, class CRef, class CPtr, class Sz, class N>
+    bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
+                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
+    bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
+                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
+    {
+        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+    }
+
+    template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
+    bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
+                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
+    bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
+                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
+    {
+        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
+    }
+
+    template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
+    bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
+                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/rbtree_node.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/rbtree_node.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/rbtree_node.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_RBTREE_NODE
+#define LIBCPP_BITS_ADT_RBTREE_NODE
+
+#include <cassert>
+#include <utility>
+
+namespace std::aux
+{
+    enum class rbcolor
+    {
+        red, black
+    };
+
+    template<class Node>
+    struct rbtree_utils
+    {
+        static Node* grandparent(Node* node)
+        {
+            if (node && node->parent())
+                return node->parent()->parent();
+            else
+                return nullptr;
+        }
+
+        static Node* brother(Node* node)
+        {
+            if (node && node->parent())
+            {
+                if (node == node->parent()->left())
+                    return node->parent()->right();
+                else
+                    return node->parent()->left();
+            }
+            else
+                return nullptr;
+        }
+
+        static Node* uncle(Node* node)
+        {
+            auto gp = grandparent(node);
+            if (gp)
+            {
+                if (node->parent() == gp->left())
+                    return gp->right();
+                else
+                    return gp->left();
+            }
+            else
+                return nullptr;
+        }
+
+        static bool is_left_child(const Node* node)
+        {
+            if (!node)
+                return false;
+
+            if (node->parent())
+                return node->parent()->left() == node;
+            else
+                return false;
+        }
+
+        static bool is_right_child(const Node* node)
+        {
+            if (!node)
+                return false;
+
+            if (node->parent())
+                return node->parent()->right() == node;
+            else
+                return false;
+        }
+
+        static void rotate_left(Node* node)
+        {
+            // TODO: implement
+        }
+
+        static void rotate_right(Node* node)
+        {
+            // TODO: implement
+        }
+
+        static Node* find_smallest(Node* node)
+        {
+            return const_cast<Node*>(find_smallest(const_cast<const Node*>(node)));
+        }
+
+        static const Node* find_smallest(const Node* node)
+        {
+            if (!node)
+                return nullptr;
+
+            while (node->left())
+                node = node->left();
+
+            return node;
+        }
+
+        static Node* find_largest(Node* node)
+        {
+            return const_cast<Node*>(find_largest(const_cast<const Node*>(node)));
+        }
+
+        static const Node* find_largest(const Node* node)
+        {
+            if (!node)
+                return nullptr;
+
+            while (node->right())
+                node = node->right();
+
+            return node;
+        }
+
+        static Node* successor(Node* node)
+        {
+            return const_cast<Node*>(successor(const_cast<const Node*>(node)));
+        }
+
+        static const Node* successor(const Node* node)
+        {
+            if (!node)
+                return nullptr;
+
+            if (node->right())
+                return find_smallest(node->right());
+            else
+            {
+                while (node && !is_left_child(node))
+                    node = node->parent();
+
+                if (node)
+                    return node->parent();
+                else
+                    return node;
+            }
+        }
+
+        static Node* predecessor(Node* node)
+        {
+            return const_cast<Node*>(predecessor(const_cast<const Node*>(node)));
+        }
+
+        static const Node* predecessor(const Node* node)
+        {
+            if (!node)
+                return nullptr;
+
+            if (node->left())
+                return find_largest(node->left());
+            else
+            {
+                while (node && is_left_child(node))
+                    node = node->parent();
+
+                if (node)
+                    return node->parent();
+                else
+                    return node;
+            }
+        }
+
+        static void add_left_child(Node* node, Node* child)
+        {
+            if (!node || !child)
+                return;
+
+            node->left(child);
+            child->parent(node);
+        }
+
+        static void add_right_child(Node* node, Node* child)
+        {
+            if (!node || !child)
+                return;
+
+            node->right(child);
+            child->parent(node);
+        }
+
+        static void swap(Node* node1, Node* node2)
+        {
+            if (!node1 || !node2)
+                return;
+
+            auto parent1 = node1->parent();
+            auto left1 = node1->left();
+            auto right1 = node1->right();
+            auto is_right1 = is_right_child(node1);
+
+            auto parent2 = node2->parent();
+            auto left2 = node2->left();
+            auto right2 = node2->right();
+            auto is_right2 = is_right_child(node2);
+
+            assimilate(node1, parent2, left2, right2, is_right2);
+            assimilate(node2, parent1, left1, right1, is_right1);
+        }
+
+        static void assimilate(
+            Node* node, Node* p, Node* l, Node* r, bool is_r
+        )
+        {
+            if (!node)
+                return;
+
+            node->parent(p);
+            if (node->parent())
+            {
+                if (is_r)
+                    node->parent()->right(node);
+                else
+                    node->parent()->left(node);
+            }
+
+            node->left(l);
+            if (node->left())
+                node->left()->parent(node);
+
+            node->right(r);
+            if (node->right())
+                node->right()->parent(node);
+        }
+    };
+
+    template<class T>
+    struct rbtree_single_node
+    {
+        using utils = rbtree_utils<rbtree_single_node<T>>;
+
+        public:
+            T value;
+            rbcolor color;
+
+            template<class... Args>
+            rbtree_single_node(Args&&... args)
+                : value{forward<Args>(args)...}, color{rbcolor::red},
+                  parent_{}, left_{}, right_{}
+            { /* DUMMY BODY */ }
+
+            rbtree_single_node* parent() const
+            {
+                return parent_;
+            }
+
+            void parent(rbtree_single_node* node)
+            {
+                parent_ = node;
+            }
+
+            rbtree_single_node* left() const
+            {
+                return left_;
+            }
+
+            void left(rbtree_single_node* node)
+            {
+                left_ = node;
+            }
+
+            rbtree_single_node* right() const
+            {
+                return right_;
+            }
+
+            void right(rbtree_single_node* node)
+            {
+                right_ = node;
+            }
+
+            rbtree_single_node* grandparent()
+            {
+                return utils::grandparent(this);
+            }
+
+            rbtree_single_node* brother()
+            {
+                return utils::brother(this);
+            }
+
+            rbtree_single_node* uncle()
+            {
+                return utils::uncle(this);
+            }
+
+            bool is_left_child() const
+            {
+                return utils::is_left_child(this);
+            }
+
+            bool is_right_child() const
+            {
+                return utils::is_right_child(this);
+            }
+
+            void rotate_left()
+            {
+                utils::rotate_left(this);
+            }
+
+            void rotate_right()
+            {
+                utils::rotate_right(this);
+            }
+
+            rbtree_single_node* find_smallest()
+            {
+                return utils::find_smallest(this);
+            }
+
+            const rbtree_single_node* find_smallest() const
+            {
+                return utils::find_smallest(this);
+            }
+
+            rbtree_single_node* find_largest()
+            {
+                return utils::find_largest(this);
+            }
+
+            const rbtree_single_node* find_largest() const
+            {
+                return utils::find_largest(this);
+            }
+
+            rbtree_single_node* successor()
+            {
+                return utils::successor(this);
+            }
+
+            const rbtree_single_node* successor() const
+            {
+                return utils::successor(this);
+            }
+
+            rbtree_single_node* predecessor()
+            {
+                return utils::predecessor(this);
+            }
+
+            const rbtree_single_node* predecessor() const
+            {
+                return utils::predecessor(this);
+            }
+
+            void add_left_child(rbtree_single_node* node)
+            {
+                utils::add_left_child(this, node);
+            }
+
+            void add_right_child(rbtree_single_node* node)
+            {
+                utils::add_right_child(this, node);
+            }
+
+            void swap(rbtree_single_node* other)
+            {
+                utils::swap(this, other);
+            }
+
+            void unlink()
+            {
+                if (is_left_child())
+                    parent_->left_ = nullptr;
+                else if (is_right_child())
+                    parent_->right_ = nullptr;
+            }
+
+            rbtree_single_node* get_node_for_deletion()
+            {
+                return nullptr;
+            }
+
+            rbtree_single_node* get_end()
+            {
+                return this;
+            }
+
+            const rbtree_single_node* get_end() const
+            {
+                return this;
+            }
+
+            ~rbtree_single_node()
+            {
+                parent_ = nullptr;
+                if (left_)
+                    delete left_;
+                if (right_)
+                    delete right_;
+            }
+
+        private:
+            rbtree_single_node* parent_;
+            rbtree_single_node* left_;
+            rbtree_single_node* right_;
+    };
+
+    template<class T>
+    struct rbtree_multi_node
+    {
+        using utils = rbtree_utils<rbtree_multi_node<T>>;
+
+        public:
+            T value;
+            rbcolor color;
+
+            template<class... Args>
+            rbtree_multi_node(Args&&... args)
+                : value{forward<Args>(args)...}, color{rbcolor::red},
+                  parent_{}, left_{}, right_{}, next_{}, first_{}
+            {
+                first_ = this;
+            }
+
+            rbtree_multi_node* parent() const
+            {
+                return parent_;
+            }
+
+            void parent(rbtree_multi_node* node)
+            {
+                parent_ = node;
+
+                auto tmp = first_;
+                while (tmp)
+                {
+                    tmp->parent_ = node;
+                    tmp = tmp->next_;
+                }
+            }
+
+            rbtree_multi_node* left() const
+            {
+                return left_;
+            }
+
+            void left(rbtree_multi_node* node)
+            {
+                left_ = node;
+
+                auto tmp = first_;
+                while (tmp)
+                {
+                    tmp->left_ = node;
+                    tmp = tmp->next_;
+                }
+            }
+
+            rbtree_multi_node* right() const
+            {
+                return right_;
+            }
+
+            void right(rbtree_multi_node* node)
+            {
+                right_ = node;
+
+                auto tmp = first_;
+                while (tmp)
+                {
+                    tmp->right_ = node;
+                    tmp = tmp->next_;
+                }
+            }
+
+            rbtree_multi_node* grandparent()
+            {
+                return utils::grandparent(this);
+            }
+
+            rbtree_multi_node* brother()
+            {
+                return utils::brother(this);
+            }
+
+            rbtree_multi_node* uncle()
+            {
+                return utils::uncle(this);
+            }
+
+            bool is_left_child() const
+            {
+                return utils::is_left_child(this);
+            }
+
+            bool is_right_child()
+            {
+                return utils::is_right_child(this);
+            }
+
+            void rotate_left()
+            {
+                utils::rotate_left(this);
+            }
+
+            void rotate_right()
+            {
+                utils::rotate_right(this);
+            }
+
+            rbtree_multi_node* find_smallest()
+            {
+                return utils::find_smallest(this);
+            }
+
+            const rbtree_multi_node* find_smallest() const
+            {
+                return utils::find_smallest(this);
+            }
+
+            rbtree_multi_node* find_largest()
+            {
+                return utils::find_largest(this);
+            }
+
+            const rbtree_multi_node* find_largest() const
+            {
+                return utils::find_largest(this);
+            }
+
+            rbtree_multi_node* successor()
+            {
+                return const_cast<
+                    rbtree_multi_node*
+                >(const_cast<const rbtree_multi_node*>(this)->successor());
+            }
+
+            const rbtree_multi_node* successor() const
+            {
+                if (next_)
+                    return next_;
+                else
+                    return utils::successor(this);
+            }
+
+            rbtree_multi_node* predecessor()
+            {
+                return const_cast<
+                    rbtree_multi_node*
+                >(const_cast<const rbtree_multi_node*>(this)->predecessor());
+            }
+
+            const rbtree_multi_node* predecessor() const
+            {
+                if (this != first_)
+                {
+                    auto tmp = first_;
+                    while (tmp->next_ != this)
+                        tmp = tmp->next_;
+
+                    return tmp;
+                }
+                else
+                {
+                    auto tmp = utils::predecessor(this);
+
+                    /**
+                     * If tmp was duplicate, we got a pointer
+                     * to the first node in the list. So we need
+                     * to move to the end.
+                     */
+                    while (tmp->next_ != nullptr)
+                        tmp = tmp->next_;
+
+                    return tmp;
+                }
+            }
+
+            void add_left_child(rbtree_multi_node* node)
+            {
+                utils::add_left_child(this, node);
+            }
+
+            void add_right_child(rbtree_multi_node* node)
+            {
+                utils::add_right_child(this, node);
+            }
+
+            void swap(rbtree_multi_node* other)
+            {
+                utils::swap(this, other);
+            }
+
+            rbtree_multi_node* get_node_for_deletion()
+            {
+                /**
+                 * To make sure we delete nodes in
+                 * the order of their insertion
+                 * (not required, but sensical), we
+                 * update then list and return this
+                 * for deletion.
+                 */
+                if (next_)
+                {
+                    // Make next the new this.
+                    next_->first_ = next_;
+                    if (is_left_child())
+                        parent_->left_ = next_;
+                    else if (is_right_child())
+                        parent_->right_ = next_;
+
+                    if (left_)
+                        left_->parent_ = next_;
+                    if (right_)
+                        right_->parent_ = next_;
+
+                    /**
+                     * Update the first_ pointer
+                     * of the rest of the list.
+                     */
+                    auto tmp = next_->next_;
+                    while (tmp)
+                    {
+                        tmp->first_ = next_;
+                        tmp = tmp->next_;
+                    }
+
+                    /**
+                     * Otherwise destructor could
+                     * destroy them.
+                     */
+                    parent_ = nullptr;
+                    left_ = nullptr;
+                    right_ = nullptr;
+                    next_ = nullptr;
+                    first_ = nullptr;
+
+                    return this; // This will get deleted.
+                }
+                else
+                    return nullptr;
+            }
+
+            void unlink()
+            {
+                if (is_left_child())
+                    parent_->left_ = nullptr;
+                else if (is_right_child())
+                    parent_->right_ = nullptr;
+            }
+
+            void add(rbtree_multi_node* node)
+            {
+                if (next_)
+                    next_->add(node);
+                else
+                {
+                    next_ = node;
+                    next_->first_ = first_;
+                    next_->parent_ = parent_;
+                    next_->left_ = left_;
+                    next_->right_ = right_;
+                }
+            }
+
+            rbtree_multi_node* get_end()
+            {
+                return const_cast<rbtree_multi_node*>(
+                    const_cast<const rbtree_multi_node*>(this)->get_end()
+                );
+            }
+
+            const rbtree_multi_node* get_end() const
+            {
+                if (!next_)
+                    return this;
+                else
+                {
+                    auto tmp = next_;
+                    while (tmp->next_)
+                        tmp = tmp->next_;
+
+                    return tmp;
+                }
+            }
+
+            ~rbtree_multi_node()
+            {
+                parent_ = nullptr;
+                if (left_)
+                    delete left_;
+                if (right_)
+                    delete right_;
+
+                // TODO: delete the list
+            }
+
+        private:
+            rbtree_multi_node* parent_;
+            rbtree_multi_node* left_;
+            rbtree_multi_node* right_;
+
+            rbtree_multi_node* next_;
+            rbtree_multi_node* first_;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/rbtree_policies.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/rbtree_policies.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/rbtree_policies.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_RBTREE_POLICIES
+#define LIBCPP_BITS_ADT_RBTREE_POLICIES
+
+#include <__bits/adt/rbtree_node.hpp>
+#include <utility>
+
+namespace std::aux
+{
+    struct rbtree_single_policy
+    {
+        template<class Tree, class Key>
+        static typename Tree::size_type count(const Tree& tree, const Key& key)
+        {
+            return tree.find(key) == tree.end() ? 0 : 1;
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::size_type erase(Tree& tree, const Key& key)
+        {
+            using size_type = typename Tree::size_type;
+
+            auto it = tree.find(key);
+            if (it == tree.end())
+                return size_type{};
+            else
+                tree.delete_node(it.node());
+            return size_type{1};
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::iterator lower_bound(const Tree& tree, const Key& key)
+        {
+            using iterator  = typename Tree::iterator;
+            using node_type = typename Tree::node_type;
+
+            auto it = lower_bound_const(tree, key);
+
+            return iterator{const_cast<node_type*>(it.node()), it.end()};
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::const_iterator lower_bound_const(const Tree& tree, const Key& key)
+        {
+            using const_iterator = typename Tree::const_iterator;
+
+            auto node = tree.find_parent_for_insertion(key);
+            const_iterator it{node, false};
+            auto beg = tree.begin();
+            auto end = tree.end();
+
+            if (tree.key_compare_(tree.get_key(*it), key))
+            {
+                // Predecessor.
+                if (it != end)
+                    return ++it;
+                else
+                    return it;
+            }
+            else if (tree.key_compare_(key, tree.get_key(*it)))
+            {
+                // Successor.
+                if (it != beg)
+                    return --it;
+                else
+                    return it;
+            }
+            else // Perfect match.
+                return it;
+
+            return it;
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::iterator upper_bound(const Tree& tree, const Key& key)
+        {
+            using iterator  = typename Tree::iterator;
+            using node_type = typename Tree::node_type;
+
+            auto it = upper_bound_const(tree, key);
+
+            return iterator{const_cast<node_type*>(it.node()), it.end()};
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::const_iterator upper_bound_const(const Tree& tree, const Key& key)
+        {
+            /**
+             * If key isn't in the tree, we get it's
+             * predecessor or tree.end(). If key is
+             * in the tree, we get it. So unless it
+             * is equal to end(), we can increment it
+             * to get the upper bound.
+             */
+            auto it = lower_bound_const(tree, key);
+            if (it == tree.end())
+                return it;
+            else
+                return ++it;
+        }
+
+        template<class Tree, class Key>
+        static pair<
+            typename Tree::iterator,
+            typename Tree::iterator
+        > equal_range(Tree& tree, const Key& key)
+        {
+            return make_pair(
+                lower_bound(tree, key),
+                upper_bound(tree, key)
+            );
+        }
+
+        template<class Tree, class Key>
+        static pair<
+            typename Tree::const_iterator,
+            typename Tree::const_iterator
+        > equal_range_const(const Tree& tree, const Key& key)
+        {
+            return make_pair(
+                lower_bound_const(tree, key),
+                upper_bound_const(tree, key)
+            );
+        }
+
+        /**
+         * Note: We have to duplicate code for emplace, insert(const&)
+         *       and insert(&&) here, because the node (which makes distinction
+         *       between the arguments) is only created if the value isn't
+         *       in the tree already.
+         */
+
+        template<class Tree, class... Args>
+        static pair<
+            typename Tree::iterator, bool
+        > emplace(Tree& tree, Args&&... args)
+        {
+            using value_type = typename Tree::value_type;
+            using iterator   = typename Tree::iterator;
+            using node_type  = typename Tree::node_type;
+
+            auto val = value_type{forward<Args>(args)...};
+            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
+
+            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
+                return make_pair(iterator{parent, false}, false);
+
+            auto node = new node_type{move(val)};
+
+            return insert(tree, node, parent);
+        }
+
+        template<class Tree, class Value>
+        static pair<
+            typename Tree::iterator, bool
+        > insert(Tree& tree, const Value& val)
+        {
+            using iterator  = typename Tree::iterator;
+            using node_type = typename Tree::node_type;
+
+            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
+            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
+                return make_pair(iterator{parent, false}, false);
+
+            auto node = new node_type{val};
+
+            return insert(tree, node, parent);
+        }
+
+        template<class Tree, class Value>
+        static pair<
+            typename Tree::iterator, bool
+        > insert(Tree& tree, Value&& val)
+        {
+            using iterator  = typename Tree::iterator;
+            using node_type = typename Tree::node_type;
+
+            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
+            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
+                return make_pair(iterator{parent, false}, false);
+
+            auto node = new node_type{forward<Value>(val)};
+
+            return insert(tree, node, parent);
+        }
+
+        template<class Tree>
+        static pair<
+            typename Tree::iterator, bool
+        > insert(
+            Tree& tree, typename Tree::node_type* node,
+            typename Tree::node_type* parent
+        )
+        {
+            using iterator  = typename Tree::iterator;
+
+            if (!node)
+                return make_pair(tree.end(), false);
+
+            ++tree.size_;
+            if (!parent)
+            {
+                node->color = rbcolor::black;
+                tree.root_ = node;
+            }
+            else
+            {
+                if (tree.keys_comp(tree.get_key(node->value), parent->value))
+                    parent->add_left_child(node);
+                else
+                    parent->add_right_child(node);
+
+                tree.repair_after_insert_(node);
+                tree.update_root_(node);
+            }
+
+            return make_pair(iterator{node, false}, true);
+        }
+    };
+
+    struct rbtree_multi_policy
+    {
+        template<class Tree, class Key>
+        static typename Tree::size_type count(const Tree& tree, const Key& key)
+        {
+            using size_type = typename Tree::size_type;
+
+            auto it = tree.find(key);
+            if (it == tree.end())
+                return size_type{};
+
+            size_type res{};
+            while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
+            {
+                ++res;
+                ++it;
+            }
+
+            return res;
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::size_type erase(Tree& tree, const Key& key)
+        {
+            using size_type = typename Tree::size_type;
+
+            auto it = tree.find(key);
+            if (it == tree.end())
+                return size_type{};
+
+            size_type res{};
+            while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
+            {
+                ++res;
+                it = tree.erase(it);
+            }
+
+            return res;
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::iterator lower_bound(const Tree& tree, const Key& key)
+        {
+            auto it = lower_bound_const(tree, key);
+
+            return typename Tree::iterator{
+                const_cast<typename Tree::node_type*>(it.node()), it.end()
+            };
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::const_iterator lower_bound_const(const Tree& tree, const Key& key)
+        {
+            using const_iterator = typename Tree::const_iterator;
+
+            auto node = tree.find_parent_for_insertion(key);
+            const_iterator it{node, false};
+            auto beg = tree.begin();
+            auto end = tree.end();
+
+            if (tree.keys_comp(key, *it))
+                --it; // Incase we are on a successor.
+            while (tree.keys_equal(tree.get_key(*it), key) && it != beg)
+                --it; // Skip keys that are equal.
+            if (it != beg)
+                ++it; // If we moved all the way to the start, key is the smallest.
+
+            if (tree.key_compare_(tree.get_key(*it), key))
+            {
+                // Predecessor.
+                if (it != end)
+                    return ++it;
+                else
+                    return it;
+            }
+
+            return it;
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::iterator upper_bound(const Tree& tree, const Key& key)
+        {
+            auto it = upper_bound_const(tree, key);
+
+            return typename Tree::iterator{
+                const_cast<typename Tree::node_type*>(it.node()), it.end()
+            };
+        }
+
+        template<class Tree, class Key>
+        static typename Tree::const_iterator upper_bound_const(const Tree& tree, const Key& key)
+        {
+            /**
+             * If key isn't in the tree, we get it's
+             * predecessor or tree.end(). If key is
+             * in the tree, we get it. So unless it
+             * is equal to end(), we keep incrementing
+             * until we get to the next key.
+             */
+            auto it = lower_bound(tree, key);
+            if (it == tree.end())
+                return it;
+            else if (tree.keys_equal(tree.get_key(*it), key))
+            {
+                while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
+                    ++it;
+
+                return it;
+            }
+
+            return it;
+        }
+
+        template<class Tree, class Key>
+        static pair<
+            typename Tree::iterator,
+            typename Tree::iterator
+        > equal_range(const Tree& tree, const Key& key)
+        {
+            return make_pair(
+                lower_bound(tree, key),
+                upper_bound(tree, key)
+            );
+        }
+
+        template<class Tree, class Key>
+        static pair<
+            typename Tree::const_iterator,
+            typename Tree::const_iterator
+        > equal_range_const(const Tree& tree, const Key& key)
+        {
+            return make_pair(
+                lower_bound_const(tree, key),
+                upper_bound_const(tree, key)
+            );
+        }
+
+        template<class Tree, class... Args>
+        static typename Tree::iterator emplace(Tree& tree, Args&&... args)
+        {
+            using node_type  = typename Tree::node_type;
+
+            auto node = new node_type{forward<Args>(args)...};
+
+            return insert(tree, node);
+        }
+
+        template<class Tree, class Value>
+        static typename Tree::iterator insert(Tree& tree, const Value& val)
+        {
+            using node_type = typename Tree::node_type;
+
+            auto node = new node_type{val};
+
+            return insert(tree, node);
+        }
+
+        template<class Tree, class Value>
+        static typename Tree::iterator insert(Tree& tree, Value&& val)
+        {
+            using node_type = typename Tree::node_type;
+
+            auto node = new node_type{forward<Value>(val)};
+
+            return insert(tree, node);
+        }
+
+        template<class Tree>
+        static typename Tree::iterator insert(
+            Tree& tree, typename Tree::node_type* node,
+            typename Tree::node_type* = nullptr
+        )
+        {
+            using iterator  = typename Tree::iterator;
+
+            if (!node)
+                return tree.end();
+
+            auto parent = tree.find_parent_for_insertion(tree.get_key(node->value));
+
+            ++tree.size_;
+            if (!parent)
+            {
+                node->color = rbcolor::black;
+                tree.root_ = node;
+            }
+            else
+            {
+                if (tree.keys_comp(tree.get_key(node->value), parent->value))
+                    parent->add_left_child(node);
+                else if (tree.keys_comp(tree.get_key(parent->value), node->value))
+                    parent->add_right_child(node);
+                else
+                {
+                    parent->add(node); // List of nodes with equivalent keys.
+                    tree.update_root_(parent);
+
+                    return iterator{node, false};
+                }
+
+                tree.repair_after_insert_(node);
+                tree.update_root_(node);
+            }
+
+            return iterator{node, false};
+        }
+    };
+}
+
+#endif
+
Index: uspace/lib/cpp/include/__bits/adt/set.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/set.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/set.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1003 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_SET
+#define LIBCPP_BITS_ADT_SET
+
+#include <__bits/adt/rbtree.hpp>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.4.6, class template set:
+     */
+
+    template<
+        class Key,
+        class Compare = less<Key>,
+        class Alloc = allocator<Key>
+    >
+    class set
+    {
+        public:
+            using key_type        = Key;
+            using value_type      = Key;
+            using key_compare     = Compare;
+            using value_compare   = Compare;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using node_type = aux::rbtree_single_node<value_type>;
+
+            /**
+             * Note: Both the iterator and const_iterator (and their local variants)
+             *       types are constant iterators, the standard does not require them
+             *       to be the same type, but why not? :)
+             */
+            using iterator             = aux::rbtree_const_iterator<
+                value_type, const_reference, const_pointer, size_type, node_type
+            >;
+            using const_iterator       = iterator;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            set()
+                : set{key_compare{}}
+            { /* DUMMY BODY */ }
+
+            explicit set(const key_compare& comp,
+                         const allocator_type& alloc = allocator_type{})
+                : tree_{comp}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            set(InputIterator first, InputIterator last,
+                const key_compare& comp = key_compare{},
+                const allocator_type& alloc = allocator_type{})
+                : set{comp, alloc}
+            {
+                insert(first, last);
+            }
+
+            set(const set& other)
+                : set{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            set(set&& other)
+                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit set(const allocator_type& alloc)
+                : tree_{}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            set(const set& other, const allocator_type& alloc)
+                : tree_{other.tree_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            set(set&& other, const allocator_type& alloc)
+                : tree_{move(other.tree_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            set(initializer_list<value_type> init,
+                const key_compare& comp = key_compare{},
+                const allocator_type& alloc = allocator_type{})
+                : set{comp, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class InputIterator>
+            set(InputIterator first, InputIterator last,
+                const allocator_type& alloc)
+                : set{first, last, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            set(initializer_list<value_type> init,
+                const allocator_type& alloc)
+                : set{init, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~set()
+            { /* DUMMY BODY */ }
+
+            set& operator=(const set& other)
+            {
+                tree_ = other.tree_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            set& operator=(set&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<key_compare>::value)
+            {
+                tree_ = move(other.tree_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            set& operator=(initializer_list<value_type>& init)
+            {
+                tree_.clear();
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return tree_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return tree_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return tree_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return tree_.end();
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return tree_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return tree_.cend();
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return tree_.crbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return tree_.crend();
+            }
+
+            bool empty() const noexcept
+            {
+                return tree_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return tree_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return tree_.max_size(allocator_);
+            }
+
+            template<class... Args>
+            pair<iterator, bool> emplace(Args&&... args)
+            {
+                return tree_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...).first;
+            }
+
+            pair<iterator, bool> insert(const value_type& val)
+            {
+                return tree_.insert(val);
+            }
+
+            pair<iterator, bool> insert(value_type&& val)
+            {
+                return tree_.insert(forward<value_type>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val).first;
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val)).first;
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return tree_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return tree_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    first.node(), first.end()
+                };
+            }
+
+            void swap(set& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
+            {
+                tree_.swap(other.tree_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            void clear() noexcept
+            {
+                tree_.clear();
+            }
+
+            key_compare key_comp() const
+            {
+                return tree_.key_comp();
+            }
+
+            value_compare value_comp() const
+            {
+                return tree_.value_comp();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return tree_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            const_iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return tree_.count(key);
+            }
+
+            template<class K>
+            size_type count(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.count(key);
+            }
+
+            iterator lower_bound(const key_type& key)
+            {
+                return tree_.lower_bound(key);
+            }
+
+            const_iterator lower_bound(const key_type& key) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            const_iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            iterator upper_bound(const key_type& key)
+            {
+                return tree_.upper_bound(key);
+            }
+
+            const_iterator upper_bound(const key_type& key) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            const_iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return tree_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<iterator, iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<const_iterator, const_iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.equal_range(key);
+            }
+
+        private:
+            using tree_type = aux::rbtree<
+                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
+                key_compare, allocator_type, size_type,
+                iterator, const_iterator,
+                aux::rbtree_single_policy, node_type
+            >;
+
+            tree_type tree_;
+            allocator_type allocator_;
+
+            template<class K, class C, class A>
+            friend bool operator==(const set<K, C, A>&,
+                                   const set<K, C, A>&);
+    };
+
+    template<class Key, class Compare, class Allocator>
+    bool operator==(const set<Key, Compare, Allocator>& lhs,
+                    const set<Key, Compare, Allocator>& rhs)
+    {
+        return lhs.tree_.is_eq_to(rhs.tree_);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<(const set<Key, Compare, Allocator>& lhs,
+                   const set<Key, Compare, Allocator>& rhs)
+    {
+        return lexicographical_compare(
+            lhs.begin(), lhs.end(),
+            rhs.begin(), rhs.end(),
+            lhs.key_comp()
+        );
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator!=(const set<Key, Compare, Allocator>& lhs,
+                    const set<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>(const set<Key, Compare, Allocator>& lhs,
+                   const set<Key, Compare, Allocator>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>=(const set<Key, Compare, Allocator>& lhs,
+                    const set<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<=(const set<Key, Compare, Allocator>& lhs,
+                    const set<Key, Compare, Allocator>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    /**
+     * 23.4.7, class template multiset:
+     */
+
+    template<
+        class Key,
+        class Compare = less<Key>,
+        class Alloc = allocator<Key>
+    >
+    class multiset
+    {
+        public:
+            using key_type        = Key;
+            using value_type      = Key;
+            using key_compare     = Compare;
+            using value_compare   = Compare;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using node_type = aux::rbtree_multi_node<value_type>;
+
+            /**
+             * Note: Both the iterator and const_iterator types are constant
+             *       iterators, the standard does not require them
+             *       to be the same type, but why not? :)
+             */
+            using iterator             = aux::rbtree_const_iterator<
+                value_type, const_reference, const_pointer, size_type, node_type
+            >;
+            using const_iterator       = iterator;
+
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            multiset()
+                : multiset{key_compare{}}
+            { /* DUMMY BODY */ }
+
+            explicit multiset(const key_compare& comp,
+                              const allocator_type& alloc = allocator_type{})
+                : tree_{comp}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            multiset(InputIterator first, InputIterator last,
+                     const key_compare& comp = key_compare{},
+                     const allocator_type& alloc = allocator_type{})
+                : multiset{comp, alloc}
+            {
+                insert(first, last);
+            }
+
+            multiset(const multiset& other)
+                : multiset{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            multiset(multiset&& other)
+                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit multiset(const allocator_type& alloc)
+                : tree_{}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multiset(const multiset& other, const allocator_type& alloc)
+                : tree_{other.tree_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multiset(multiset&& other, const allocator_type& alloc)
+                : tree_{move(other.tree_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            multiset(initializer_list<value_type> init,
+                     const key_compare& comp = key_compare{},
+                     const allocator_type& alloc = allocator_type{})
+                : multiset{comp, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class InputIterator>
+            multiset(InputIterator first, InputIterator last,
+                     const allocator_type& alloc)
+                : multiset{first, last, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            multiset(initializer_list<value_type> init,
+                     const allocator_type& alloc)
+                : multiset{init, key_compare{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~multiset()
+            { /* DUMMY BODY */ }
+
+            multiset& operator=(const multiset& other)
+            {
+                tree_ = other.tree_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            multiset& operator=(multiset&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<key_compare>::value)
+            {
+                tree_ = move(other.tree_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            multiset& operator=(initializer_list<value_type>& init)
+            {
+                tree_.clear();
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            iterator begin() noexcept
+            {
+                return tree_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return tree_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return tree_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return tree_.end();
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return tree_.rbegin();
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return tree_.rend();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return tree_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return tree_.cend();
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return tree_.crbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return tree_.crend();
+            }
+
+            bool empty() const noexcept
+            {
+                return tree_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return tree_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return tree_.max_size(allocator_);
+            }
+
+            template<class... Args>
+            iterator emplace(Args&&... args)
+            {
+                return tree_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...);
+            }
+
+            iterator insert(const value_type& val)
+            {
+                return tree_.insert(val);
+            }
+
+            iterator insert(value_type&& val)
+            {
+                return tree_.insert(forward<value_type>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val);
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return tree_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return tree_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    first.node(), first.end()
+                };
+            }
+
+            void swap(multiset& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
+            {
+                tree_.swap(other.tree_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            void clear() noexcept
+            {
+                tree_.clear();
+            }
+
+            key_compare key_comp() const
+            {
+                return tree_.key_comp();
+            }
+
+            value_compare value_comp() const
+            {
+                return tree_.value_comp();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return tree_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.find(key);
+            }
+
+            template<class K>
+            const_iterator find(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return tree_.count(key);
+            }
+
+            template<class K>
+            size_type count(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.count(key);
+            }
+
+            iterator lower_bound(const key_type& key)
+            {
+                return tree_.lower_bound(key);
+            }
+
+            const_iterator lower_bound(const key_type& key) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.lower_bound(key);
+            }
+
+            template<class K>
+            const_iterator lower_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.lower_bound(key);
+            }
+
+            iterator upper_bound(const key_type& key)
+            {
+                return tree_.upper_bound(key);
+            }
+
+            const_iterator upper_bound(const key_type& key) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.upper_bound(key);
+            }
+
+            template<class K>
+            const_iterator upper_bound(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.upper_bound(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return tree_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<iterator, iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            )
+            {
+                return tree_.equal_range(key);
+            }
+
+            template<class K>
+            pair<const_iterator, const_iterator> equal_range(
+                const K& key,
+                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
+            ) const
+            {
+                return tree_.equal_range(key);
+            }
+
+        private:
+            using tree_type = aux::rbtree<
+                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
+                key_compare, allocator_type, size_type,
+                iterator, const_iterator,
+                aux::rbtree_multi_policy, node_type
+            >;
+
+            tree_type tree_;
+            allocator_type allocator_;
+
+            template<class K, class C, class A>
+            friend bool operator==(const multiset<K, C, A>&,
+                                   const multiset<K, C, A>&);
+    };
+
+    template<class Key, class Compare, class Allocator>
+    bool operator==(const multiset<Key, Compare, Allocator>& lhs,
+                    const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return lhs.tree_.is_eq_to(rhs.tree_);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<(const multiset<Key, Compare, Allocator>& lhs,
+                   const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return lexicographical_compare(
+            lhs.begin(), lhs.end(),
+            rhs.begin(), rhs.end(),
+            lhs.value_comp()
+        );
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator!=(const multiset<Key, Compare, Allocator>& lhs,
+                    const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>(const multiset<Key, Compare, Allocator>& lhs,
+                   const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator>=(const multiset<Key, Compare, Allocator>& lhs,
+                    const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class Key, class Compare, class Allocator>
+    bool operator<=(const multiset<Key, Compare, Allocator>& lhs,
+                    const multiset<Key, Compare, Allocator>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/stack.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/stack.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/stack.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_STACK
+#define LIBCPP_BITS_ADT_STACK
+
+#include <deque>
+#include <initializer_list>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.5.6.2, stack:
+     */
+
+    template<class T, class Container = deque<T>>
+    class stack
+    {
+        public:
+            using container_type  = Container;
+            using value_type      = typename container_type::value_type;
+            using reference       = typename container_type::reference;
+            using const_reference = typename container_type::const_reference;
+            using size_type       = typename container_type::size_type;
+
+            explicit stack(container_type& cont)
+                : c{cont}
+            { /* DUMMY BODY */ }
+
+            explicit stack(container_type&& cont = container_type{})
+                : c{move(cont)}
+            { /* DUMMY BODY */ }
+
+            /**
+             * TODO: The allocator constructor should use enable_if
+             *       as a last parameter that checks if uses_allocator
+             *       from <memory> holds.
+             */
+            template<class Alloc>
+            explicit stack(Alloc& alloc)
+                : c{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class Alloc>
+            stack(const container_type& cont, const Alloc& alloc)
+                : c{cont, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class Alloc>
+            stack(container_type&& cont, const Alloc& alloc)
+                : c{move(cont), alloc}
+            { /* DUMMY BODY */ }
+
+            template<class Alloc>
+            stack(const stack& other, const Alloc& alloc)
+                : c{other.c, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class Alloc>
+            stack(stack&& other, const Alloc& alloc)
+                : c{move(other.c), alloc}
+            { /* DUMMY BODY */ }
+
+            bool empty()
+            {
+                return c.empty();
+            }
+
+            size_type size()
+            {
+                return c.size();
+            }
+
+            reference top()
+            {
+                return c.back();
+            }
+
+            const_reference top() const
+            {
+                return c.back();
+            }
+
+            void push(const value_type& val)
+            {
+                c.push_back(val);
+            }
+
+            void push(value_type&& val)
+            {
+                c.push_back(move(val));
+            }
+
+            template<class... Args>
+            void emplace(Args&&... args)
+            {
+                c.emplace_back(forward<Args>(args)...);
+            }
+
+            void pop()
+            {
+                c.pop_back();
+            }
+
+            void swap(stack& other) // We cannot use c in the noexcept :/
+                noexcept(noexcept(declval<container_type>().swap(declval<container_type&>())))
+            {
+                std::swap(c, other.c);
+            }
+
+        protected:
+            container_type c;
+    };
+
+    /**
+     * 23.6.5.5, stack operators:
+     */
+
+    template<class T, class Container>
+    bool operator==(const stack<T, Container>& lhs,
+                    const stack<T, Container>& rhs)
+    {
+        return lhs.c == rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator!=(const stack<T, Container>& lhs,
+                    const stack<T, Container>& rhs)
+    {
+        return lhs.c != rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator<(const stack<T, Container>& lhs,
+                   const stack<T, Container>& rhs)
+    {
+        return lhs.c < rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator<=(const stack<T, Container>& lhs,
+                    const stack<T, Container>& rhs)
+    {
+        return lhs.c <= rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator>(const stack<T, Container>& lhs,
+                   const stack<T, Container>& rhs)
+    {
+        return lhs.c > rhs.c;
+    }
+
+    template<class T, class Container>
+    bool operator>=(const stack<T, Container>& lhs,
+                    const stack<T, Container>& rhs)
+    {
+        return lhs.c >= rhs.c;
+    }
+
+    /**
+     * 23.6.5.6, stack specialized algorithms:
+     */
+
+    template<class T, class Container>
+    void swap(stack<T, Container>& lhs, stack<T, Container>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/unordered_map.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/unordered_map.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/unordered_map.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1193 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_UNORDERED_MAP
+#define LIBCPP_BITS_ADT_UNORDERED_MAP
+
+#include <__bits/adt/hash_table.hpp>
+#include <initializer_list>
+#include <functional>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.5.4, class template unordered_map:
+     */
+
+    template<
+        class Key, class Value,
+        class Hash = hash<Key>,
+        class Pred = equal_to<Key>,
+        class Alloc = allocator<pair<const Key, Value>>
+    >
+    class unordered_map
+    {
+        public:
+            using key_type        = Key;
+            using mapped_type     = Value;
+            using value_type      = pair<const key_type, mapped_type>;
+            using hasher          = Hash;
+            using key_equal       = Pred;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using iterator             = aux::hash_table_iterator<
+                value_type, reference, pointer, size_type
+            >;
+            using const_iterator       = aux::hash_table_const_iterator<
+                value_type, const_reference, const_pointer, size_type
+            >;
+            using local_iterator       = aux::hash_table_local_iterator<
+                value_type, reference, pointer
+            >;
+            using const_local_iterator = aux::hash_table_const_local_iterator<
+                value_type, const_reference, const_pointer
+            >;
+
+            unordered_map()
+                : unordered_map{default_bucket_count_}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_map(size_type bucket_count,
+                                   const hasher& hf = hasher{},
+                                   const key_equal& eql = key_equal{},
+                                   const allocator_type& alloc = allocator_type{})
+                : table_{bucket_count, hf, eql}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_map(InputIterator first, InputIterator last,
+                          size_type bucket_count = default_bucket_count_,
+                          const hasher& hf = hasher{},
+                          const key_equal& eql = key_equal{},
+                          const allocator_type& alloc = allocator_type{})
+                : unordered_map{bucket_count, hf, eql, alloc}
+            {
+                insert(first, last);
+            }
+
+            unordered_map(const unordered_map& other)
+                : unordered_map{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            unordered_map(unordered_map&& other)
+                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_map(const allocator_type& alloc)
+                : table_{default_bucket_count_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(const unordered_map& other, const allocator_type& alloc)
+                : table_{other.table_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(unordered_map&& other, const allocator_type& alloc)
+                : table_{move(other.table_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(initializer_list<value_type> init,
+                          size_type bucket_count = default_bucket_count_,
+                          const hasher& hf = hasher{},
+                          const key_equal& eql = key_equal{},
+                          const allocator_type& alloc = allocator_type{})
+                : unordered_map{bucket_count, hf, eql, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            unordered_map(size_type bucket_count, const allocator_type& alloc)
+                : unordered_map{bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_map{bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_map(InputIterator first, InputIterator last,
+                          size_type bucket_count, const allocator_type& alloc)
+                : unordered_map{first, last, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_map(InputIterator first, InputIterator last,
+                          size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_map{first, last, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(initializer_list<value_type> init, size_type bucket_count,
+                          const allocator_type& alloc)
+                : unordered_map{init, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_map(initializer_list<value_type> init, size_type bucket_count,
+                          const hasher& hf, const allocator_type& alloc)
+                : unordered_map{init, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~unordered_map()
+            { /* DUMMY BODY */ }
+
+            unordered_map& operator=(const unordered_map& other)
+            {
+                table_ = other.table_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            unordered_map& operator=(unordered_map&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<hasher>::value &&
+                         is_nothrow_move_assignable<key_equal>::value)
+            {
+                table_ = move(other.table_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            unordered_map& operator=(initializer_list<value_type>& init)
+            {
+                table_.clear();
+                table_.reserve(init.size());
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            bool empty() const noexcept
+            {
+                return table_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return table_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return table_.max_size(allocator_);
+            }
+
+            iterator begin() noexcept
+            {
+                return table_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return table_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return table_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return table_.cend();
+            }
+
+            template<class... Args>
+            pair<iterator, bool> emplace(Args&&... args)
+            {
+                return table_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...).first;
+            }
+
+            pair<iterator, bool> insert(const value_type& val)
+            {
+                return table_.insert(val);
+            }
+
+            pair<iterator, bool> insert(value_type&& val)
+            {
+                return table_.insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            pair<iterator, bool> insert(
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace(forward<T>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val).first;
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val)).first;
+            }
+
+            template<class T>
+            iterator insert(
+                const_iterator hint,
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace_hint(hint, forward<T>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            template<class... Args>
+            pair<iterator, bool> try_emplace(const key_type& key, Args&&... args)
+            {
+                /**
+                 * Note: If anyone (like me) wonders what is the difference between
+                 *       emplace and try_emplace, the former always constructs the value
+                 *       (in order to get the key) and the latter does it only if
+                 *       an insertion takes place.
+                 */
+
+                table_.increment_size();
+
+                auto [bucket, target, idx] = table_.find_insertion_spot(key);
+
+                if (!bucket)
+                    return make_pair(end(), false);
+
+                if (target && table_.keys_equal(key, target->value))
+                {
+                    table_.decrement_size();
+
+                    return make_pair(
+                        iterator{
+                            table_.table(), idx, table_.bucket_count(),
+                            target
+                        },
+                        false
+                    );
+                }
+                else
+                {
+                    auto node = new node_type{key, forward<Args>(args)...};
+                    bucket->append(node);
+
+                    return make_pair(iterator{
+                        table_.table(), idx,
+                        table_.bucket_count(),
+                        node
+                    }, true);
+                }
+            }
+
+            template<class... Args>
+            pair<iterator, bool> try_emplace(key_type&& key, Args&&... args)
+            {
+                table_.increment_size();
+
+                auto [bucket, target, idx] = table_.find_insertion_spot(key);
+
+                if (!bucket)
+                    return make_pair(end(), false);
+
+                if (target && table_.keys_equal(key, target->value))
+                {
+                    table_.decrement_size();
+
+                    return make_pair(
+                        iterator{
+                            table_.table(), idx, table_.bucket_count(),
+                            target
+                        },
+                        false
+                    );
+                }
+                else
+                {
+                    auto node = new node_type{move(key), forward<Args>(args)...};
+                    bucket->append(node);
+
+                    return make_pair(iterator{
+                        table_.table(), idx,
+                        table_.bucket_count(),
+                        node
+                    }, true);
+                }
+            }
+
+            template<class... Args>
+            iterator try_emplace(const_iterator, const key_type& key, Args&&... args)
+            {
+                return try_emplace(key, forward<Args>(args)...).first;
+            }
+
+            template<class... Args>
+            iterator try_emplace(const_iterator, key_type&& key, Args&&... args)
+            {
+                return try_emplace(move(key), forward<Args>(args)...).first;
+            }
+
+            template<class T>
+            pair<iterator, bool> insert_or_assign(const key_type& key, T&& val)
+            {
+                table_.increment_size();
+
+                auto [bucket, target, idx] = table_.find_insertion_spot(key);
+
+                if (!bucket)
+                    return make_pair(end(), false);
+
+                if (target && table_.keys_equal(key, target->value))
+                {
+                    table_.decrement_size();
+                    target->value.second = forward<T>(val);
+
+                    return make_pair(
+                        iterator{
+                            table_.table(), idx, table_.bucket_count(),
+                            target
+                        },
+                        false
+                    );
+                }
+                else
+                {
+                    auto node = new node_type{key, forward<T>(val)};
+                    bucket->append(node);
+
+                    return make_pair(iterator{
+                        table_.table(), idx,
+                        table_.bucket_count(),
+                        node
+                    }, true);
+                }
+            }
+
+            template<class T>
+            pair<iterator, bool> insert_or_assign(key_type&& key, T&& val)
+            {
+                table_.increment_size();
+
+                auto [bucket, target, idx] = table_.find_insertion_spot(key);
+
+                if (!bucket)
+                    return make_pair(end(), false);
+
+                if (target && table_.keys_equal(key, target->value))
+                {
+                    table_.decrement_size();
+                    target->value.second = forward<T>(val);
+
+                    return make_pair(
+                        iterator{
+                            table_.table(), idx, table_.bucket_count(),
+                            target
+                        },
+                        false
+                    );
+                }
+                else
+                {
+                    auto node = new node_type{move(key), forward<T>(val)};
+                    bucket->append(node);
+
+                    return make_pair(iterator{
+                        table_.table(), idx,
+                        table_.bucket_count(),
+                        node
+                    }, true);
+                }
+            }
+
+            template<class T>
+            iterator insert_or_assign(const_iterator, const key_type& key, T&& val)
+            {
+                return insert_or_assign(key, forward<T>(val)).first;
+            }
+
+            template<class T>
+            iterator insert_or_assign(const_iterator, key_type&& key, T&& val)
+            {
+                return insert_or_assign(move(key), forward<T>(val)).first;
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return table_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return table_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    table_.table(), first.idx(),
+                    table_.bucket_count(), table_.head(first.idx())
+                };
+            }
+
+            void clear() noexcept
+            {
+                table_.clear();
+            }
+
+            void swap(unordered_map& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
+                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
+            {
+                table_.swap(other.table_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            hasher hash_function() const
+            {
+                return table_.hash_function();
+            }
+
+            key_equal key_eq() const
+            {
+                return table_.key_eq();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return table_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return table_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return table_.count(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return table_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return table_.equal_range(key);
+            }
+
+            mapped_type& operator[](const key_type& key)
+            {
+                auto spot = table_.find_insertion_spot(key);
+                auto bucket = get<0>(spot);
+
+                if (bucket->head)
+                {
+                    auto head = bucket->head;
+                    auto current = bucket->head;
+
+                    do
+                    {
+                        if (table_.keys_equal(key, current->value))
+                            return current->value.second;
+                        else
+                            current = current->next;
+                    }
+                    while (current != head);
+                }
+
+                auto node = new node_type{key, mapped_type{}};
+                bucket->append(node);
+
+                table_.increment_size();
+                table_.rehash_if_needed();
+                return node->value.second;
+            }
+
+            mapped_type& operator[](key_type&& key)
+            {
+                auto spot = table_.find_insertion_spot(key);
+                auto bucket = get<0>(spot);
+
+                if (bucket->head)
+                {
+                    auto head = bucket->head;
+                    auto current = bucket->head;
+
+                    do
+                    {
+                        if (table_.keys_equal(key, current->value))
+                            return current->value.second;
+                        else
+                            current = current->next;
+                    }
+                    while (current != head);
+                }
+
+                auto node = new node_type{move(key), mapped_type{}};
+                bucket->append(node);
+
+                table_.increment_size();
+                table_.rehash_if_needed();
+                return node->value.second;
+            }
+
+            mapped_type& at(const key_type& key)
+            {
+                auto it = find(key);
+
+                // TODO: throw out_of_range if it == end()
+                return it->second;
+            }
+
+            const mapped_type& at(const key_type& key) const
+            {
+                auto it = find(key);
+
+                // TODO: throw out_of_range if it == end()
+                return it->second;
+            }
+
+            size_type bucket_count() const noexcept
+            {
+                return table_.bucket_count();
+            }
+
+            size_type max_bucket_count() const noexcept
+            {
+                return table_.max_bucket_count();
+            }
+
+            size_type bucket_size(size_type idx) const
+            {
+                return table_.bucket_size(idx);
+            }
+
+            size_type bucket(const key_type& key) const
+            {
+                return table_.bucket(key);
+            }
+
+            local_iterator begin(size_type idx)
+            {
+                return table_.begin(idx);
+            }
+
+            const_local_iterator begin(size_type idx) const
+            {
+                return table_.begin(idx);
+            }
+
+            local_iterator end(size_type idx)
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator end(size_type idx) const
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator cbegin(size_type idx) const
+            {
+                return table_.cbegin(idx);
+            }
+
+            const_local_iterator cend(size_type idx) const
+            {
+                return table_.cend(idx);
+            }
+
+            float load_factor() const noexcept
+            {
+                return table_.load_factor();
+            }
+
+            float max_load_factor() const noexcept
+            {
+                return table_.max_load_factor();
+            }
+
+            void max_load_factor(float factor)
+            {
+                table_.max_load_factor(factor);
+            }
+
+            void rehash(size_type bucket_count)
+            {
+                table_.rehash(bucket_count);
+            }
+
+            void reserve(size_type count)
+            {
+                table_.reserve(count);
+            }
+
+        private:
+            using table_type = aux::hash_table<
+                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
+                hasher, key_equal, allocator_type, size_type,
+                iterator, const_iterator, local_iterator, const_local_iterator,
+                aux::hash_single_policy
+            >;
+            using node_type = typename table_type::node_type;
+
+            table_type table_;
+            allocator_type allocator_;
+
+            static constexpr size_type default_bucket_count_{16};
+
+            template<class K, class V, class H, class P, class A>
+            friend bool operator==(unordered_map<K, V, H, P, A>&,
+                                   unordered_map<K, V, H, P, A>&);
+    };
+
+    /**
+     * 23.5.5, class template unordered_multimap:
+     */
+
+    template<
+        class Key, class Value,
+        class Hash = hash<Key>,
+        class Pred = equal_to<Key>,
+        class Alloc = allocator<pair<const Key, Value>>
+    >
+    class unordered_multimap
+    {
+        public:
+            using key_type        = Key;
+            using mapped_type     = Value;
+            using value_type      = pair<const key_type, mapped_type>;
+            using hasher          = Hash;
+            using key_equal       = Pred;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            using iterator             = aux::hash_table_iterator<
+                value_type, reference, pointer, size_type
+            >;
+            using const_iterator       = aux::hash_table_const_iterator<
+                value_type, const_reference, const_pointer, size_type
+            >;
+            using local_iterator       = aux::hash_table_local_iterator<
+                value_type, reference, pointer
+            >;
+            using const_local_iterator = aux::hash_table_const_local_iterator<
+                value_type, const_reference, const_pointer
+            >;
+
+            unordered_multimap()
+                : unordered_multimap{default_bucket_count_}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_multimap(size_type bucket_count,
+                                        const hasher& hf = hasher{},
+                                        const key_equal& eql = key_equal{},
+                                        const allocator_type& alloc = allocator_type{})
+                : table_{bucket_count, hf, eql}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multimap(InputIterator first, InputIterator last,
+                               size_type bucket_count = default_bucket_count_,
+                               const hasher& hf = hasher{},
+                               const key_equal& eql = key_equal{},
+                               const allocator_type& alloc = allocator_type{})
+                : unordered_multimap{bucket_count, hf, eql, alloc}
+            {
+                insert(first, last);
+            }
+
+            unordered_multimap(const unordered_multimap& other)
+                : unordered_multimap{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(unordered_multimap&& other)
+                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_multimap(const allocator_type& alloc)
+                : table_{default_bucket_count_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(const unordered_multimap& other, const allocator_type& alloc)
+                : table_{other.table_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(unordered_multimap&& other, const allocator_type& alloc)
+                : table_{move(other.table_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(initializer_list<value_type> init,
+                               size_type bucket_count = default_bucket_count_,
+                               const hasher& hf = hasher{},
+                               const key_equal& eql = key_equal{},
+                               const allocator_type& alloc = allocator_type{})
+                : unordered_multimap{bucket_count, hf, eql, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            unordered_multimap(size_type bucket_count, const allocator_type& alloc)
+                : unordered_multimap{bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(size_type bucket_count, const hasher& hf,
+                               const allocator_type& alloc)
+                : unordered_multimap{bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multimap(InputIterator first, InputIterator last,
+                               size_type bucket_count, const allocator_type& alloc)
+                : unordered_multimap{first, last, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multimap(InputIterator first, InputIterator last,
+                               size_type bucket_count, const hasher& hf,
+                               const allocator_type& alloc)
+                : unordered_multimap{first, last, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(initializer_list<value_type> init, size_type bucket_count,
+                               const allocator_type& alloc)
+                : unordered_multimap{init, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multimap(initializer_list<value_type> init, size_type bucket_count,
+                               const hasher& hf, const allocator_type& alloc)
+                : unordered_multimap{init, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~unordered_multimap()
+            { /* DUMMY BODY */ }
+
+            unordered_multimap& operator=(const unordered_multimap& other)
+            {
+                table_ = other.table_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            unordered_multimap& operator=(unordered_multimap&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<hasher>::value &&
+                         is_nothrow_move_assignable<key_equal>::value)
+            {
+                table_ = move(other.table_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            unordered_multimap& operator=(initializer_list<value_type>& init)
+            {
+                table_.clear();
+                table_.reserve(init.size());
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            bool empty() const noexcept
+            {
+                return table_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return table_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return table_.max_size(allocator_);
+            }
+
+            iterator begin() noexcept
+            {
+                return table_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return table_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return table_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return table_.cend();
+            }
+
+            template<class... Args>
+            iterator emplace(Args&&... args)
+            {
+                return table_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...);
+            }
+
+            iterator insert(const value_type& val)
+            {
+                return table_.insert(val);
+            }
+
+            iterator insert(value_type&& val)
+            {
+                return table_.insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            iterator insert(
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace(forward<T>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val);
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val));
+            }
+
+            template<class T>
+            iterator insert(
+                const_iterator hint,
+                T&& val,
+                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
+            )
+            {
+                return emplace_hint(hint, forward<T>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return table_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return table_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    table_.table(), first.idx(),
+                    table_.bucket_count(), table_.head(first.idx())
+                };
+            }
+
+            void clear() noexcept
+            {
+                table_.clear();
+            }
+
+            void swap(unordered_multimap& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
+                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
+            {
+                table_.swap(other.table_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            hasher hash_function() const
+            {
+                return table_.hash_function();
+            }
+
+            key_equal key_eq() const
+            {
+                return table_.key_eq();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return table_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return table_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return table_.count(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return table_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return table_.equal_range(key);
+            }
+
+            size_type bucket_count() const noexcept
+            {
+                return table_.bucket_count();
+            }
+
+            size_type max_bucket_count() const noexcept
+            {
+                return table_.max_bucket_count();
+            }
+
+            size_type bucket_size(size_type idx) const
+            {
+                return table_.bucket_size(idx);
+            }
+
+            size_type bucket(const key_type& key) const
+            {
+                return table_.bucket(key);
+            }
+
+            local_iterator begin(size_type idx)
+            {
+                return table_.begin(idx);
+            }
+
+            const_local_iterator begin(size_type idx) const
+            {
+                return table_.begin(idx);
+            }
+
+            local_iterator end(size_type idx)
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator end(size_type idx) const
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator cbegin(size_type idx) const
+            {
+                return table_.cbegin(idx);
+            }
+
+            const_local_iterator cend(size_type idx) const
+            {
+                return table_.cend(idx);
+            }
+
+            float load_factor() const noexcept
+            {
+                return table_.load_factor();
+            }
+
+            float max_load_factor() const noexcept
+            {
+                return table_.max_load_factor();
+            }
+
+            void max_load_factor(float factor)
+            {
+                table_.max_load_factor(factor);
+            }
+
+            void rehash(size_type bucket_count)
+            {
+                table_.rehash(bucket_count);
+            }
+
+            void reserve(size_type count)
+            {
+                table_.reserve(count);
+            }
+
+        private:
+            using table_type = aux::hash_table<
+                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
+                hasher, key_equal, allocator_type, size_type,
+                iterator, const_iterator, local_iterator, const_local_iterator,
+                aux::hash_multi_policy
+            >;
+
+            table_type table_;
+            allocator_type allocator_;
+
+            static constexpr size_type default_bucket_count_{16};
+
+            template<class K, class V, class H, class P, class A>
+            friend bool operator==(unordered_multimap<K, V, H, P, A>&,
+                                   unordered_multimap<K, V, H, P, A>&);
+    };
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    void swap(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
+              unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    void swap(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
+              unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    bool operator==(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
+                    unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
+    {
+        // TODO: this does not compare values, use is_permutation when we have it
+        return lhs.table_.is_eq_to(rhs.table_);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    bool operator!=(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
+                    unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    bool operator==(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
+                    unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
+    {
+        return lhs.table_.is_eq_to(rhs.table_);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    bool operator!=(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
+                    unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/unordered_set.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/unordered_set.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/unordered_set.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_UNORDERED_SET
+#define LIBCPP_BITS_ADT_UNORDERED_SET
+
+#include <__bits/adt/hash_table.hpp>
+#include <initializer_list>
+#include <functional>
+#include <memory>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.5.6, class template unordered_set:
+     */
+
+    template<
+        class Key,
+        class Hash = hash<Key>,
+        class Pred = equal_to<Key>,
+        class Alloc = allocator<Key>
+    >
+    class unordered_set
+    {
+        public:
+            using key_type        = Key;
+            using value_type      = Key;
+            using hasher          = Hash;
+            using key_equal       = Pred;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            /**
+             * Note: Both the iterator and const_iterator (and their local variants)
+             *       types are constant iterators, the standard does not require them
+             *       to be the same type, but why not? :)
+             */
+            using iterator             = aux::hash_table_const_iterator<
+                value_type, const_reference, const_pointer, size_type
+            >;
+            using const_iterator       = iterator;
+            using local_iterator       = aux::hash_table_const_local_iterator<
+                value_type, const_reference, const_pointer
+            >;
+            using const_local_iterator = local_iterator;
+
+            /**
+             * Note: We need () to delegate the constructor,
+             *       otherwise it could be deduced as the initializer
+             *       list constructor when size_type is convertible
+             *       to value_type.
+             */
+            unordered_set()
+                : unordered_set(default_bucket_count_)
+            { /* DUMMY BODY */ }
+
+            explicit unordered_set(size_type bucket_count,
+                                   const hasher& hf = hasher{},
+                                   const key_equal& eql = key_equal{},
+                                   const allocator_type& alloc = allocator_type{})
+                : table_{bucket_count, hf, eql}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_set(InputIterator first, InputIterator last,
+                          size_type bucket_count = default_bucket_count_,
+                          const hasher& hf = hasher{},
+                          const key_equal& eql = key_equal{},
+                          const allocator_type& alloc = allocator_type{})
+                : unordered_set{bucket_count, hf, eql, alloc}
+            {
+                insert(first, last);
+            }
+
+            unordered_set(const unordered_set& other)
+                : unordered_set{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            unordered_set(unordered_set&& other)
+                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_set(const allocator_type& alloc)
+                : table_{default_bucket_count_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(const unordered_set& other, const allocator_type& alloc)
+                : table_{other.table_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(unordered_set&& other, const allocator_type& alloc)
+                : table_{move(other.table_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(initializer_list<value_type> init,
+                          size_type bucket_count = default_bucket_count_,
+                          const hasher& hf = hasher{},
+                          const key_equal& eql = key_equal{},
+                          const allocator_type& alloc = allocator_type{})
+                : unordered_set{bucket_count, hf, eql, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            unordered_set(size_type bucket_count, const allocator_type& alloc)
+                : unordered_set{bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_set{bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_set(InputIterator first, InputIterator last,
+                          size_type bucket_count, const allocator_type& alloc)
+                : unordered_set{first, last, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_set(InputIterator first, InputIterator last,
+                          size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_set{first, last, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(initializer_list<value_type> init, size_type bucket_count,
+                          const allocator_type& alloc)
+                : unordered_set{init, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_set(initializer_list<value_type> init, size_type bucket_count,
+                          const hasher& hf, const allocator_type& alloc)
+                : unordered_set{init, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~unordered_set()
+            { /* DUMMY BODY */ }
+
+            unordered_set& operator=(const unordered_set& other)
+            {
+                table_ = other.table_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            unordered_set& operator=(unordered_set&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<hasher>::value &&
+                         is_nothrow_move_assignable<key_equal>::value)
+            {
+                table_ = move(other.table_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            unordered_set& operator=(initializer_list<value_type>& init)
+            {
+                table_.clear();
+                table_.reserve(init.size());
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            bool empty() const noexcept
+            {
+                return table_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return table_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return table_.max_size(allocator_);
+            }
+
+            iterator begin() noexcept
+            {
+                return table_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return table_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return table_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return table_.cend();
+            }
+
+            template<class... Args>
+            pair<iterator, bool> emplace(Args&&... args)
+            {
+                return table_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...).first;
+            }
+
+            pair<iterator, bool> insert(const value_type& val)
+            {
+                return table_.insert(val);
+            }
+
+            pair<iterator, bool> insert(value_type&& val)
+            {
+                return table_.insert(forward<value_type>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val).first;
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val)).first;
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return table_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return table_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    table_.table(), first.idx(),
+                    table_.bucket_count(), first.node()
+                };
+            }
+
+            void clear() noexcept
+            {
+                table_.clear();
+            }
+
+            void swap(unordered_set& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
+                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
+            {
+                table_.swap(other.table_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            hasher hash_function() const
+            {
+                return table_.hash_function();
+            }
+
+            key_equal key_eq() const
+            {
+                return table_.key_eq();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return table_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return table_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return table_.count(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return table_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return table_.equal_range(key);
+            }
+
+            size_type bucket_count() const noexcept
+            {
+                return table_.bucket_count();
+            }
+
+            size_type max_bucket_count() const noexcept
+            {
+                return table_.max_bucket_count();
+            }
+
+            size_type bucket_size(size_type idx) const
+            {
+                return table_.bucket_size(idx);
+            }
+
+            size_type bucket(const key_type& key) const
+            {
+                return table_.bucket(key);
+            }
+
+            local_iterator begin(size_type idx)
+            {
+                return table_.begin(idx);
+            }
+
+            const_local_iterator begin(size_type idx) const
+            {
+                return table_.begin(idx);
+            }
+
+            local_iterator end(size_type idx)
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator end(size_type idx) const
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator cbegin(size_type idx) const
+            {
+                return table_.cbegin(idx);
+            }
+
+            const_local_iterator cend(size_type idx) const
+            {
+                return table_.cend(idx);
+            }
+
+            float load_factor() const noexcept
+            {
+                return table_.load_factor();
+            }
+
+            float max_load_factor() const noexcept
+            {
+                return table_.max_load_factor();
+            }
+
+            void max_load_factor(float factor)
+            {
+                table_.max_load_factor(factor);
+            }
+
+            void rehash(size_type bucket_count)
+            {
+                table_.rehash(bucket_count);
+            }
+
+            void reserve(size_type count)
+            {
+                table_.reserve(count);
+            }
+
+        private:
+            using table_type = aux::hash_table<
+                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
+                hasher, key_equal, allocator_type, size_type,
+                iterator, const_iterator, local_iterator, const_local_iterator,
+                aux::hash_single_policy
+            >;
+
+            table_type table_;
+            allocator_type allocator_;
+
+            static constexpr size_type default_bucket_count_{16};
+
+            template<class K, class H, class P, class A>
+            friend bool operator==(const unordered_set<K, H, P, A>&,
+                                   const unordered_set<K, H, P, A>&);
+    };
+
+    /**
+     * 23.5.7, class template unordered_multiset:
+     */
+
+    template<
+        class Key,
+        class Hash = hash<Key>,
+        class Pred = equal_to<Key>,
+        class Alloc = allocator<Key>
+    >
+    class unordered_multiset
+    {
+        public:
+            using key_type        = Key;
+            using value_type      = Key;
+            using hasher          = Hash;
+            using key_equal       = Pred;
+            using allocator_type  = Alloc;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using size_type       = size_t;
+            using difference_type = ptrdiff_t;
+
+            /**
+             * Note: Both the iterator and const_iterator (and their local variants)
+             *       types are constant iterators, the standard does not require them
+             *       to be the same type, but why not? :)
+             */
+            using iterator             = aux::hash_table_const_iterator<
+                value_type, const_reference, const_pointer, size_type
+            >;
+            using const_iterator       = iterator;
+            using local_iterator       = aux::hash_table_const_local_iterator<
+                value_type, const_reference, const_pointer
+            >;
+            using const_local_iterator = local_iterator;
+
+            /**
+             * Note: We need () to delegate the constructor,
+             *       otherwise it could be deduced as the initializer
+             *       list constructor when size_type is convertible
+             *       to value_type.
+             */
+            unordered_multiset()
+                : unordered_multiset(default_bucket_count_)
+            { /* DUMMY BODY */ }
+
+            explicit unordered_multiset(size_type bucket_count,
+                                        const hasher& hf = hasher{},
+                                        const key_equal& eql = key_equal{},
+                                        const allocator_type& alloc = allocator_type{})
+                : table_{bucket_count, hf, eql}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multiset(InputIterator first, InputIterator last,
+                               size_type bucket_count = default_bucket_count_,
+                               const hasher& hf = hasher{},
+                               const key_equal& eql = key_equal{},
+                               const allocator_type& alloc = allocator_type{})
+                : unordered_multiset{bucket_count, hf, eql, alloc}
+            {
+                insert(first, last);
+            }
+
+            unordered_multiset(const unordered_multiset& other)
+                : unordered_multiset{other, other.allocator_}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(unordered_multiset&& other)
+                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
+            { /* DUMMY BODY */ }
+
+            explicit unordered_multiset(const allocator_type& alloc)
+                : table_{default_bucket_count_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(const unordered_multiset& other, const allocator_type& alloc)
+                : table_{other.table_}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(unordered_multiset&& other, const allocator_type& alloc)
+                : table_{move(other.table_)}, allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(initializer_list<value_type> init,
+                               size_type bucket_count = default_bucket_count_,
+                               const hasher& hf = hasher{},
+                               const key_equal& eql = key_equal{},
+                               const allocator_type& alloc = allocator_type{})
+                : unordered_multiset{bucket_count, hf, eql, alloc}
+            {
+                insert(init.begin(), init.end());
+            }
+
+            unordered_multiset(size_type bucket_count, const allocator_type& alloc)
+                : unordered_multiset{bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_multiset{bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multiset(InputIterator first, InputIterator last,
+                               size_type bucket_count, const allocator_type& alloc)
+                : unordered_multiset{first, last, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            unordered_multiset(InputIterator first, InputIterator last,
+                               size_type bucket_count, const hasher& hf, const allocator_type& alloc)
+                : unordered_multiset{first, last, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
+                               const allocator_type& alloc)
+                : unordered_multiset{init, bucket_count, hasher{}, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
+                               const hasher& hf, const allocator_type& alloc)
+                : unordered_multiset{init, bucket_count, hf, key_equal{}, alloc}
+            { /* DUMMY BODY */ }
+
+            ~unordered_multiset()
+            { /* DUMMY BODY */ }
+
+            unordered_multiset& operator=(const unordered_multiset& other)
+            {
+                table_ = other.table_;
+                allocator_ = other.allocator_;
+
+                return *this;
+            }
+
+            unordered_multiset& operator=(unordered_multiset&& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         is_nothrow_move_assignable<hasher>::value &&
+                         is_nothrow_move_assignable<key_equal>::value)
+            {
+                table_ = move(other.table_);
+                allocator_ = move(other.allocator_);
+
+                return *this;
+            }
+
+            unordered_multiset& operator=(initializer_list<value_type>& init)
+            {
+                table_.clear();
+                table_.reserve(init.size());
+
+                insert(init.begin(), init.end());
+
+                return *this;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_;
+            }
+
+            bool empty() const noexcept
+            {
+                return table_.empty();
+            }
+
+            size_type size() const noexcept
+            {
+                return table_.size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return table_.max_size(allocator_);
+            }
+
+            iterator begin() noexcept
+            {
+                return table_.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return table_.begin();
+            }
+
+            iterator end() noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator end() const noexcept
+            {
+                return table_.end();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return table_.cbegin();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return table_.cend();
+            }
+
+            template<class... Args>
+            iterator emplace(Args&&... args)
+            {
+                return table_.emplace(forward<Args>(args)...);
+            }
+
+            template<class... Args>
+            iterator emplace_hint(const_iterator, Args&&... args)
+            {
+                return emplace(forward<Args>(args)...);
+            }
+
+            iterator insert(const value_type& val)
+            {
+                return table_.insert(val);
+            }
+
+            iterator insert(value_type&& val)
+            {
+                return table_.insert(forward<value_type>(val));
+            }
+
+            iterator insert(const_iterator, const value_type& val)
+            {
+                return insert(val);
+            }
+
+            iterator insert(const_iterator, value_type&& val)
+            {
+                return insert(forward<value_type>(val));
+            }
+
+            template<class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+            {
+                while (first != last)
+                    insert(*first++);
+            }
+
+            void insert(initializer_list<value_type> init)
+            {
+                insert(init.begin(), init.end());
+            }
+
+            iterator erase(const_iterator position)
+            {
+                return table_.erase(position);
+            }
+
+            size_type erase(const key_type& key)
+            {
+                return table_.erase(key);
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                while (first != last)
+                    first = erase(first);
+
+                return iterator{
+                    table_.table(), first.idx(),
+                    table_.bucket_count(), table_.head(first.idx())
+                };
+            }
+
+            void clear() noexcept
+            {
+                table_.clear();
+            }
+
+            void swap(unordered_multiset& other)
+                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
+                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
+            {
+                table_.swap(other.table_);
+                std::swap(allocator_, other.allocator_);
+            }
+
+            hasher hash_function() const
+            {
+                return table_.hash_function();
+            }
+
+            key_equal key_eq() const
+            {
+                return table_.key_eq();
+            }
+
+            iterator find(const key_type& key)
+            {
+                return table_.find(key);
+            }
+
+            const_iterator find(const key_type& key) const
+            {
+                return table_.find(key);
+            }
+
+            size_type count(const key_type& key) const
+            {
+                return table_.count(key);
+            }
+
+            pair<iterator, iterator> equal_range(const key_type& key)
+            {
+                return table_.equal_range(key);
+            }
+
+            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+            {
+                return table_.equal_range(key);
+            }
+
+            size_type bucket_count() const noexcept
+            {
+                return table_.bucket_count();
+            }
+
+            size_type max_bucket_count() const noexcept
+            {
+                return table_.max_bucket_count();
+            }
+
+            size_type bucket_size(size_type idx) const
+            {
+                return table_.bucket_size(idx);
+            }
+
+            size_type bucket(const key_type& key) const
+            {
+                return table_.bucket(key);
+            }
+
+            local_iterator begin(size_type idx)
+            {
+                return table_.begin(idx);
+            }
+
+            const_local_iterator begin(size_type idx) const
+            {
+                return table_.begin(idx);
+            }
+
+            local_iterator end(size_type idx)
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator end(size_type idx) const
+            {
+                return table_.end(idx);
+            }
+
+            const_local_iterator cbegin(size_type idx) const
+            {
+                return table_.cbegin(idx);
+            }
+
+            const_local_iterator cend(size_type idx) const
+            {
+                return table_.cend(idx);
+            }
+
+            float load_factor() const noexcept
+            {
+                return table_.load_factor();
+            }
+
+            float max_load_factor() const noexcept
+            {
+                return table_.max_load_factor();
+            }
+
+            void max_load_factor(float factor)
+            {
+                table_.max_load_factor(factor);
+            }
+
+            void rehash(size_type bucket_count)
+            {
+                table_.rehash(bucket_count);
+            }
+
+            void reserve(size_type count)
+            {
+                table_.reserve(count);
+            }
+
+        private:
+            using table_type = aux::hash_table<
+                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
+                hasher, key_equal, allocator_type, size_type,
+                iterator, const_iterator, local_iterator, const_local_iterator,
+                aux::hash_multi_policy
+            >;
+
+            table_type table_;
+            allocator_type allocator_;
+
+            static constexpr size_type default_bucket_count_{16};
+
+            template<class K, class H, class P, class A>
+            friend bool operator==(const unordered_multiset<K, H, P, A>&,
+                                   const unordered_multiset<K, H, P, A>&);
+    };
+
+    template<class Key, class Hash, class Pred, class Alloc>
+    void swap(unordered_set<Key, Hash, Pred, Alloc>& lhs,
+              unordered_set<Key, Hash, Pred, Alloc>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class Key, class Hash, class Pred, class Alloc>
+    void swap(unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
+              unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class Key, class Hash, class Pred, class Alloc>
+    bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& lhs,
+                    const unordered_set<Key, Hash, Pred, Alloc>& rhs)
+    {
+        return lhs.table_.is_eq_to(rhs.table_);
+    }
+
+    template<class Key, class Hash, class Pred, class Alloc>
+    bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& lhs,
+                    const unordered_set<Key, Hash, Pred, Alloc>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Key, class Hash, class Pred, class Alloc>
+    bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
+                    const unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
+    {
+        return lhs.table_.is_eq_to(rhs.table_);
+    }
+
+    template<class Key, class Value, class Hash, class Pred, class Alloc>
+    bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
+                    const unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/valarray.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/valarray.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/valarray.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_VALARRAY
+#define LIBCPP_BITS_ADT_VALARRAY
+
+#error "<valarray> is not implemented"
+
+#endif
Index: uspace/lib/cpp/include/__bits/adt/vector.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/vector.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/adt/vector.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ADT_VECTOR
+#define LIBCPP_BITS_ADT_VECTOR
+
+#include <algorithm>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 23.3.6, vector:
+     */
+
+    template<class T, class Allocator = allocator<T>>
+    class vector
+    {
+        public:
+            using value_type             = T;
+            using reference              = value_type&;
+            using const_reference        = const value_type&;
+            using allocator_type         = Allocator;
+            using size_type              = size_t;
+            using difference_type        = ptrdiff_t;
+            using pointer                = typename allocator_traits<Allocator>::pointer;
+            using const_pointer          = typename allocator_traits<Allocator>::pointer;
+            using iterator               = pointer;
+            using const_iterator         = const_pointer;
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            vector() noexcept
+                : vector{Allocator{}}
+            { /* DUMMY BODY */ }
+
+            explicit vector(const Allocator& alloc)
+                : data_{nullptr}, size_{}, capacity_{},
+                  allocator_{alloc}
+            { /* DUMMY BODY */ }
+
+            explicit vector(size_type n, const Allocator& alloc = Allocator{})
+                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
+            {
+                data_ = allocator_.allocate(capacity_);
+
+                for (size_type i = 0; i < size_; ++i)
+                    allocator_traits<Allocator>::construct(allocator_, data_ + i);
+            }
+
+            vector(size_type n, const T& val, const Allocator& alloc = Allocator{})
+                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
+            {
+                data_ = allocator_.allocate(capacity_);
+
+                for (size_type i = 0; i < size_; ++i)
+                    data_[i] = val;
+            }
+
+            template<class InputIterator>
+            vector(InputIterator first, InputIterator last,
+                   const Allocator& alloc = Allocator{})
+            {
+                // TODO: research constraints and provide multiple
+                //       implementations via enable_if
+            }
+
+            vector(const vector& other)
+                : data_{nullptr}, size_{other.size_}, capacity_{other.capacity_},
+                  allocator_{other.allocator_}
+            {
+                data_ = allocator_.allocate(capacity_);
+
+                for (size_type i = 0; i < size_; ++i)
+                    data_[i] = other.data_[i];
+            }
+
+            vector(vector&& other) noexcept
+                : data_{other.data_}, size_{other.size_}, capacity_{other.capacity_},
+                  allocator_{move(other.allocator_)}
+            {
+                // other is guaranteed to be empty()
+                other.size_ = other.capacity_ = 0;
+                other.data_ = nullptr;
+            }
+
+            vector(const vector& other, const Allocator& alloc)
+                : data_{nullptr}, size_{other.size_}, capacity_{other.capacity_},
+                  allocator_{alloc}
+            {
+                data_ = allocator_.allocate(capacity_);
+
+                for (size_type i = 0; i < size_; ++i)
+                    data_[i] = other.data_[i];
+            }
+
+            vector(initializer_list<T> init, const Allocator& alloc = Allocator{})
+                : data_{nullptr}, size_{init.size()}, capacity_{init.size()},
+                  allocator_{alloc}
+            {
+                data_ = allocator_.allocate(capacity_);
+
+                auto it = init.begin();
+                for (size_type i = 0; it != init.end(); ++i, ++it)
+                {
+                    data_[i] = *it;
+                }
+            }
+
+            ~vector()
+            {
+                allocator_.deallocate(data_, capacity_);
+            }
+
+            vector& operator=(const vector& other)
+            {
+                vector tmp{other};
+                swap(tmp);
+
+                return *this;
+            }
+
+            vector& operator=(vector&& other)
+                noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
+                         allocator_traits<Allocator>::is_always_equal::value)
+            {
+                if (data_)
+                    allocator_.deallocate(data_, capacity_);
+
+                // TODO: test this
+                data_ = other.data_;
+                size_ = other.size_;
+                capacity_ = other.capacity_;
+                allocator_ = move(other.allocator_);
+
+                other.data_ = nullptr;
+                other.size_ = size_type{};
+                other.capacity_ = size_type{};
+                other.allocator_ = allocator_type{};
+                return *this;
+            }
+
+            vector& operator=(initializer_list<T> init)
+            {
+                vector tmp{init, allocator_};
+                swap(tmp);
+
+                return *this;
+            }
+
+            template<class InputIterator>
+            void assign(InputIterator first, InputIterator last)
+            {
+                vector tmp{first, last};
+                swap(tmp);
+            }
+
+            void assign(size_type size, const T& val)
+            {
+                // Parenthesies required to avoid initializer list
+                // construction.
+                vector tmp(size, val);
+                swap(tmp);
+            }
+
+            void assign(initializer_list<T> init)
+            {
+                vector tmp{init};
+                swap(tmp);
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_type{allocator_};
+            }
+
+            iterator begin() noexcept
+            {
+                return &data_[0];
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return &data_[0];
+            }
+
+            iterator end() noexcept
+            {
+                return begin() + size_;
+            }
+
+            const_iterator end() const noexcept
+            {
+                return begin() + size_;
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return make_reverse_iterator(end());
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return make_reverse_iterator(begin());
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return &data_[0];
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return cbegin() + size_;
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return rbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return rend();
+            }
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type max_size() const noexcept
+            {
+                return std::allocator_traits<Allocator>::max_size(allocator_);
+            }
+
+            void resize(size_type sz)
+            {
+                resize_with_copy_(size_, capacity_);
+            }
+
+            void resize(size_type sz, const value_type& val)
+            {
+                auto old_size = size_;
+                resize_with_copy_(sz, capacity_);
+
+                for (size_type i = old_size - 1; i < size_; ++i)
+                    data_[i] = val;
+            }
+
+            size_type capacity() const noexcept
+            {
+                return capacity_;
+            }
+
+            bool empty() const noexcept
+            {
+                return size_ == 0;
+            }
+
+            void reserve(size_type new_capacity)
+            {
+                // TODO: if new_capacity > max_size() throw
+                //       length_error (this function shall have no
+                //       effect in such case)
+                if (new_capacity > capacity_)
+                    resize_with_copy_(size_, new_capacity);
+            }
+
+            void shrink_to_fit()
+            {
+                resize_with_copy_(size_, size_);
+            }
+
+            reference operator[](size_type idx)
+            {
+                return data_[idx];
+            }
+
+            const_reference operator[](size_type idx) const
+            {
+                return data_[idx];
+            }
+
+            reference at(size_type idx)
+            {
+                // TODO: bounds checking
+                return data_[idx];
+            }
+
+            const_reference at(size_type idx) const
+            {
+                // TODO: bounds checking
+                return data_[idx];
+            }
+
+            reference front()
+            {
+                /**
+                 * Note: Calling front/back on an empty container
+                 *       is undefined, we opted for at-like
+                 *       behavior to provide our users with means
+                 *       to protect their programs from accidental
+                 *       accesses to an empty vector.
+                 */
+                return at(0);
+            }
+
+            const_reference front() const
+            {
+                return at(0);
+            }
+
+            reference back()
+            {
+                return at(size_ - 1);
+            }
+
+            const_reference back() const
+            {
+                return at(size - 1);
+            }
+
+            T* data() noexcept
+            {
+                return data_;
+            }
+
+            const T* data() const noexcept
+            {
+                return data_;
+            }
+
+            template<class... Args>
+            reference emplace_back(Args&&... args)
+            {
+                if (size_ >= capacity_)
+                    resize_with_copy_(size_, next_capacity_());
+
+                allocator_traits<Allocator>::construct(allocator_,
+                                                       begin() + size_, forward<Args>(args)...);
+
+                return back();
+            }
+
+            void push_back(const T& x)
+            {
+                if (size_ >= capacity_)
+                    resize_with_copy_(size_, next_capacity_());
+                data_[size_++] = x;
+            }
+
+            void push_back(T&& x)
+            {
+                if (size_ >= capacity_)
+                    resize_with_copy_(size_, next_capacity_());
+                data_[size_++] = forward<T>(x);
+            }
+
+            void pop_back()
+            {
+                destroy_from_end_until_(end() - 1);
+                --size_;
+            }
+
+            template<class... Args>
+            iterator emplace(const_iterator position, Args&&... args)
+            {
+                auto pos = const_cast<iterator>(position);
+
+                pos = shift_(pos, 1);
+                allocator_.construct(pos, forward<Args>(args)...);
+
+                return pos;
+            }
+
+            iterator insert(const_iterator position, const value_type& x)
+            {
+                auto pos = const_cast<iterator>(position);
+
+                pos = shift_(pos, 1);
+                *pos = x;
+
+                return pos;
+            }
+
+            iterator insert(const_iterator position, value_type&& x)
+            {
+                auto pos = const_cast<iterator>(position);
+
+                pos = shift_(pos, 1);
+                *pos = forward<value_type>(x);
+
+                return pos;
+            }
+
+            iterator insert(const_iterator position, size_type count, const value_type& x)
+            {
+                auto pos = const_cast<iterator>(position);
+
+                pos = shift_(pos, count);
+                auto copy_target = pos;
+                for (size_type i = 0; i < count; ++i)
+                    *copy_target++ = x;
+
+                return pos;
+            }
+
+            template<class InputIterator>
+            iterator insert(const_iterator position, InputIterator first,
+                            InputIterator last)
+            {
+                auto pos = const_cast<iterator>(position);
+                auto count = static_cast<size_type>(last - first);
+
+                pos = shift_(pos, count);
+                copy(first, last, pos);
+
+                return pos;
+            }
+
+            iterator insert(const_iterator position, initializer_list<T> init)
+            {
+                auto pos = const_cast<iterator>(position);
+
+                pos = shift_(pos, init.size());
+                copy(init.begin(), init.end(), pos);
+
+                return pos;
+            }
+
+            iterator erase(const_iterator position)
+            {
+                iterator pos = const_cast<iterator>(position);
+                copy(position + 1, cend(), pos);
+                --size_;
+
+                return pos;
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                iterator pos = const_cast<iterator>(first);
+                copy(last, cend(), pos);
+                size_ -= static_cast<size_type>(last - first);
+
+                return pos;
+            }
+
+            void swap(vector& other)
+                noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
+                         allocator_traits<Allocator>::is_always_equal::value)
+            {
+                std::swap(data_, other.data_);
+                std::swap(size_, other.size_);
+                std::swap(capacity_, other.capacity_);
+            }
+
+            void clear() noexcept
+            {
+                // Note: Capacity remains unchanged.
+                destroy_from_end_until_(begin());
+                size_ = 0;
+            }
+
+        private:
+            value_type* data_;
+            size_type size_;
+            size_type capacity_;
+            allocator_type allocator_;
+
+            void resize_without_copy_(size_type capacity)
+            {
+                if (data_)
+                    allocator_.deallocate(data_, capacity_);
+
+                data_ = allocator_.allocate(capacity);
+                size_ = 0;
+                capacity_ = capacity;
+            }
+
+            void resize_with_copy_(size_type size, size_type capacity)
+            {
+                if (size < size_)
+                    destroy_from_end_until_(begin() + size);
+
+                if(capacity_ == 0 || capacity_ < capacity)
+                {
+                    auto new_data = allocator_.allocate(capacity);
+
+                    auto to_copy = min(size, size_);
+                    for (size_type i = 0; i < to_copy; ++i)
+                        new_data[i] = move(data_[i]);
+
+                    std::swap(data_, new_data);
+
+                    allocator_.deallocate(new_data, capacity_);
+                }
+
+                capacity_ = capacity;
+                size_ = size;
+            }
+
+            void destroy_from_end_until_(iterator target)
+            {
+                if (!empty())
+                {
+                    auto last = end();
+                    while(last != target)
+                        allocator_traits<Allocator>::destroy(allocator_, --last);
+                }
+            }
+
+            size_type next_capacity_(size_type hint = 0) const noexcept
+            {
+                if (hint != 0)
+                    return max(capacity_ * 2, hint);
+                else
+                    return max(capacity_ * 2, 2ul);
+            }
+
+            iterator shift_(iterator position, size_type count)
+            {
+                if (size_ + count < capacity_)
+                {
+                    copy_backward(position, end(), end() + count);
+                    size_ += count;
+
+                    return position;
+                }
+                else
+                {
+                    auto start_idx = static_cast<size_type>(position - begin());
+                    auto end_idx = start_idx + count;
+                    auto new_size = size_ + count;
+
+                    // Auxiliary vector for easier swap.
+                    vector tmp{};
+                    tmp.resize_without_copy_(max(new_size, capacity_));
+                    tmp.size_ = new_size;
+
+                    // Copy before insertion index.
+                    copy(begin(), begin() + start_idx, tmp.begin());
+
+                    // Copy after insertion index.
+                    copy(begin() + start_idx, end(), tmp.begin() + end_idx);
+
+                    swap(tmp);
+
+                    // Position was invalidated!
+                    return begin() + start_idx;
+                }
+            }
+    };
+
+    template<class T, class Alloc>
+    bool operator==(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        if (lhs.size() != rhs.size())
+            return false;
+
+        for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i)
+        {
+            if (lhs[i] != rhs[i])
+                return false;
+        }
+
+        return true;
+    }
+
+    template<class T, class Alloc>
+    bool operator<(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        auto min_size = min(lhs.size(), rhs.size());
+        for (decltype(lhs.size()) i = 0; i < min_size; ++i)
+        {
+            if (lhs[i] >= rhs[i])
+                return false;
+        }
+
+        if (lhs.size() == rhs.size())
+            return true;
+        else
+            return lhs.size() < rhs.size();
+    }
+
+    template<class T, class Alloc>
+    bool operator!=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class T, class Alloc>
+    bool operator>(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class T, class Alloc>
+    bool operator>=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class T, class Alloc>
+    bool operator<=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    /**
+     * 23.3.6.6, specialized algorithms:
+     */
+    template<class T, class Alloc>
+    void swap(vector<T, Alloc>& lhs, vector<T, Alloc>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 23.3.7, class vector<bool>:
+     */
+
+    // TODO: implement
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/algorithm.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/algorithm.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/algorithm.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ALGORITHM
+#define LIBCPP_BITS_ALGORITHM
+
+#include <iterator>
+#include <utility>
+
+namespace std
+{
+    template<class T>
+    struct less;
+
+    /**
+     * 25.2, non-modyfing sequence operations:
+     */
+
+    /**
+     * 25.2.1, all_of:
+     */
+
+    template<class InputIterator, class Predicate>
+    bool all_of(InputIterator first, InputIterator last, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (!pred(*first++))
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * 25.2.2, any_of:
+     */
+
+    template<class InputIterator, class Predicate>
+    bool any_of(InputIterator first, InputIterator last, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (pred(*first++))
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * 25.2.3, none_of:
+     */
+
+    template<class InputIterator, class Predicate>
+    bool none_of(InputIterator first, InputIterator last, Predicate pred)
+    {
+        return !any_of(first, last, pred);
+    }
+
+    /**
+     * 25.2.4, for_each:
+     */
+
+    template<class InputIterator, class Function>
+    Function for_each(InputIterator first, InputIterator last, Function f)
+    {
+        while (first != last)
+            f(*first++);
+
+        return move(f);
+    }
+
+    /**
+     * 25.2.5, find:
+     */
+
+    template<class InputIterator, class T>
+    InputIterator find(InputIterator first, InputIterator last, const T& value)
+    {
+        while (first != last)
+        {
+            if (*first == value)
+                return first;
+            ++first;
+        }
+
+        return last;
+    }
+
+    template<class InputIterator, class Predicate>
+    InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (pred(*first))
+                return first;
+            ++first;
+        }
+
+        return last;
+    }
+
+    template<class InputIterator, class Predicate>
+    InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (!pred(*first))
+                return first;
+            ++first;
+        }
+
+        return last;
+    }
+
+    /**
+     * 25.2.6, find_end:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.2.7, find_first:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.2.8, adjacent_find:
+     */
+
+    template<class ForwardIterator>
+    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)
+    {
+        while (first != last)
+        {
+            if (*first == *(first + 1))
+                return first;
+            ++first;
+        }
+
+        return last;
+    }
+
+    template<class ForwardIterator, class Predicate>
+    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (pred(*first, *(first + 1)))
+                return first;
+            ++first;
+        }
+
+        return last;
+    }
+
+    /**
+     * 25.2.9, count:
+     */
+
+    template<class InputIterator, class T>
+    typename iterator_traits<InputIterator>::difference_type
+    count(InputIterator first, InputIterator last, const T& value)
+    {
+        typename iterator_traits<InputIterator>::difference_type cnt{};
+
+        while (first != last)
+        {
+            if (*first++ == value)
+                ++cnt;
+        }
+
+        return cnt;
+    }
+
+    template<class InputIterator, class Predicate>
+    typename iterator_traits<InputIterator>::difference_type
+    count_if(InputIterator first, InputIterator last, Predicate pred)
+    {
+        typename iterator_traits<InputIterator>::difference_type cnt{};
+
+        while (first != last)
+        {
+            if (pred(*first++))
+                ++cnt;
+        }
+
+        return cnt;
+    }
+
+    /**
+     * 25.2.10, mismatch:
+     */
+
+    template<class InputIterator1, class InputIterator2>
+    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
+                                                  InputIterator2 first2)
+    {
+        while (first1 != last1 && *first1 == *first2)
+        {
+            ++first1;
+            ++first2;
+        }
+
+        return make_pair(first1, first2);
+    }
+
+    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
+    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
+                                                  InputIterator2 first2, BinaryPredicate pred)
+    {
+        while (first1 != last1 && pred(*first1, *first2))
+        {
+            ++first1;
+            ++first2;
+        }
+
+        return make_pair(first1, first2);
+    }
+
+    template<class InputIterator1, class InputIterator2>
+    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
+                                                  InputIterator2 first2, InputIterator2 last2)
+    {
+        while (first1 != last1 && first2 != last2 && *first1 == *first2)
+        {
+            ++first1;
+            ++first2;
+        }
+
+        return make_pair(first1, first2);
+    }
+
+    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
+    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
+                                                  InputIterator2 first2, InputIterator2 last2,
+                                                  BinaryPredicate pred)
+    {
+        while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
+        {
+            ++first1;
+            ++first2;
+        }
+
+        return make_pair(first1, first2);
+    }
+
+    /**
+     * 25.2.11, equal:
+     */
+
+    template<class InputIterator1, class InputIterator2>
+    bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+    {
+        while (first1 != last1)
+        {
+            if (*first1++ != *first2++)
+                return false;
+        }
+
+        return true;
+    }
+
+    template<class InputIterator1, class InputIterator2>
+    bool equal(InputIterator1 first1, InputIterator1 last1,
+               InputIterator2 first2, InputIterator2 last2)
+    {
+        while (first1 != last1 && first2 != last2)
+        {
+            if (*first1++ != *first2++)
+                return false;
+        }
+
+        return true;
+    }
+
+    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
+    bool equal(InputIterator1 first1, InputIterator1 last1,
+               InputIterator2 first2, BinaryPredicate pred)
+    {
+        while (first1 != last1)
+        {
+            if (!pred(*first1++, *first2++))
+                return false;
+        }
+
+        return true;
+    }
+
+    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
+    bool equal(InputIterator1 first1, InputIterator1 last1,
+               InputIterator2 first2, InputIterator2 last2,
+               BinaryPredicate pred)
+    {
+        while (first1 != last1 && first2 != last2)
+        {
+            if (!pred(*first1++, *first2++))
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * 25.2.12, is_permutation:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.2.13, search:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.3, mutating sequence operations:
+     */
+
+    /**
+     * 25.3.1, copy:
+     */
+
+    template<class InputIterator, class OutputIterator>
+    OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
+    {
+        while (first != last)
+            *result++ = *first++;
+
+        return result;
+    }
+
+    template<class InputIterator, class Size, class OutputIterator>
+    OutputIterator copy_n(InputIterator first, Size count, OutputIterator result)
+    {
+        for (Size i = 0; i < count; ++i, ++first, ++result)
+            *result = *first;
+
+        return result;
+    }
+
+    template<class InputIterator, class OutputIterator, class Predicate>
+    OutputIterator copy_if(InputIterator first, InputIterator last,
+                           OutputIterator result, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (pred(*first))
+                *result++ = *first;
+            ++first;
+        }
+
+        return result;
+    }
+
+    template<class BidirectionalIterator1, class BidirectionalIterator2>
+    BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
+                                         BidirectionalIterator2 result)
+    {
+        // Note: We're copying [first, last) so we need to skip the initial value of last.
+        while (last-- != first)
+            *result-- = *last;
+
+        return result;
+    }
+
+    /**
+     * 25.3.2, move:
+     */
+
+    template<class InputIterator, class OutputIterator>
+    OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
+    {
+        while (first != last)
+            *result++ = move(*first++);
+
+        return result;
+    }
+
+    template<class BidirectionalIterator1, class BidirectionalIterator2>
+    BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
+                                         BidirectionalIterator2 result)
+    {
+        // Note: We're copying [first, last) so we need to skip the initial value of last.
+        while (last-- != first)
+            *result-- = move(*last);
+    }
+
+    /**
+     * 25.3.3, swap:
+     */
+
+    template<class ForwardIterator1, class ForwardIterator2>
+    ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
+                                 ForwardIterator2 first2)
+    {
+        while (first1 != last1)
+            swap(*first1++, *first2++);
+
+        return first2;
+    }
+
+    template<class ForwardIterator1, class ForwardIterator2>
+    void iter_swap(ForwardIterator1 iter1, ForwardIterator2 iter2)
+    {
+        swap(*iter1, *iter2);
+    }
+
+    /**
+     * 25.3.4, transform:
+     */
+
+    template<class InputIterator, class OutputIterator, class UnaryOperation>
+    OutputIterator transform(InputIterator first, InputIterator last,
+                             OutputIterator result, UnaryOperation op)
+    {
+        while (first != last)
+            *result++ = op(*first++);
+
+        return result;
+    }
+
+    template<class InputIterator1, class InputIterator2,
+             class OutputIterator, class BinaryOperation>
+    OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
+                             InputIterator2 first2, OutputIterator result,
+                             BinaryOperation op)
+    {
+        while (first1 != last1)
+            *result++ = op(*first1++, *first2++);
+
+        return result;
+    }
+
+    /**
+     * 25.3.5, replace:
+     */
+
+    template<class ForwardIterator, class T>
+    void replace(ForwardIterator first, ForwardIterator last,
+                 const T& old_value, const T& new_value)
+    {
+        while (first != last)
+        {
+            if (*first == old_value)
+                *first = new_value;
+            ++first;
+        }
+    }
+
+    template<class ForwardIterator, class Predicate, class T>
+    void replace_if(ForwardIterator first, ForwardIterator last,
+                    Predicate pred, const T& new_value)
+    {
+        while (first != last)
+        {
+            if (pred(*first))
+                *first = new_value;
+            ++first;
+        }
+    }
+
+    template<class InputIterator, class OutputIterator, class T>
+    OutputIterator replace_copy(InputIterator first, InputIterator last,
+                                OutputIterator result, const T& old_value,
+                                const T& new_value)
+    {
+        while (first != last)
+        {
+            if (*first == old_value)
+                *result = new_value;
+            else
+                *result = *first;
+
+            ++first;
+            ++result;
+        }
+    }
+
+    template<class InputIterator, class OutputIterator, class Predicate, class T>
+    OutputIterator replace_copy_if(InputIterator first, InputIterator last,
+                                OutputIterator result, Predicate pred,
+                                const T& new_value)
+    {
+        while (first != last)
+        {
+            if (pred(*first))
+                *result = new_value;
+            else
+                *result = *first;
+
+            ++first;
+            ++result;
+        }
+    }
+
+    /**
+     * 25.3.6, fill:
+     */
+
+    template<class ForwardIterator, class T>
+    void fill(ForwardIterator first, ForwardIterator last, const T& value)
+    {
+        while (first != last)
+            *first++ = value;
+    }
+
+    template<class InputIterator, class Size, class T>
+    void fill_n(InputIterator first, Size count, const T& value)
+    {
+        for (Size i = 0; i < count; ++i)
+            *first++ = value;
+    }
+
+    /**
+     * 25.3.7, generate:
+     */
+
+    template<class ForwardIterator, class Generator>
+    void generate(ForwardIterator first, ForwardIterator last,
+                  Generator gen)
+    {
+        while (first != last)
+            *first++ = gen();
+    }
+
+    template<class OutputIterator, class Size, class Generator>
+    void generate(OutputIterator first, Size count, Generator gen)
+    {
+        for (Size i = 0; i < count; ++i)
+            *first++ = gen();
+    }
+
+    /**
+     * 25.3.8, remove:
+     */
+
+    template<class ForwardIterator, class T>
+    ForwardIterator remove(ForwardIterator first, ForwardIterator last,
+                           const T& value)
+    {
+        auto it = first;
+        while (it != last)
+        {
+            if (*it != value)
+                *first++ = move(*it);
+        }
+
+        return first;
+    }
+
+    template<class ForwardIterator, class Predicate>
+    ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
+                              Predicate pred)
+    {
+        auto it = first;
+        while (it != last)
+        {
+            if (!pred(*it))
+                *first++ = move(*it);
+        }
+
+        return first;
+    }
+
+    template<class InputIterator, class OutputIterator, class T>
+    OutputIterator remove_copy(InputIterator first, InputIterator last,
+                               OutputIterator result, const T& value)
+    {
+        while (first != last)
+        {
+            if (*first != value)
+                *result++ = *first;
+            ++first;
+        }
+
+        return result;
+    }
+
+    template<class InputIterator, class OutputIterator, class Predicate>
+    OutputIterator remove_copy_if(InputIterator first, InputIterator last,
+                                  OutputIterator result, Predicate pred)
+    {
+        while (first != last)
+        {
+            if (!pred(*first))
+                *result++ = *first;
+            ++first;
+        }
+
+        return result;
+    }
+
+    /**
+     * 25.3.9, unique:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.3.10, reverse:
+     */
+
+    template<class BidirectionalIterator>
+    void reverse(BidirectionalIterator first, BidirectionalIterator last)
+    {
+        if (first == last)
+            return;
+        auto mid_count = (last - first) / 2;
+
+        --last;
+        for (decltype(mid_count) i = 0; i < mid_count; ++i)
+            iter_swap(first++, last--);
+    }
+
+    template<class BidirectionalIterator, class OutputIterator>
+    OutputIterator reverse_copy(BidirectionalIterator first,
+                                BidirectionalIterator last,
+                                OutputIterator result)
+    {
+        while (--last != first)
+            *result++ = *last;
+    }
+
+    /**
+     * 25.3.11, rotate:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.3.12, shuffle:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.3.13, partitions:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4, sorting and related operations:
+     */
+
+    /**
+     * 25.4.1, sorting:
+     */
+
+    /**
+     * 25.4.1.1, sort:
+     */
+
+    template<class RandomAccessIterator, class Compare>
+    void make_heap(RandomAccessIterator, RandomAccessIterator,
+                   Compare);
+
+    template<class RandomAccessIterator, class Compare>
+    void sort_heap(RandomAccessIterator, RandomAccessIterator,
+                   Compare);
+
+    template<class RandomAccessIterator>
+    void sort(RandomAccessIterator first, RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        sort(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    void sort(RandomAccessIterator first, RandomAccessIterator last,
+              Compare comp)
+    {
+        /**
+         * Note: This isn't the most effective approach,
+         *       but since we already have these two functions
+         *       and they satisfy asymptotic limitations
+         *       imposed by the standard, we're using them at
+         *       the moment. Might be good to change it to qsort
+         *       or merge sort later.
+         */
+
+        make_heap(first, last, comp);
+        sort_heap(first, last, comp);
+    }
+
+    /**
+     * 25.4.1.2, stable_sort:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.1.3, partial_sort:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.1.4, partial_sort_copy:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.1.5, is_sorted:
+     */
+
+    template<class ForwardIterator>
+    bool is_sorted(ForwardIterator first, ForwardIterator last)
+    {
+        return is_sorted_until(first, last) == last;
+    }
+
+    template<class ForwardIterator, class Comp>
+    bool is_sorted(ForwardIterator first, ForwardIterator last,
+                   Comp comp)
+    {
+        return is_sorted_until(first, last, comp) == last;
+    }
+
+    template<class ForwardIterator>
+    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last)
+    {
+        if (distance(first, last) < 2)
+            return last;
+
+        while (first != last)
+        {
+            if (*first > *(++first))
+                return first;
+        }
+
+        return last;
+    }
+
+    template<class ForwardIterator, class Comp>
+    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last,
+                                    Comp comp)
+    {
+        if (distance(first, last) < 2)
+            return last;
+
+        while (first != last)
+        {
+            if (!comp(*first, *(++first)))
+                return first;
+        }
+
+        return last;
+    }
+
+    /**
+     * 25.4.2, nth_element:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.3, binary search:
+     */
+
+    /**
+     * 25.4.3.1, lower_bound
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.3.2, upper_bound
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.3.3, equal_range:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.3.4, binary_search:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.4, merge:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.5, set operations on sorted structures:
+     */
+
+    /**
+     * 25.4.5.1, includes:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.5.2, set_union:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.5.3, set_intersection:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.5.4, set_difference:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.5.5, set_symmetric_difference:
+     */
+
+    // TODO: implement
+
+    /**
+     * 25.4.6, heap operations:
+     */
+
+    namespace aux
+    {
+        template<class T>
+        T heap_parent(T idx)
+        {
+            return (idx - 1) / 2;
+        }
+
+        template<class T>
+        T heap_left_child(T idx)
+        {
+            return 2 * idx + 1;
+        }
+
+        template<class T>
+        T heap_right_child(T idx)
+        {
+            return 2 * idx + 2;
+        }
+
+        template<class RandomAccessIterator, class Size, class Compare>
+        void correct_children(RandomAccessIterator first,
+                              Size idx, Size count, Compare comp)
+        {
+            using aux::heap_left_child;
+            using aux::heap_right_child;
+
+            auto left = heap_left_child(idx);
+            auto right = heap_right_child(idx);
+
+            bool left_incorrect{comp(first[idx], first[left])};
+            bool right_incorrect{comp(first[idx], first[right])};
+            while ((left < count && left_incorrect) ||
+                   (right < count && right_incorrect))
+            {
+                if (right >= count || (left_incorrect && comp(first[right], first[left])))
+                {
+                    swap(first[idx], first[left]);
+
+                    idx = left;
+                }
+                else if (right < count && right_incorrect)
+                {
+                    swap(first[idx], first[right]);
+
+                    idx = right;
+                } // Else should not happen because of the while condition.
+
+                left = heap_left_child(idx);
+                right = heap_right_child(idx);
+
+                left_incorrect = comp(first[idx], first[left]);
+                right_incorrect = comp(first[idx], first[right]);
+            }
+        }
+    }
+
+    /**
+     * 25.4.6.1, push_heap:
+     */
+
+    template<class RandomAccessIterator>
+    void push_heap(RandomAccessIterator first,
+                   RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        push_heap(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    void push_heap(RandomAccessIterator first,
+                   RandomAccessIterator last,
+                   Compare comp)
+    {
+        using aux::heap_parent;
+
+        auto count = distance(first, last);
+        if (count <= 1)
+            return;
+
+        auto idx = count - 1;
+        auto parent = heap_parent(idx);
+        while (idx > 0 && comp(first[parent], first[idx]))
+        {
+            swap(first[idx], first[parent]);
+
+            idx = parent;
+            parent = heap_parent(idx);
+        }
+    }
+
+    /**
+     * 25.4.6.2, pop_heap:
+     */
+
+    template<class RandomAccessIterator>
+    void pop_heap(RandomAccessIterator first,
+                  RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        pop_heap(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    void pop_heap(RandomAccessIterator first,
+                  RandomAccessIterator last,
+                  Compare comp)
+    {
+        auto count = distance(first, last);
+        if (count <= 1)
+            return;
+
+        swap(first[0], first[count - 1]);
+        aux::correct_children(first, decltype(count){}, count - 2, comp);
+    }
+
+    /**
+     * 25.4.6.3, make_heap:
+     */
+
+    template<class RandomAccessIterator>
+    void make_heap(RandomAccessIterator first,
+                   RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        make_heap(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    void make_heap(RandomAccessIterator first,
+                   RandomAccessIterator last,
+                   Compare comp)
+    {
+        auto count = distance(first, last);
+        if (count <= 1)
+            return;
+
+        for (auto i = count; i > 0; --i)
+        {
+            auto idx = i - 1;
+
+            aux::correct_children(first, idx, count, comp);
+        }
+    }
+
+    /**
+     * 25.4.6.4, sort_heap:
+     */
+
+    template<class RandomAccessIterator>
+    void sort_heap(RandomAccessIterator first,
+                   RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        sort_heap(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    void sort_heap(RandomAccessIterator first,
+                   RandomAccessIterator last,
+                   Compare comp)
+    {
+        while (first != last)
+            pop_heap(first, last--, comp);
+    }
+
+    /**
+     * 25.4.6.5, is_heap:
+     */
+
+    template<class RandomAccessIterator>
+    auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last)
+    {
+        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
+
+        return is_heap_until(first, last, less<value_type>{});
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last,
+                       Compare comp)
+    {
+        using aux::heap_left_child;
+        using aux::heap_right_child;
+
+        auto count = distance(first, last);
+        if (count < 2)
+            return last;
+
+        auto res = first;
+        for (decltype(count) idx = 0; idx < count; ++idx)
+        {
+            auto left = heap_left_child(idx);
+            auto right = heap_right_child(idx);
+
+            if (left < count && comp(first[idx], first[left]))
+                return res;
+            if (right < count && comp(first[idx], first[right]))
+                return res;
+
+            ++res;
+        }
+
+        return res;
+    }
+
+    template<class RandomAccessIterator>
+    bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
+    {
+        return is_heap_until(first, last) == last;
+    }
+
+    template<class RandomAccessIterator, class Compare>
+    bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
+                 Compare comp)
+    {
+        return is_heap_until(first, last, comp) == last;
+    }
+
+    /**
+     * 25.4.7, minimum and maximum:
+     * // TODO: implement container versions when we have
+     *          numeric limits and min/max element
+     * // TODO: versions with comparators
+     * // TODO: minmax
+     */
+
+    template<class T>
+    constexpr const T& min(const T& lhs, const T& rhs)
+    {
+        return (lhs < rhs) ? lhs : rhs;
+    }
+
+    template<class T>
+    constexpr const T& max(const T& lhs, const T& rhs)
+    {
+        return (lhs > rhs) ? lhs : rhs;
+    }
+
+    /**
+     * 25.4.8, lexicographical comparison:
+     */
+
+    template<class InputIterator1, class InputIterator2>
+    bool lexicographical_compare(InputIterator1 first1,
+                                 InputIterator1 last1,
+                                 InputIterator2 first2,
+                                 InputIterator2 last2)
+    {
+        /**
+         * *first1 and *first2 can have different types
+         * so we use a transparent comparator.
+         */
+        return lexicographical_compare(
+            first1, last1, first2, last2,
+            less<void>{}
+        );
+    }
+
+    template<class InputIterator1, class InputIterator2, class Compare>
+    bool lexicographical_compare(InputIterator1 first1,
+                                 InputIterator1 last1,
+                                 InputIterator2 first2,
+                                 InputIterator2 last2,
+                                 Compare comp)
+    {
+        while ((first1 != last1) && (first2 != last2))
+        {
+            if (comp(*first1, *first2))
+                return true;
+            if (comp(*first2, *first1))
+                return false;
+
+            ++first1;
+            ++first2;
+        }
+
+        /**
+         * Up until now they are same, so we have to check
+         * if we reached the end on one.
+         */
+        return (first1 == last1) && (first2 != last2);
+    }
+
+    /**
+     * 25.4.9, permutation generators:
+     */
+
+    // TODO: implement
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/atomic.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/atomic.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/atomic.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ATOMIC
+#define LIBCPP_BITS_ATOMIC
+
+#error "<atomic> is not implemented"
+
+#endif
Index: uspace/lib/cpp/include/__bits/aux.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/aux.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/aux.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBCPP_AUX
-#define LIBCPP_AUX
+#ifndef LIBCPP_BITS_AUX
+#define LIBCPP_BITS_AUX
 
 namespace std
Index: uspace/lib/cpp/include/__bits/chrono.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/chrono.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/chrono.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,759 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_CHRONO
+#define LIBCPP_BITS_CHRONO
+
+#include <ctime>
+#include <limits>
+#include <ratio>
+#include <type_traits>
+
+namespace std::chrono
+{
+    /**
+     * 20.12.5, class template duration:
+     */
+
+    // Forward declarations.
+    template<class Rep, class Period = ratio<1>>
+    class duration;
+
+    template<class ToDuration, class Rep, class Period>
+    constexpr ToDuration duration_cast(const duration<Rep, Period>& dur);
+
+    template<class Rep>
+    struct duration_values;
+
+    template<class Rep, class Period>
+    class duration
+    {
+        public:
+            using rep    = Rep;
+            using period = Period;
+
+            /**
+             * 20.12.5.1, construct/copy/destroy:
+             */
+
+            constexpr duration() = default;
+
+            // TODO: check remarks to these two constructors, need is_convertible
+            template<class Rep2>
+            constexpr explicit duration(const Rep2& r)
+                : rep_{r}
+            { /* DUMMY BODY */ }
+
+            template<class Rep2, class Period2>
+            constexpr duration(const duration<Rep2, Period2>& other)
+                : rep_{duration_cast<duration>(other).count()}
+            { /* DUMMY BODY */ }
+
+            ~duration() = default;
+
+            duration(const duration&) = default;
+
+            duration& operator=(const duration&) = default;
+
+            /**
+             * 20.12.5.2, observer:
+             */
+
+            constexpr rep count() const
+            {
+                return rep_;
+            }
+
+            /**
+             * 20.12.5.3, arithmetic:
+             */
+
+            constexpr duration operator+() const
+            {
+                return *this;
+            }
+
+            constexpr duration operator-() const
+            {
+                return duration{-rep_};
+            }
+
+            duration& operator++()
+            {
+                ++rep_;
+
+                return *this;
+            }
+
+            duration operator++(int)
+            {
+                return duration{rep_++};
+            }
+
+            duration& operator--()
+            {
+                --rep_;
+
+                *this;
+            }
+
+            duration operator--(int)
+            {
+                return duration{rep_--};
+            }
+
+            duration& operator+=(const duration& rhs)
+            {
+                rep_ += rhs.count();
+
+                return *this;
+            }
+
+            duration& operator-=(const duration& rhs)
+            {
+                rep_ -= rhs.count();
+
+                return *this;
+            }
+
+            duration& operator*=(const rep& rhs)
+            {
+                rep_ *= rhs;
+
+                return *this;
+            }
+
+            duration& operator/=(const rep& rhs)
+            {
+                rep_ /= rhs;
+
+                return *this;
+            }
+
+            duration& operator%=(const rep& rhs)
+            {
+                rep_ %= rhs;
+
+                return *this;
+            }
+
+            duration& operator%=(const duration& rhs)
+            {
+                rep_ %= rhs.count();
+
+                return *this;
+            }
+
+            /**
+             * 20.12.5.4, special values:
+             */
+
+            static constexpr duration zero()
+            {
+                return duration{duration_values<rep>::zero()};
+            }
+
+            static constexpr duration min()
+            {
+                return duration{duration_values<rep>::min()};
+            }
+
+            static constexpr duration max()
+            {
+                return duration{duration_values<rep>::max()};
+            }
+
+        private:
+            rep rep_;
+    };
+
+    /**
+     * 20.12.6, class template time_point:
+     */
+
+    template<class Clock, class Duration = typename Clock::duration>
+    class time_point
+    {
+        public:
+            using clock    = Clock;
+            using duration = Duration;
+            using rep      = typename duration::rep;
+            using period   = typename duration::period;
+
+            /**
+             * 20.12.6.1, construct:
+             */
+
+            constexpr time_point()
+                : duration_{duration::zero()}
+            { /* DUMMY BODY */ }
+
+            constexpr explicit time_point(const duration& d)
+                : duration_{d}
+            { /* DUMMY BODY */ }
+
+            // TODO: see remark to this constuctor
+            template<class Duration2>
+            constexpr time_point(const time_point<clock, Duration2>& other)
+                : duration_{static_cast<duration>(other.time_since_epoch())}
+            { /* DUMMY BODY */ }
+
+            /**
+             * 20.12.6.2, observer:
+             */
+
+            constexpr duration time_since_epoch() const
+            {
+                return duration_;
+            }
+
+            /**
+             * 20.12.6.3, arithmetic:
+             */
+
+            time_point& operator+=(const duration& rhs)
+            {
+                duration_ += rhs;
+
+                return *this;
+            }
+
+            time_point& operator-=(const duration& rhs)
+            {
+                duration_ -= rhs;
+
+                return *this;
+            }
+
+            /**
+             * 20.12.6.4, special values:
+             */
+
+            static constexpr time_point min()
+            {
+                return time_point{duration::min()};
+            }
+
+            static constexpr time_point max()
+            {
+                return time_point{duration::max()};
+            }
+
+        private:
+            duration duration_;
+    };
+}
+
+namespace std
+{
+    /**
+     * 20.12.4.3, common_type specializations:
+     */
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>
+    {
+        using type = chrono::duration<
+            common_type_t<Rep1, Rep2>,
+            ratio<aux::gcd_v<Period1::num, Period2::num>, aux::lcm_v<Period1::den, Period2::den>>
+        >;
+    };
+
+    template<class Clock, class Duration1, class Duration2>
+    struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>
+    {
+        using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
+    };
+}
+
+namespace std::chrono
+{
+    /**
+     * 20.12.4, customization traits:
+     */
+
+    template<class Rep>
+    struct treat_as_floating_point: is_floating_point<Rep>
+    { /* DUMMY BODY */ };
+
+    template<class Rep>
+    struct duration_values
+    {
+        static constexpr Rep zero()
+        {
+            // Note: Using Rep(0) instead of Rep{} is intentional, do not change.
+            return Rep(0);
+        }
+
+        static constexpr Rep min()
+        {
+            return numeric_limits<Rep>::lowest();
+        }
+
+        static constexpr Rep max()
+        {
+            return numeric_limits<Rep>::max();
+        }
+    };
+
+    /**
+     * 20.12.5.5, duration arithmetic:
+     */
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
+    operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
+        return CD(CD(lhs.count()) + CD(rhs.count()));
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
+    operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
+        return CD(CD(lhs).count() - CD(rhs).count());
+    }
+
+    // TODO: This shall not participate in overloading if Rep2 is not implicitly
+    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
+    //       common_type_t<A, B>.
+    template<class Rep1, class Period, class Rep2>
+    constexpr duration<common_type_t<Rep1, Rep2>, Period>
+    operator*(const duration<Rep1, Period>& dur, const Rep2& rep)
+    {
+        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
+        return CD(CD(dur).count() * rep);
+    }
+
+    // TODO: This shall not participate in overloading if Rep2 is not implicitly
+    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
+    //       common_type_t<A, B>.
+    template<class Rep1, class Period, class Rep2>
+    constexpr duration<common_type_t<Rep1, Rep2>, Period>
+    operator*(const Rep2& rep, const duration<Rep1, Period>& dur)
+    {
+        return dur * rep;
+    }
+
+    // TODO: This shall not participate in overloading if Rep2 is not implicitly
+    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
+    //       common_type_t<A, B>.
+    template<class Rep1, class Period, class Rep2>
+    constexpr duration<common_type_t<Rep1, Rep2>, Period>
+    operator/(const duration<Rep1, Period>& dur, const Rep2& rep)
+    {
+        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
+        return CD(CD(dur).count() / rep);
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr common_type_t<Rep1, Rep2>
+    operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        using CD = common_type_t<Rep1, Rep2>;
+        return CD(lhs).count() / CD(rhs).count();
+    }
+
+    // TODO: This shall not participate in overloading if Rep2 is not implicitly
+    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
+    //       common_type_t<A, B>.
+    template<class Rep1, class Period, class Rep2>
+    constexpr duration<common_type_t<Rep1, Rep2>, Period>
+    operator%(const duration<Rep1, Period>& dur, const Rep2& rep)
+    {
+        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
+        return CD(CD(dur).count() / rep);
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
+    operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
+        return CD(CD(lhs).count() % CD(rhs).count());
+    }
+
+    /**
+     * 20.12.5.6, duration comparisons:
+     */
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator==(const duration<Rep1, Period1>& lhs,
+                              const duration<Rep2, Period2>& rhs)
+    {
+        using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
+        return CT(lhs).count() == CT(rhs).count();
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
+                              const duration<Rep2, Period2>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator<(const duration<Rep1, Period1>& lhs,
+                             const duration<Rep2, Period2>& rhs)
+    {
+        using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
+        return CT(lhs).count() < CT(rhs).count();
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
+                              const duration<Rep2, Period2>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator>(const duration<Rep1, Period1>& lhs,
+                             const duration<Rep2, Period2>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Rep1, class Period1, class Rep2, class Period2>
+    constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
+                              const duration<Rep2, Period2>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    /**
+     * 20.12.5.7, duration cast:
+     */
+
+    // TODO: This function should not participate in overloading
+    //       unless ToDuration is an instantiation of duration.
+    template<class ToDuration, class Rep, class Period>
+    constexpr ToDuration duration_cast(const duration<Rep, Period>& dur)
+    {
+        using CF = ratio_divide<Period, typename ToDuration::period>;
+        using CR = typename common_type<typename ToDuration::rep, Rep, intmax_t>::type;
+
+        using to_rep = typename ToDuration::rep;
+
+        if constexpr (CF::num == 1 && CF::den == 1)
+            return ToDuration(static_cast<to_rep>(dur.count()));
+        else if constexpr (CF::num != 1 && CF::den == 1)
+        {
+            return ToDuration(
+                static_cast<to_rep>(
+                    static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
+                )
+            );
+        }
+        else if constexpr (CF::num == 1 && CF::den != 1)
+        {
+            return ToDuration(
+                static_cast<to_rep>(
+                    static_cast<CR>(dur.count()) / static_cast<CR>(CF::den)
+                )
+            );
+        }
+        else
+        {
+            return ToDuration(
+                static_cast<to_rep>(
+                    static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
+                    / static_cast<CR>(CF::den)
+                )
+            );
+        }
+    }
+
+    // convenience typedefs
+    using nanoseconds  = duration<int64_t, nano>;
+    using microseconds = duration<int64_t, micro>;
+    using milliseconds = duration<int64_t, milli>;
+    using seconds      = duration<int64_t>;
+    using minutes      = duration<int32_t, ratio<60>>;
+    using hours        = duration<int32_t, ratio<3600>>;
+
+    /**
+     * 20.12.6.5, time_point arithmetic:
+     */
+
+    template<class Clock, class Duration1, class Rep2, class Period2>
+    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
+    operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        using CT = time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>;
+        return CT(lhs.time_since_epoch() + rhs);
+    }
+
+    template<class Rep1, class Period1, class Clock, class Duration2>
+    constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
+    operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs)
+    {
+        return rhs + lhs;
+    }
+
+    template<class Clock, class Duration1, class Rep2, class Period2>
+    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
+    operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
+    {
+        return lhs + (-rhs);
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr common_type_t<Duration1, Duration2>
+    operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
+    {
+        return lhs.time_since_epoch() - rhs.time_since_epoch();
+    }
+
+    /**
+     * 20.12.6.6, time_point comparisons:
+     */
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
+                              const time_point<Clock, Duration2>& rhs)
+    {
+        return lhs.time_since_epoch() == rhs.time_since_epoch();
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
+                              const time_point<Clock, Duration2>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator<(const time_point<Clock, Duration1>& lhs,
+                             const time_point<Clock, Duration2>& rhs)
+    {
+        return lhs.time_since_epoch() < rhs.time_since_epoch();
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
+                              const time_point<Clock, Duration2>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator>(const time_point<Clock, Duration1>& lhs,
+                             const time_point<Clock, Duration2>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Clock, class Duration1, class Duration2>
+    constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
+                              const time_point<Clock, Duration2>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    /**
+     * 20.12.6.7, time_point cast:
+     */
+
+    // TODO: This function should not participate in overloading
+    //       unless ToDuration is an instantiation of duration.
+    template<class ToDuration, class Clock, class Duration>
+    constexpr time_point<Clock, ToDuration>
+    time_point_cast(const time_point<Clock, Duration>& tp)
+    {
+        return time_point<Clock, ToDuration>(
+            duration_cast<ToDuration>(tp.time_since_epoch())
+        );
+    }
+
+    /**
+     * 20.12.7, clocks:
+     */
+
+    class system_clock
+    {
+        public:
+            using rep        = int64_t;
+            using period     = micro;
+            using duration   = chrono::duration<rep, period>;
+            using time_point = chrono::time_point<system_clock>;
+
+            // TODO: is it steady?
+            static constexpr bool is_steady = true;
+
+            static time_point now()
+            {
+                hel::timeval tv{};
+                hel::gettimeofday(&tv, nullptr);
+
+                rep time = tv.tv_usec;
+                time += (tv.tv_sec * 1'000'000ul);
+
+                return time_point{duration{time - epoch_usecs}};
+            }
+
+            static time_t to_time_t(const time_point& tp)
+            {
+                /* auto dur = tp.time_since_epoch(); */
+                /* auto time_t_dur = duration_cast<chrono::duration<time_t, seconds>>(dur); */
+
+                /* return time_t{time_t_dur.count()}; */
+                return time_t{};
+            }
+
+            static time_point from_time_t(time_t tt)
+            {
+                /* auto time_t_dur = chrono::duration<time_t, seconds>{tt}; */
+                /* auto dur = duration_cast<duration>(time_t_dur); */
+
+                /* return time_point{duration_cast<duration>(chrono::duration<time_t, seconds>{tt})}; */
+                return time_point{};
+            }
+
+        private:
+            static constexpr rep epoch_usecs{11644473600ul * 1'000'000ul};
+    };
+
+    class steady_clock
+    {
+        public:
+            using rep        = int64_t;
+            using period     = micro;
+            using duration   = chrono::duration<rep, period>;
+            using time_point = chrono::time_point<steady_clock>;
+
+            static constexpr bool is_steady = true;
+
+            static time_point now()
+            {
+                hel::timeval tv{};
+                hel::getuptime(&tv);
+
+                rep time = tv.tv_usec;
+                time += (tv.tv_sec * 1'000'000ul);
+
+                return time_point{duration{time}};
+            }
+    };
+
+    using high_resolution_clock = system_clock;
+}
+
+namespace std
+{
+    inline namespace literals
+    {
+        inline namespace chrono_literals
+        {
+            /**
+             * 20.125.8, suffixes for duration literals:
+             */
+
+            /**
+             * Note: According to the standard, literal suffixes that do not
+             *       start with an underscore are reserved for future standardization,
+             *       but since we are implementing the standard, we're going to ignore it.
+             *       This should work (according to their documentation) work for clang,
+             *       but that should be tested.
+             */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wliteral-suffix"
+
+            constexpr chrono::hours operator ""h(unsigned long long hrs)
+            {
+                return chrono::hours{static_cast<chrono::hours::rep>(hrs)};
+            }
+
+            constexpr chrono::duration<long double, ratio<3600>> operator ""h(long double hrs)
+            {
+                return chrono::duration<long double, ratio<3600>>{hrs};
+            }
+
+            constexpr chrono::minutes operator ""m(unsigned long long mins)
+            {
+                return chrono::minutes{static_cast<chrono::minutes::rep>(mins)};
+            }
+
+            constexpr chrono::duration<long double, ratio<60>> operator ""m(long double mins)
+            {
+                return chrono::duration<long double, ratio<60>>{mins};
+            }
+
+            constexpr chrono::seconds operator ""s(unsigned long long secs)
+            {
+                return chrono::seconds{static_cast<chrono::seconds::rep>(secs)};
+            }
+
+            constexpr chrono::duration<long double, ratio<1>> operator ""s(long double secs)
+            {
+                return chrono::duration<long double, ratio<1>>{secs};
+            }
+
+            constexpr chrono::milliseconds operator ""ms(unsigned long long msecs)
+            {
+                return chrono::milliseconds{static_cast<chrono::milliseconds::rep>(msecs)};
+            }
+
+            constexpr chrono::duration<long double, milli> operator ""ms(long double msecs)
+            {
+                return chrono::duration<long double, milli>{msecs};
+            }
+
+            constexpr chrono::microseconds operator ""us(unsigned long long usecs)
+            {
+                return chrono::microseconds{static_cast<chrono::microseconds::rep>(usecs)};
+            }
+
+            constexpr chrono::duration<long double, micro> operator ""us(long double usecs)
+            {
+                return chrono::duration<long double, micro>{usecs};
+            }
+
+            constexpr chrono::nanoseconds operator ""ns(unsigned long long nsecs)
+            {
+                return chrono::nanoseconds{static_cast<chrono::nanoseconds::rep>(nsecs)};
+            }
+
+            constexpr chrono::duration<long double, nano> operator ""ns(long double nsecs)
+            {
+                return chrono::duration<long double, nano>{nsecs};
+            }
+
+#pragma GCC diagnostic pop
+        }
+    }
+
+    namespace chrono
+    {
+        using namespace literals::chrono_literals;
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/common.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/common.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/common.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,2 +1,30 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #ifndef LIBCPP_BITS_COMMON
 #define LIBCPP_BITS_COMMON
Index: uspace/lib/cpp/include/__bits/complex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/complex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/complex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,977 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_COMPLEX
+#define LIBCPP_BITS_COMPLEX
+
+#include <iosfwd>
+#include <sstream>
+
+namespace std
+{
+    template<class T>
+    class complex
+    {
+        public:
+            using value_type = T;
+
+            constexpr complex(const value_type& re = value_type{},
+                              const value_type& im = value_type{})
+                : real_{re}, imag_{im}
+            { /* DUMMY BODY */ }
+
+            constexpr complex(const complex& other)
+                : real_{other.real_}, imag_{other.imag_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            constexpr complex(const complex<U>& other)
+                : real_(other.real()), imag_(other.imag())
+            { /* DUMMY BODY */ }
+
+            constexpr value_type real() const
+            {
+                return real_;
+            }
+
+            void real(value_type val)
+            {
+                real_ = val;
+            }
+
+            constexpr value_type imag() const
+            {
+                return imag_;
+            }
+
+            void imag(value_type val)
+            {
+                imag_ = val;
+            }
+
+            complex& operator=(const value_type& val)
+            {
+                real_ = val;
+                imag_ = value_type{};
+
+                return *this;
+            }
+
+            complex& operator+=(const value_type& val)
+            {
+                real_ += val;
+
+                return *this;
+            }
+
+            complex& operator-=(const value_type& val)
+            {
+                real_ -= val;
+
+                return *this;
+            }
+
+            complex& operator*=(const value_type& val)
+            {
+                real_ *= val;
+                imag_ *= val;
+
+                return *this;
+            }
+
+            complex& operator/=(const value_type& val)
+            {
+                real_ /= val;
+                imag_ /= val;
+
+                return *this;
+            }
+
+            complex& operator=(const complex& other)
+            {
+                real_ = other.real_;
+                imag_ = other.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator=(const complex<U>& rhs)
+            {
+                real_ = rhs.real_;
+                imag_ = rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator+=(const complex<U>& rhs)
+            {
+                real_ += rhs.real_;
+                imag_ += rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator-=(const complex<U>& rhs)
+            {
+                real_ -= rhs.real_;
+                imag_ -= rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator*=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
+                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator/=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+
+                return *this;
+            }
+
+        private:
+            value_type real_;
+            value_type imag_;
+    };
+
+    template<>
+    class complex<float>
+    {
+        public:
+            using value_type = float;
+
+            constexpr complex(const value_type& re = value_type{},
+                              const value_type& im = value_type{})
+                : real_{re}, imag_{im}
+            { /* DUMMY BODY */ }
+
+            constexpr complex(const complex& other)
+                : real_{other.real_}, imag_{other.imag_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            constexpr complex(const complex<U>& other)
+                : real_(other.real()), imag_(other.imag())
+            { /* DUMMY BODY */ }
+
+            constexpr value_type real() const
+            {
+                return real_;
+            }
+
+            void real(value_type val)
+            {
+                real_ = val;
+            }
+
+            constexpr value_type imag() const
+            {
+                return imag_;
+            }
+
+            void imag(value_type val)
+            {
+                imag_ = val;
+            }
+
+            complex& operator=(const value_type& val)
+            {
+                real_ = val;
+                imag_ = value_type{};
+
+                return *this;
+            }
+
+            complex& operator+=(const value_type& val)
+            {
+                real_ += val;
+
+                return *this;
+            }
+
+            complex& operator-=(const value_type& val)
+            {
+                real_ -= val;
+
+                return *this;
+            }
+
+            complex& operator*=(const value_type& val)
+            {
+                real_ *= val;
+                imag_ *= val;
+
+                return *this;
+            }
+
+            complex& operator/=(const value_type& val)
+            {
+                real_ /= val;
+                imag_ /= val;
+
+                return *this;
+            }
+
+            complex& operator=(const complex& other)
+            {
+                real_ = other.real_;
+                imag_ = other.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator=(const complex<U>& rhs)
+            {
+                real_ = rhs.real_;
+                imag_ = rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator+=(const complex<U>& rhs)
+            {
+                real_ += rhs.real_;
+                imag_ += rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator-=(const complex<U>& rhs)
+            {
+                real_ -= rhs.real_;
+                imag_ -= rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator*=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
+                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator/=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+
+                return *this;
+            }
+
+        private:
+            value_type real_;
+            value_type imag_;
+    };
+
+    template<>
+    class complex<double>
+    {
+        public:
+            using value_type = double;
+
+            constexpr complex(const value_type& re = value_type{},
+                              const value_type& im = value_type{})
+                : real_{re}, imag_{im}
+            { /* DUMMY BODY */ }
+
+            constexpr complex(const complex& other)
+                : real_{other.real_}, imag_{other.imag_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            constexpr complex(const complex<U>& other)
+                : real_(other.real()), imag_(other.imag())
+            { /* DUMMY BODY */ }
+
+            constexpr value_type real() const
+            {
+                return real_;
+            }
+
+            void real(value_type val)
+            {
+                real_ = val;
+            }
+
+            constexpr value_type imag() const
+            {
+                return imag_;
+            }
+
+            void imag(value_type val)
+            {
+                imag_ = val;
+            }
+
+            complex& operator=(const value_type& val)
+            {
+                real_ = val;
+                imag_ = value_type{};
+
+                return *this;
+            }
+
+            complex& operator+=(const value_type& val)
+            {
+                real_ += val;
+
+                return *this;
+            }
+
+            complex& operator-=(const value_type& val)
+            {
+                real_ -= val;
+
+                return *this;
+            }
+
+            complex& operator*=(const value_type& val)
+            {
+                real_ *= val;
+                imag_ *= val;
+
+                return *this;
+            }
+
+            complex& operator/=(const value_type& val)
+            {
+                real_ /= val;
+                imag_ /= val;
+
+                return *this;
+            }
+
+            complex& operator=(const complex& other)
+            {
+                real_ = other.real_;
+                imag_ = other.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator=(const complex<U>& rhs)
+            {
+                real_ = rhs.real_;
+                imag_ = rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator+=(const complex<U>& rhs)
+            {
+                real_ += rhs.real_;
+                imag_ += rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator-=(const complex<U>& rhs)
+            {
+                real_ -= rhs.real_;
+                imag_ -= rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator*=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
+                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator/=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+
+                return *this;
+            }
+
+        private:
+            value_type real_;
+            value_type imag_;
+    };
+
+    template<>
+    class complex<long double>
+    {
+        public:
+            using value_type = long double;
+
+            constexpr complex(const value_type& re = value_type{},
+                              const value_type& im = value_type{})
+                : real_{re}, imag_{im}
+            { /* DUMMY BODY */ }
+
+            constexpr complex(const complex& other)
+                : real_{other.real_}, imag_{other.imag_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            constexpr complex(const complex<U>& other)
+                : real_(other.real()), imag_(other.imag())
+            { /* DUMMY BODY */ }
+
+            constexpr value_type real() const
+            {
+                return real_;
+            }
+
+            void real(value_type val)
+            {
+                real_ = val;
+            }
+
+            constexpr value_type imag() const
+            {
+                return imag_;
+            }
+
+            void imag(value_type val)
+            {
+                imag_ = val;
+            }
+
+            complex& operator=(const value_type& val)
+            {
+                real_ = val;
+                imag_ = value_type{};
+
+                return *this;
+            }
+
+            complex& operator+=(const value_type& val)
+            {
+                real_ += val;
+
+                return *this;
+            }
+
+            complex& operator-=(const value_type& val)
+            {
+                real_ -= val;
+
+                return *this;
+            }
+
+            complex& operator*=(const value_type& val)
+            {
+                real_ *= val;
+                imag_ *= val;
+
+                return *this;
+            }
+
+            complex& operator/=(const value_type& val)
+            {
+                real_ /= val;
+                imag_ /= val;
+
+                return *this;
+            }
+
+            complex& operator=(const complex& other)
+            {
+                real_ = other.real_;
+                imag_ = other.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator=(const complex<U>& rhs)
+            {
+                real_ = rhs.real_;
+                imag_ = rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator+=(const complex<U>& rhs)
+            {
+                real_ += rhs.real_;
+                imag_ += rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator-=(const complex<U>& rhs)
+            {
+                real_ -= rhs.real_;
+                imag_ -= rhs.imag_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator*=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
+                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
+
+                return *this;
+            }
+
+            template<class U>
+            complex& operator/=(const complex<U>& rhs)
+            {
+                auto old_real = real_;
+                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+                imag_ = (imag_ * rhs.real_ - old_real* rhs.imag_)
+                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
+
+                return *this;
+            }
+
+        private:
+            value_type real_;
+            value_type imag_;
+    };
+
+    /**
+     * 26.4.6, operators:
+     */
+
+    template<class T>
+    complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} += rhs;
+    }
+
+    template<class T>
+    complex<T> operator+(const complex<T>& lhs, const T& rhs)
+    {
+        return complex<T>{lhs} += rhs;
+    }
+
+    template<class T>
+    complex<T> operator+(const T& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} += rhs;
+    }
+
+    template<class T>
+    complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} -= rhs;
+    }
+
+    template<class T>
+    complex<T> operator-(const complex<T>& lhs, const T& rhs)
+    {
+        return complex<T>{lhs} -= rhs;
+    }
+
+    template<class T>
+    complex<T> operator-(const T& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} -= rhs;
+    }
+
+    template<class T>
+    complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} *= rhs;
+    }
+
+    template<class T>
+    complex<T> operator*(const complex<T>& lhs, const T& rhs)
+    {
+        return complex<T>{lhs} *= rhs;
+    }
+
+    template<class T>
+    complex<T> operator*(const T& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} *= rhs;
+    }
+
+    template<class T>
+    complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} /= rhs;
+    }
+
+    template<class T>
+    complex<T> operator/(const complex<T>& lhs, const T& rhs)
+    {
+        return complex<T>{lhs} /= rhs;
+    }
+
+    template<class T>
+    complex<T> operator/(const T& lhs, const complex<T>& rhs)
+    {
+        return complex<T>{lhs} /= rhs;
+    }
+
+    template<class T>
+    complex<T> operator+(const complex<T>& c)
+    {
+        return complex<T>{c};
+    }
+
+    template<class T>
+    complex<T> operator-(const complex<T>& c)
+    {
+        return complex<T>{-c.real(), -c.imag()};
+    }
+
+    template<class T>
+    constexpr bool operator==(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
+    }
+
+    template<class T>
+    constexpr bool operator==(const complex<T>& lhs, const T& rhs)
+    {
+        return lhs.real() == rhs && lhs.imag() == T{};
+    }
+
+    template<class T>
+    constexpr bool operator==(const T& lhs, const complex<T>& rhs)
+    {
+        return lhs == rhs.real() && T{} == rhs.imag();
+    }
+
+    template<class T>
+    constexpr bool operator!=(const complex<T>& lhs, const complex<T>& rhs)
+    {
+        return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
+    }
+
+    template<class T>
+    constexpr bool operator!=(const complex<T>& lhs, const T& rhs)
+    {
+        return lhs.real() != rhs || lhs.imag() != T{};
+    }
+
+    template<class T>
+    constexpr bool operator!=(const T& lhs, const complex<T>& rhs)
+    {
+        return lhs != rhs.real() || T{} != rhs.imag();
+    }
+
+    template<class T, class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            const complex<T>& c)
+    {
+        // TODO: implement
+    }
+
+    template<class T, class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            const complex<T>& c)
+    {
+        basic_ostringstream<Char, Traits> oss{};
+        oss.flags(os.flags());
+        oss.imbue(os.getloc());
+        oss.precision(os.precision());
+
+        oss << "(" << c.real() << "," << c.imag() << ")";
+
+        return os << oss.str();
+    }
+
+    /**
+     * 26.4.7, values:
+     */
+
+    template<class T>
+    constexpr T real(const complex<T>& c)
+    {
+        return c.real();
+    }
+
+    template<class T>
+    constexpr T imag(const complex<T>& c)
+    {
+        return c.imag();
+    }
+
+    template<class T>
+    T abs(const complex<T>& c)
+    {
+        return c.real() * c.real() + c.imag() * c.imag();
+    }
+
+    template<class T>
+    T arg(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    T norm(const complex<T>& c)
+    {
+        return abs(c) * abs(c);
+    }
+
+    template<class T>
+    complex<T> conj(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> proj(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> polar(const T&, const T& = T{})
+    {
+        // TODO: implement
+        return complex<T>{};
+    }
+
+    /**
+     * 26.4.8, transcendentals:
+     */
+
+    template<class T>
+    complex<T> acos(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> asin(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> atan(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> acosh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> asinh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> atanh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> cos(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> cosh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> exp(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> log(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> log10(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> pow(const complex<T>& base, const T& exp)
+    {
+        // TODO: implement
+        return base;
+    }
+
+    template<class T>
+    complex<T> pow(const complex<T>& base, const complex<T>& exp)
+    {
+        // TODO: implement
+        return base;
+    }
+
+    template<class T>
+    complex<T> pow(const T& base, const complex<T>& exp)
+    {
+        // TODO: implement
+        return complex<T>{base};
+    }
+
+    template<class T>
+    complex<T> sin(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> sinh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> sqrt(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> tan(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    template<class T>
+    complex<T> tanh(const complex<T>& c)
+    {
+        // TODO: implement
+        return c;
+    }
+
+    /**
+     * 26.4.10, complex literals:
+     */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wliteral-suffix"
+inline namespace literals {
+inline namespace complex_literals
+{
+    constexpr complex<long double> operator ""il(long double val)
+    {
+        return complex<long double>{0.0L, val};
+    }
+
+    constexpr complex<long double> operator ""il(unsigned long long val)
+    {
+        return complex<long double>{0.0L, static_cast<long double>(val)};
+    }
+
+    constexpr complex<double> operator ""i(long double val)
+    {
+        return complex<double>{0.0, static_cast<double>(val)};
+    }
+
+    constexpr complex<double> operator ""i(unsigned long long val)
+    {
+        return complex<double>{0.0, static_cast<double>(val)};
+    }
+
+    constexpr complex<float> operator ""if(long double val)
+    {
+        return complex<float>{0.0f, static_cast<float>(val)};
+    }
+
+    constexpr complex<float> operator ""if(unsigned long long val)
+    {
+        return complex<float>{0.0f, static_cast<float>(val)};
+    }
+}}
+#pragma GCC diagnostic pop
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/exception.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/exception.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/exception.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_EXCEPTION
+#define LIBCPP_BITS_EXCEPTION
+
+#include <__bits/trycatch.hpp>
+
+namespace std
+{
+    /**
+     * 18.8.1, class exception:
+     */
+
+    class exception
+    {
+        public:
+            exception() noexcept = default;
+            exception(const exception&) noexcept = default;
+            exception& operator=(const exception&) noexcept = default;
+            virtual ~exception() = default;
+
+            virtual const char* what() const noexcept;
+    };
+
+    /**
+     * 18.8.2, class bad_exception:
+     */
+
+    class bad_exception: public exception
+    {
+        public:
+            bad_exception() noexcept = default;
+            bad_exception(const bad_exception&) noexcept = default;
+            bad_exception& operator=(const bad_exception&) noexcept = default;
+
+            virtual const char* what() const noexcept;
+    };
+
+    /**
+     * 18.8.3, abnormal termination:
+     */
+
+    using terminate_handler = void (*)();
+
+    terminate_handler get_terminate() noexcept;
+    terminate_handler set_terminate(terminate_handler) noexcept;
+    [[noreturn]] void terminate() noexcept;
+
+    /**
+     * 18.8.4, uncaght_exceptions:
+     */
+
+    bool uncaught_exception() noexcept;
+    int uncaught_exceptions() noexcept;
+
+    using unexpected_handler = void (*)();
+
+    unexpected_handler get_unexpected() noexcept;
+    unexpected_handler set_unexpected(unexpected_handler) noexcept;
+    [[noreturn]] void unexpected();
+
+    /**
+     * 18.8.5, exception propagation:
+     */
+
+    namespace aux
+    {
+        class exception_ptr_t
+        { /* DUMMY BODY */ };
+    }
+
+    using exception_ptr = aux::exception_ptr_t;
+
+    exception_ptr current_exception() noexcept;
+    [[noreturn]] void rethrow_exception(exception_ptr);
+
+    template<class E>
+    exception_ptr make_exception_ptr(E e) noexcept
+    {
+        return exception_ptr{};
+    }
+
+    class nested_exception
+    {
+        public:
+            nested_exception() noexcept = default;
+            nested_exception(const nested_exception&) noexcept = default;
+            nested_exception& operator=(const nested_exception&) noexcept = default;
+            virtual ~nested_exception() = default;
+
+            [[noreturn]] void throw_nested() const;
+            exception_ptr nested_ptr() const noexcept;
+
+        private:
+            exception_ptr ptr_;
+    };
+
+    template<class E>
+    [[noreturn]] void throw_with_nested(E&& e)
+    {
+        terminate();
+    }
+
+    template<class E>
+    void rethrow_if_nested(const E& e)
+    {
+        auto casted = dynamic_cast<const nested_exception*>(&e);
+        if (casted)
+            casted->throw_nested();
+    }
+}
+
+#endif
+
Index: uspace/lib/cpp/include/__bits/functional/function.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/functional/function.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/functional/function.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -32,6 +32,9 @@
 #include <__bits/functional/conditional_function_typedefs.hpp>
 #include <__bits/functional/reference_wrapper.hpp>
+#include <__bits/memory/allocator_arg.hpp>
+#include <__bits/memory/allocator_traits.hpp>
 #include <typeinfo>
 #include <type_traits>
+#include <utility>
 
 namespace std
Index: uspace/lib/cpp/include/__bits/functional/functional.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/functional/functional.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/functional/functional.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_FUNCTIONAL
+#define LIBCPP_BITS_FUNCTIONAL
+
+#include <__bits/functional/conditional_function_typedefs.hpp>
+#include <__bits/functional/invoke.hpp>
+#include <limits>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 20.9.3, invoke:
+     */
+
+    template<class F, class... Args>
+    decltype(auto) invoke(F&& f, Args&&... args)
+    {
+        return aux::INVOKE(forward<F>(f)(forward<Args>(args)...));
+    }
+
+    /**
+     * 20.9.11, member function adaptors:
+     */
+
+    namespace aux
+    {
+        template<class F>
+        class mem_fn_t
+            : public conditional_function_typedefs<remove_cv_t<remove_reference_t<F>>>
+        {
+            public:
+                mem_fn_t(F f)
+                    : func_{f}
+                { /* DUMMY BODY */ }
+
+                template<class... Args>
+                decltype(auto) operator()(Args&&... args)
+                {
+                    return INVOKE(func_, forward<Args>(args)...);
+                }
+
+            private:
+                F func_;
+        };
+    }
+
+    template<class R, class T>
+    aux::mem_fn_t<R T::*> mem_fn(R T::* f)
+    {
+        return aux::mem_fn_t<R T::*>{f};
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/hash_table.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/hash_table.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,595 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_HASH_TABLE
-#define LIBCPP_BITS_HASH_TABLE
-
-#include <cstdlib>
-#include <__bits/list_node.hpp>
-#include <__bits/key_extractors.hpp>
-#include <__bits/hash_table_iterators.hpp>
-#include <__bits/hash_table_policies.hpp>
-#include <iterator>
-#include <limits>
-#include <memory>
-#include <tuple>
-#include <utility>
-
-namespace std::aux
-{
-    /**
-     * To save code, we're going to implement one hash table
-     * for both unordered_map and unordered_set. To do this,
-     * we create one inner hash table that is oblivious to its
-     * held type (and uses a key extractor to get the key from it)
-     * and two proxies that either use plain Key type or a pair
-     * of a key and a value.
-     * Additionally, we will use policies to represent both single
-     * and multi variants of these containers at once.
-     * Note: I am aware the naming is very unimaginative here,
-     *       not my strong side :)
-     */
-
-    template<
-        class Value, class Key, class KeyExtractor,
-        class Hasher, class KeyEq,
-        class Alloc, class Size,
-        class Iterator, class ConstIterator,
-        class LocalIterator, class ConstLocalIterator,
-        class Policy
-    >
-    class hash_table
-    {
-        public:
-            using value_type     = Value;
-            using key_type       = Key;
-            using size_type      = Size;
-            using allocator_type = Alloc;
-            using key_equal      = KeyEq;
-            using hasher         = Hasher;
-            using key_extract    = KeyExtractor;
-
-            using iterator             = Iterator;
-            using const_iterator       = ConstIterator;
-            using local_iterator       = LocalIterator;
-            using const_local_iterator = ConstLocalIterator;
-
-            using node_type = list_node<value_type>;
-
-            using place_type = tuple<
-                hash_table_bucket<value_type, size_type>*,
-                list_node<value_type>*, size_type
-            >;
-
-            hash_table(size_type buckets, float max_load_factor = 1.f)
-                : table_{new hash_table_bucket<value_type, size_type>[buckets]()},
-                  bucket_count_{buckets}, size_{}, hasher_{}, key_eq_{},
-                  key_extractor_{}, max_load_factor_{max_load_factor}
-            { /* DUMMY BODY */ }
-
-            hash_table(size_type buckets, const hasher& hf, const key_equal& eql,
-                       float max_load_factor = 1.f)
-                : table_{new hash_table_bucket<value_type, size_type>[buckets]()},
-                  bucket_count_{buckets}, size_{}, hasher_{hf}, key_eq_{eql},
-                  key_extractor_{}, max_load_factor_{max_load_factor}
-            { /* DUMMY BODY */ }
-
-            hash_table(const hash_table& other)
-                : hash_table{other.bucket_count_, other.hasher_, other.key_eq_,
-                             other.max_load_factor_}
-            {
-                for (const auto& x: other)
-                    insert(x);
-            }
-
-            hash_table(hash_table&& other)
-                : table_{other.table_}, bucket_count_{other.bucket_count_},
-                  size_{other.size_}, hasher_{move(other.hasher_)},
-                  key_eq_{move(other.key_eq_)}, key_extractor_{move(other.key_extractor_)},
-                  max_load_factor_{other.max_load_factor_}
-            {
-                other.table_ = nullptr;
-                other.bucket_count_ = size_type{};
-                other.size_ = size_type{};
-                other.max_load_factor_ = 1.f;
-            }
-
-            hash_table& operator=(const hash_table& other)
-            {
-                hash_table tmp{other};
-                tmp.swap(*this);
-
-                return *this;
-            }
-
-            hash_table& operator=(hash_table&& other)
-            {
-                hash_table tmp{move(other)};
-                tmp.swap(*this);
-
-                return *this;
-            }
-
-            bool empty() const noexcept
-            {
-                return size_ == 0;
-            }
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type max_size(allocator_type& alloc)
-            {
-                return allocator_traits<allocator_type>::max_size(alloc);
-            }
-
-            iterator begin() noexcept
-            {
-                auto idx = first_filled_bucket_();
-                return iterator{
-                    table_, idx, bucket_count_,
-                    table_[idx].head
-                };
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return cbegin();
-            }
-
-            iterator end() noexcept
-            {
-                return iterator{};
-            }
-
-            const_iterator end() const noexcept
-            {
-                return cend();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                auto idx = first_filled_bucket_();
-                return const_iterator{
-                    table_, idx, bucket_count_,
-                    table_[idx].head
-                };
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return const_iterator{};
-            }
-
-            template<class... Args>
-            auto emplace(Args&&... args)
-            {
-                return Policy::emplace(*this, forward<Args>(args)...);
-            }
-
-            auto insert(const value_type& val)
-            {
-                return Policy::insert(*this, val);
-            }
-
-            auto insert(value_type&& val)
-            {
-                return Policy::insert(*this, forward<value_type>(val));
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return Policy::erase(*this, key);
-            }
-
-            iterator erase(const_iterator it)
-            {
-                auto node = it.node();
-                auto idx = it.idx();
-
-                /**
-                 * Note: This way we will continue on the next bucket
-                 *       if this is the last element in its bucket.
-                 */
-                iterator res{table_, idx, size_, node};
-                ++res;
-
-                if (table_[idx].head == node)
-                {
-                    if (node->next != node)
-                        table_[idx].head = node->next;
-                    else
-                        table_[idx].head = nullptr;
-                }
-                --size_;
-
-                node->unlink();
-                delete node;
-
-                return res;
-            }
-
-            void clear() noexcept
-            {
-                for (size_type i = 0; i < bucket_count_; ++i)
-                    table_[i].clear();
-                size_ = size_type{};
-            }
-
-            void swap(hash_table& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(swap(declval<Hasher&>(), declval<Hasher&>())) &&
-                         noexcept(swap(declval<KeyEq&>(), declval<KeyEq&>())))
-            {
-                std::swap(table_, other.table_);
-                std::swap(bucket_count_, other.bucket_count_);
-                std::swap(size_, other.size_);
-                std::swap(hasher_, other.hasher_);
-                std::swap(key_eq_, other.key_eq_);
-                std::swap(max_load_factor_, other.max_load_factor_);
-            }
-
-            hasher hash_function() const
-            {
-                return hasher_;
-            }
-
-            key_equal key_eq() const
-            {
-                return key_eq_;
-            }
-
-            iterator find(const key_type& key)
-            {
-                auto idx = get_bucket_idx_(key);
-                auto head = table_[idx].head;
-
-                if (!head)
-                    return end();
-
-                auto current = head;
-                do
-                {
-                    if (key_eq_(key, key_extractor_(current->value)))
-                        return iterator{table_, idx, size_, current};
-                    current = current->next;
-                }
-                while (current != head);
-
-                return end();
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                auto idx = get_bucket_idx_(key);
-                auto head = table_[idx].head;
-
-                if (!head)
-                    return end();
-
-                auto current = head;
-                do
-                {
-                    if (key_eq_(key, key_extractor_(current->value)))
-                        return iterator{table_, idx, size_, current};
-                    current = current->next;
-                }
-                while (current != head);
-
-                return end();
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return Policy::count(*this, key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return Policy::equal_range(*this, key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return Policy::equal_range_const(*this, key);
-            }
-
-            size_type bucket_count() const noexcept
-            {
-                return bucket_count_;
-            }
-
-            size_type max_bucket_count() const noexcept
-            {
-                return numeric_limits<size_type>::max() /
-                       sizeof(hash_table_bucket<value_type, size_type>);
-            }
-
-            size_type bucket_size(size_type n) const
-            {
-                return table_[n].size();
-            }
-
-            size_type bucket(const key_type& key) const
-            {
-                return get_bucket_idx_(key);
-            }
-
-            local_iterator begin(size_type n)
-            {
-                return local_iterator{table_[n].head, table_[n].head};
-            }
-
-            const_local_iterator begin(size_type n) const
-            {
-                return cbegin(n);
-            }
-
-            local_iterator end(size_type n)
-            {
-                return local_iterator{};
-            }
-
-            const_local_iterator end(size_type n) const
-            {
-                return cend(n);
-            }
-
-            const_local_iterator cbegin(size_type n) const
-            {
-                return const_local_iterator{table_[n].head, table_[n].head};
-            }
-
-            const_local_iterator cend(size_type n) const
-            {
-                return const_local_iterator{};
-            }
-
-            float load_factor() const noexcept
-            {
-                return size_ / static_cast<float>(bucket_count_);
-            }
-
-            float max_load_factor() const noexcept
-            {
-                return max_load_factor_;
-            }
-
-            void max_load_factor(float factor)
-            {
-                if (factor > 0.f)
-                    max_load_factor_ = factor;
-
-                rehash_if_needed();
-            }
-
-            void rehash(size_type count)
-            {
-                if (count < size_ / max_load_factor_)
-                    count = size_ / max_load_factor_;
-
-                /**
-                 * Note: If an exception is thrown, there
-                 *       is no effect. Since this is the only
-                 *       place where an exception (no mem) can
-                 *       be thrown and no changes to this have been
-                 *       made, we're ok.
-                 */
-                hash_table new_table{count, max_load_factor_};
-
-                for (std::size_t i = 0; i < bucket_count_; ++i)
-                {
-                    auto head = table_[i].head;
-                    if (!head)
-                        continue;
-
-                    auto current = head;
-
-                    do
-                    {
-                        auto next = current->next;
-
-                        current->next = current;
-                        current->prev = current;
-
-                        auto where = Policy::find_insertion_spot(
-                            new_table, key_extractor_(current->value)
-                        );
-
-                        /**
-                         * Note: We're rehashing, so we know each
-                         *       key can be inserted.
-                         */
-                        auto new_bucket = get<0>(where);
-                        auto new_successor = get<1>(where);
-
-                        if (new_successor)
-                            new_successor->append(current);
-                        else
-                            new_bucket->append(current);
-
-                        current = next;
-                    } while (current != head);
-
-                    table_[i].head = nullptr;
-                }
-
-                new_table.size_ = size_;
-                swap(new_table);
-
-                delete[] new_table.table_;
-                new_table.table_ = nullptr;
-            }
-
-            void reserve(size_type count)
-            {
-                rehash(count / max_load_factor_ + 1);
-            }
-
-            bool is_eq_to(const hash_table& other) const
-            {
-                if (size() != other.size())
-                    return false;
-
-                auto it = begin();
-                while (it != end())
-                {
-                    /**
-                     * For each key K we will check how many
-                     * instances of K are there in the table.
-                     * Then we will check if the count for K
-                     * is equal to that amount.
-                     */
-
-                    size_type cnt{};
-                    auto tmp = it;
-
-                    while (key_eq_(key_extractor_(*it), key_extractor_(*tmp)))
-                    {
-                        ++cnt;
-                        if (++tmp == end())
-                            break;
-                    }
-
-                    auto other_cnt = other.count(key_extractor_(*it));
-                    if (cnt != other_cnt)
-                        return false;
-
-                    it = tmp; // tmp  is one past *it's key.
-                }
-
-                return true;
-            }
-
-            ~hash_table()
-            {
-                // Lists are deleted in ~hash_table_bucket.
-                if (table_)
-                    delete[] table_;
-            }
-
-            place_type find_insertion_spot(const key_type& key) const
-            {
-                return Policy::find_insertion_spot(*this, key);
-            }
-
-            place_type find_insertion_spot(key_type&& key) const
-            {
-                return Policy::find_insertion_spot(*this, key);
-            }
-
-            const key_type& get_key(const value_type& val) const
-            {
-                return key_extractor_(val);
-            }
-
-            bool keys_equal(const key_type& key, const value_type& val)
-            {
-                return key_eq_(key, key_extractor_(val));
-            }
-
-            bool keys_equal(const key_type& key, const value_type& val) const
-            {
-                return key_eq_(key, key_extractor_(val));
-            }
-
-            hash_table_bucket<value_type, size_type>* table()
-            {
-                return table_;
-            }
-
-            hash_table_bucket<value_type, size_type>* head(size_type idx)
-            {
-                if (idx < bucket_count_)
-                    return table_[idx]->head;
-                else
-                    return nullptr;
-            }
-
-            void rehash_if_needed()
-            {
-                if (size_ > max_load_factor_ * bucket_count_)
-                    rehash(bucket_count_ * bucket_count_growth_factor_);
-            }
-
-            void increment_size()
-            {
-                ++size_;
-
-                rehash_if_needed();
-            }
-
-            void decrement_size()
-            {
-                --size_;
-            }
-
-        private:
-            hash_table_bucket<value_type, size_type>* table_;
-            size_type bucket_count_;
-            size_type size_;
-            hasher hasher_;
-            key_equal key_eq_;
-            key_extract key_extractor_;
-            float max_load_factor_;
-
-            static constexpr float bucket_count_growth_factor_{1.25};
-
-            size_type get_bucket_idx_(const key_type& key) const
-            {
-                return hasher_(key) % bucket_count_;
-            }
-
-            size_type first_filled_bucket_() const
-            {
-                size_type res{};
-                while (res < bucket_count_)
-                {
-                    if (table_[res].head)
-                        return res;
-                    ++res;
-                }
-
-                /**
-                 * Note: This is used for iterators,
-                 *       so we need to return a valid index.
-                 *       But since table_[0].head is nullptr
-                 *       we know that if we return 0 the
-                 *       created iterator will test as equal
-                 *       to end().
-                 */
-                return 0;
-            }
-
-            friend Policy;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/hash_table_bucket.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/hash_table_bucket.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,106 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_HASH_TABLE_BUCKET
-#define LIBCPP_BITS_HASH_TABLE_BUCKET
-
-#include <__bits/list_node.hpp>
-
-namespace std::aux
-{
-    template<class Value, class Size>
-    struct hash_table_bucket
-    {
-        /**
-         * Note: We use a doubly linked list because
-         *       we need to use hints, which point to the
-         *       element after the hinted spot.
-         */
-
-        list_node<Value>* head;
-
-        hash_table_bucket()
-            : head{}
-        { /* DUMMY BODY */ }
-
-        Size size() const noexcept
-        {
-            auto current = head;
-            Size res{};
-
-            do
-            {
-                ++res;
-                current = current->next;
-            }
-            while (current != head);
-
-            return res;
-        }
-
-        void append(list_node<Value>* node)
-        {
-            if (!head)
-                head = node;
-            else
-                head->append(node);
-        }
-
-        void prepend(list_node<Value>* node)
-        {
-            if (!head)
-                head = node;
-            else
-                head->prepend(node);
-        }
-
-        void clear()
-        {
-            if (!head)
-                return;
-
-            auto current = head;
-            do
-            {
-                auto tmp = current;
-                current = current->next;
-                delete tmp;
-            }
-            while (current != head);
-
-            head = nullptr;
-        }
-
-        ~hash_table_bucket()
-        {
-            clear();
-        }
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/hash_table_iterators.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/hash_table_iterators.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,485 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_HASH_TABLE_ITERATORS
-#define LIBCPP_BITS_HASH_TABLE_ITERATORS
-
-#include <__bits/iterator.hpp>
-#include <__bits/list_node.hpp>
-#include <__bits/hash_table_bucket.hpp>
-#include <iterator>
-
-namespace std::aux
-{
-    template<class Value, class Reference, class Pointer, class Size>
-    class hash_table_iterator
-    {
-        public:
-            using value_type      = Value;
-            using size_type       = Size;
-            using reference       = Reference;
-            using pointer         = Pointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = forward_iterator_tag;
-
-            hash_table_iterator(hash_table_bucket<value_type, size_type>* table = nullptr,
-                                size_type idx = size_type{}, size_type max_idx = size_type{},
-                                list_node<value_type>* current = nullptr)
-                : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
-            { /* DUMMY BODY */ }
-
-            hash_table_iterator(const hash_table_iterator&) = default;
-            hash_table_iterator& operator=(const hash_table_iterator&) = default;
-
-            reference operator*()
-            {
-                return current_->value;
-            }
-
-            pointer operator->()
-            {
-                return &current_->value;
-            }
-
-            hash_table_iterator& operator++()
-            {
-                current_ = current_->next;
-                if (current_ == table_[idx_].head)
-                {
-                    if (idx_ < max_idx_)
-                    {
-                        while (!table_[++idx_].head && idx_ < max_idx_)
-                        { /* DUMMY BODY */ }
-
-                        if (idx_ < max_idx_)
-                            current_ = table_[idx_].head;
-                        else
-                            current_ = nullptr;
-                    }
-                    else
-                        current_ = nullptr;
-                }
-
-                return *this;
-            }
-
-            hash_table_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-            list_node<value_type>* node()
-            {
-                return current_;
-            }
-
-            const list_node<value_type>* node() const
-            {
-                return current_;
-            }
-
-            size_type idx() const
-            {
-                return idx_;
-            }
-
-        private:
-            hash_table_bucket<value_type, size_type>* table_;
-            size_type idx_;
-            size_type max_idx_;
-            list_node<value_type>* current_;
-
-            template<class V, class CR, class CP, class S>
-            friend class hash_table_const_iterator;
-    };
-
-    template<class Value, class Ref, class Ptr, class Size>
-    bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
-                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class Ref, class Ptr, class Size>
-    bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
-                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class ConstReference, class ConstPointer, class Size>
-    class hash_table_const_iterator
-    {
-        using non_const_iterator_type = hash_table_iterator<
-            Value, get_non_const_ref_t<ConstReference>,
-            get_non_const_ptr_t<ConstPointer>, Size
-        >;
-
-        public:
-            using value_type      = Value;
-            using size_type       = Size;
-            using const_reference = ConstReference;
-            using const_pointer   = ConstPointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = forward_iterator_tag;
-
-            hash_table_const_iterator(const hash_table_bucket<value_type, size_type>* table = nullptr,
-                                      size_type idx = size_type{}, size_type max_idx = size_type{},
-                                      const list_node<value_type>* current = nullptr)
-                : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
-            { /* DUMMY BODY */ }
-
-            hash_table_const_iterator(const hash_table_const_iterator&) = default;
-            hash_table_const_iterator& operator=(const hash_table_const_iterator&) = default;
-
-            hash_table_const_iterator(const non_const_iterator_type& other)
-                : table_{other.table_}, idx_{other.idx_}, max_idx_{other.max_idx_},
-                  current_{other.current_}
-            { /* DUMMY BODY */ }
-
-            hash_table_const_iterator& operator=(const non_const_iterator_type& other)
-            {
-                table_ = other.table_;
-                idx_ = other.idx_;
-                max_idx_ = other.max_idx_;
-                current_ = other.current_;
-
-                return *this;
-            }
-
-            const_reference operator*() const
-            {
-                return current_->value;
-            }
-
-            const_pointer operator->() const
-            {
-                return &current_->value;
-            }
-
-            hash_table_const_iterator& operator++()
-            {
-                current_ = current_->next;
-                if (current_ == table_[idx_].head)
-                {
-                    if (idx_ < max_idx_)
-                    {
-                        while (!table_[++idx_].head && idx_ < max_idx_)
-                        { /* DUMMY BODY */ }
-
-                        if (idx_ < max_idx_)
-                            current_ = table_[idx_].head;
-                        else
-                            current_ = nullptr;
-                    }
-                    else
-                        current_ = nullptr;
-                }
-
-                return *this;
-            }
-
-            hash_table_const_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-            list_node<value_type>* node()
-            {
-                return const_cast<list_node<value_type>*>(current_);
-            }
-
-            const list_node<value_type>* node() const
-            {
-                return current_;
-            }
-
-            size_type idx() const
-            {
-                return idx_;
-            }
-
-        private:
-            const hash_table_bucket<value_type, size_type>* table_;
-            size_type idx_;
-            size_type max_idx_;
-            const list_node<value_type>* current_;
-    };
-
-    template<class Value, class CRef, class CPtr, class Size>
-    bool operator==(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
-                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class CRef, class CPtr, class Size>
-    bool operator!=(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
-                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class Ref, class Ptr, class CRef, class CPtr, class Size>
-    bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
-                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class Ref, class Ptr, class CRef, class CPtr, class Size>
-    bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
-                    const hash_table_const_iterator<Value, CRef, CPtr, Size>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class CRef, class CPtr, class Ref, class Ptr, class Size>
-    bool operator==(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
-                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class CRef, class CPtr, class Ref, class Ptr, class Size>
-    bool operator!=(const hash_table_const_iterator<Value, CRef, CPtr, Size>& lhs,
-                    const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class Reference, class Pointer>
-    class hash_table_local_iterator
-    {
-        public:
-            using value_type      = Value;
-            using reference       = Reference;
-            using pointer         = Pointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = forward_iterator_tag;
-
-            hash_table_local_iterator(list_node<value_type>* head = nullptr,
-                                      list_node<value_type>* current = nullptr)
-                : head_{head}, current_{current}
-            { /* DUMMY BODY */ }
-
-            hash_table_local_iterator(const hash_table_local_iterator&) = default;
-            hash_table_local_iterator& operator=(const hash_table_local_iterator&) = default;
-
-            reference operator*()
-            {
-                return current_->value;
-            }
-
-            pointer operator->()
-            {
-                return &current_->value;
-            }
-
-            hash_table_local_iterator& operator++()
-            {
-                current_ = current_->next;
-                if (current_ == head_)
-                    current_ = nullptr;
-
-                return *this;
-            }
-
-            hash_table_local_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-            list_node<value_type>* node()
-            {
-                return current_;
-            }
-
-            const list_node<value_type>* node() const
-            {
-                return current_;
-            }
-
-        private:
-            list_node<value_type>* head_;
-            list_node<value_type>* current_;
-
-            template<class V, class CR, class CP>
-            friend class hash_table_const_local_iterator;
-    };
-
-    template<class Value, class Ref, class Ptr>
-    bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
-                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class Ref, class Ptr>
-    bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
-                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class ConstReference, class ConstPointer>
-    class hash_table_const_local_iterator
-    {
-        using non_const_iterator_type = hash_table_local_iterator<
-            Value, get_non_const_ref_t<ConstReference>,
-            get_non_const_ptr_t<ConstPointer>
-        >;
-
-        public:
-            using value_type      = Value;
-            using const_reference = ConstReference;
-            using const_pointer   = ConstPointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = forward_iterator_tag;
-
-            // TODO: requirement for forward iterator is default constructibility, fix others!
-            hash_table_const_local_iterator(const list_node<value_type>* head = nullptr,
-                                            const list_node<value_type>* current = nullptr)
-                : head_{head}, current_{current}
-            { /* DUMMY BODY */ }
-
-            hash_table_const_local_iterator(const hash_table_const_local_iterator&) = default;
-            hash_table_const_local_iterator& operator=(const hash_table_const_local_iterator&) = default;
-
-            hash_table_const_local_iterator(const non_const_iterator_type& other)
-                : head_{other.head_}, current_{other.current_}
-            { /* DUMMY BODY */ }
-
-            hash_table_const_local_iterator& operator=(const non_const_iterator_type& other)
-            {
-                head_ = other.head_;
-                current_ = other.current_;
-
-                return *this;
-            }
-
-            const_reference operator*() const
-            {
-                return current_->value;
-            }
-
-            const_pointer operator->() const
-            {
-                return &current_->value;
-            }
-
-            hash_table_const_local_iterator& operator++()
-            {
-                current_ = current_->next;
-                if (current_ == head_)
-                    current_ = nullptr;
-
-                return *this;
-            }
-
-            hash_table_const_local_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-
-            list_node<value_type>* node()
-            {
-                return const_cast<list_node<value_type>*>(current_);
-            }
-
-            const list_node<value_type>* node() const
-            {
-                return current_;
-            }
-
-        private:
-            const list_node<value_type>* head_;
-            const list_node<value_type>* current_;
-    };
-
-    template<class Value, class CRef, class CPtr>
-    bool operator==(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
-                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class CRef, class CPtr>
-    bool operator!=(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
-                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class Ref, class Ptr, class CRef, class CPtr>
-    bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
-                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class Ref, class Ptr, class CRef, class CPtr>
-    bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
-                    const hash_table_const_local_iterator<Value, CRef, CPtr>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class CRef, class CPtr, class Ref, class Ptr>
-    bool operator==(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
-                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
-    {
-        return lhs.node() == rhs.node();
-    }
-
-    template<class Value, class CRef, class CPtr, class Ref, class Ptr>
-    bool operator!=(const hash_table_const_local_iterator<Value, CRef, CPtr>& lhs,
-                    const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/hash_table_policies.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/hash_table_policies.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,435 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_HASH_TABLE_POLICIES
-#define LIBCPP_BITS_HASH_TABLE_POLICIES
-
-#include <tuple>
-#include <utility>
-
-namespace std::aux
-{
-    struct hash_single_policy
-    {
-        template<class Table, class Key>
-        static typename Table::size_type count(const Table& table, const Key& key)
-        {
-            return table.find(key) == table.end() ? 0 : 1;
-        }
-
-        template<class Table, class Key>
-        static typename Table::place_type find_insertion_spot(const Table& table, const Key& key)
-        {
-            auto idx = table.get_bucket_idx_(key);
-            return make_tuple(
-                &table.table_[idx],
-                table.table_[idx].head,
-                idx
-            );
-        }
-
-        template<class Table, class Key>
-        static typename Table::size_type erase(Table& table, const Key& key)
-        {
-            auto idx = table.get_bucket_idx_(key);
-            auto head = table.table_[idx].head;
-            auto current = head;
-
-            if (!current)
-                return 0;
-
-            do
-            {
-                if (table.keys_equal(key, current->value))
-                {
-                    --table.size_;
-
-                    if (current == head)
-                    {
-                        if (current->next != head)
-                            table.table_[idx].head = current->next;
-                        else
-                            table.table_[idx].head = nullptr;
-                    }
-
-                    current->unlink();
-                    delete current;
-
-                    return 1;
-                }
-                else
-                    current = current->next;
-            }
-            while (current != head);
-
-            return 0;
-        }
-
-        template<class Table, class Key>
-        static pair<
-            typename Table::iterator,
-            typename Table::iterator
-        > equal_range(Table& table, const Key& key)
-        {
-            auto it = table.find(key);
-            return make_pair(it, ++it);
-        }
-
-        template<class Table, class Key>
-        static pair<
-            typename Table::const_iterator,
-            typename Table::const_iterator
-        > equal_range_const(const Table& table, const Key& key)
-        { // Note: We cannot overload by return type, so we use a different name.
-            auto it = table.find(key);
-            return make_pair(it, ++it);
-        }
-
-        /**
-         * Note: We have to duplicate code for emplace, insert(const&)
-         *       and insert(&&) here, because the node (which makes distinction
-         *       between the arguments) is only created if the value isn't
-         *       in the table already.
-         */
-
-        template<class Table, class... Args>
-        static pair<
-            typename Table::iterator, bool
-        > emplace(Table& table, Args&&... args)
-        {
-            using value_type = typename Table::value_type;
-            using node_type  = typename Table::node_type;
-            using iterator   = typename Table::iterator;
-
-            table.increment_size();
-
-            auto val = value_type{forward<Args>(args)...};
-            const auto& key = table.get_key(val);
-            auto [bucket, target, idx] = table.find_insertion_spot(key);
-
-            if (!bucket)
-                return make_pair(table.end(), false);
-
-            if (target && table.keys_equal(key, target->value))
-            {
-                table.decrement_size();
-
-                return make_pair(
-                    iterator{
-                        table.table(), idx, table.bucket_count(),
-                        target
-                    },
-                    false
-                );
-            }
-            else
-            {
-                auto node = new node_type{move(val)};
-                bucket->prepend(node);
-
-                return make_pair(iterator{
-                    table.table(), idx,
-                    table.bucket_count(),
-                    node
-                }, true);
-            }
-        }
-
-        template<class Table, class Value>
-        static pair<
-            typename Table::iterator, bool
-        > insert(Table& table, const Value& val)
-        {
-            using node_type  = typename Table::node_type;
-            using iterator   = typename Table::iterator;
-
-            table.increment_size();
-
-            const auto& key = table.get_key(val);
-            auto [bucket, target, idx] = table.find_insertion_spot(key);
-
-            if (!bucket)
-                return make_pair(table.end(), false);
-
-            if (target && table.keys_equal(key, target->value))
-            {
-                table.decrement_size();
-
-                return make_pair(
-                    iterator{
-                        table.table(), idx, table.bucket_count(),
-                        target
-                    },
-                    false
-                );
-            }
-            else
-            {
-                auto node = new node_type{val};
-                bucket->prepend(node);
-
-                return make_pair(iterator{
-                    table.table(), idx,
-                    table.bucket_count(),
-                    node
-                }, true);
-            }
-        }
-
-        template<class Table, class Value>
-        static pair<
-            typename Table::iterator, bool
-        > insert(Table& table, Value&& val)
-        {
-            using value_type = typename Table::value_type;
-            using node_type  = typename Table::node_type;
-            using iterator   = typename Table::iterator;
-
-            table.increment_size();
-
-            const auto& key = table.get_key(val);
-            auto [bucket, target, idx] = table.find_insertion_spot(key);
-
-            if (!bucket)
-                return make_pair(table.end(), false);
-
-            if (target && table.keys_equal(key, target->value))
-            {
-                table.decrement_size();
-
-                return make_pair(
-                    iterator{
-                        table.table(), idx, table.bucket_count(),
-                        target
-                    },
-                    false
-                );
-            }
-            else
-            {
-                auto node = new node_type{forward<value_type>(val)};
-                bucket->prepend(node);
-
-                return make_pair(iterator{
-                    table.table(), idx,
-                    table.bucket_count(),
-                    node
-                }, true);
-            }
-        }
-    };
-
-    struct hash_multi_policy
-    {
-        template<class Table, class Key>
-        static typename Table::size_type count(const Table& table, const Key& key)
-        {
-            auto head = table.table_[table.get_bucket_idx_(key)].head;
-            if (!head)
-                return 0;
-
-            auto current = head;
-            typename Table::size_type res = 0;
-            do
-            {
-                if (table.keys_equal(key, current->value))
-                    ++res;
-
-                current = current->next;
-            }
-            while (current != head);
-
-            return res;
-        }
-
-        template<class Table, class Key>
-        static typename Table::place_type find_insertion_spot(const Table& table, const Key& key)
-        {
-            auto idx = table.get_bucket_idx_(key);
-            auto head = table.table_[idx].head;
-
-            if (head)
-            {
-                auto current = head;
-                do
-                {
-                    if (table.keys_equal(key, current->value))
-                    {
-                        return make_tuple(
-                            &table.table_[idx],
-                            current,
-                            idx
-                        );
-                    }
-
-                    current = current->next;
-                } while (current != head);
-            }
-
-            return make_tuple(
-                &table.table_[idx],
-                table.table_[idx].head,
-                idx
-            );
-        }
-
-        template<class Table, class Key>
-        static typename Table::size_type erase(Table& table, const Key& key)
-        {
-            auto idx = table.get_bucket_idx_(key);
-            auto head = table.table_[idx].head;
-            auto current = head;
-            table.table_[idx].head = nullptr;
-
-            if (!current)
-                return 0;
-
-            /**
-             * We traverse the list and delete if the keys
-             * equal, if they don't we append the nodes back
-             * to the bucket.
-             */
-            typename Table::size_type res{};
-
-            do
-            {
-                auto tmp = current;
-                current = current->next;
-
-                if (!table.keys_equal(key, tmp->value))
-                    table.table_[idx].append(tmp);
-                else
-                {
-                    ++res;
-                    --table.size_;
-
-                    delete tmp;
-                }
-            }
-            while (current != head);
-
-            return res;
-        }
-
-        template<class Table, class Key>
-        static pair<
-            typename Table::iterator,
-            typename Table::iterator
-        > equal_range(Table& table, const Key& key)
-        {
-            auto first = table.find(key);
-            if (first == table.end())
-                return make_pair(table.end(), table.end());
-
-            auto last = first;
-            do
-            {
-                ++last;
-            } while (table.keys_equal(key, *last));
-
-            return make_pair(first, last);
-        }
-
-        template<class Table, class Key>
-        static pair<
-            typename Table::const_iterator,
-            typename Table::const_iterator
-        > equal_range_const(const Table& table, const Key& key)
-        {
-            auto first = table.find(key);
-            if (first == table.end())
-                return make_pair(table.end(), table.end());
-
-            auto last = first;
-            do
-            {
-                ++last;
-            } while (table.keys_equal(key, *last));
-
-            return make_pair(first, last);
-        }
-
-        template<class Table, class... Args>
-        static typename Table::iterator emplace(Table& table, Args&&... args)
-        {
-            using node_type  = typename Table::node_type;
-
-            auto node = new node_type{forward<Args>(args)...};
-
-            return insert(table, node);
-        }
-
-        template<class Table, class Value>
-        static typename Table::iterator insert(Table& table, const Value& val)
-        {
-            using node_type  = typename Table::node_type;
-
-            auto node = new node_type{val};
-
-            return insert(table, node);
-        }
-
-        template<class Table, class Value>
-        static typename Table::iterator insert(Table& table, Value&& val)
-        {
-            using value_type = typename Table::value_type;
-            using node_type  = typename Table::node_type;
-
-            auto node = new node_type{forward<value_type>(val)};
-
-            return insert(table, node);
-        }
-
-        template<class Table>
-        static typename Table::iterator insert(Table& table, typename Table::node_type* node)
-        {
-            using iterator   = typename Table::iterator;
-
-            table.increment_size();
-
-            const auto& key = table.get_key(node->value);
-            auto [bucket, target, idx] = table.find_insertion_spot(key);
-
-            if (!bucket)
-                table.end();
-
-            if (target && table.keys_equal(key, target->value))
-                target->append(node);
-            else
-                bucket->prepend(node);
-
-            return iterator{
-                table.table(), idx,
-                table.bucket_count(),
-                node
-            };
-        }
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/io/fstream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_FSTREAM
+#define LIBCPP_BITS_IO_FSTREAM
+
+#include <cstdio>
+#include <ios>
+#include <iosfwd>
+#include <locale>
+#include <streambuf>
+#include <string>
+
+namespace std
+{
+    /**
+     * 27.9.1.1, class template basic_filebuf:
+     */
+    template<class Char, class Traits>
+    class basic_filebuf: public basic_streambuf<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.9.1.2, constructors/destructor:
+             */
+
+            basic_filebuf()
+                : basic_streambuf<char_type, traits_type>{},
+                  obuf_{nullptr}, ibuf_{nullptr}, mode_{}, file_{nullptr}
+            { /* DUMMY BODY */ }
+
+            basic_filebuf(const basic_filebuf&) = delete;
+
+            basic_filebuf(basic_filebuf&& other)
+                : mode_{other.mode_}
+            {
+                close();
+                std::swap(obuf_, other.obuf_);
+                std::swap(ibuf_, other.ibuf_);
+                std::swap(file_, other.file_);
+
+                basic_streambuf<char_type, traits_type>::swap(other);
+            }
+
+            virtual ~basic_filebuf()
+            {
+                // TODO: exception here caught and not rethrown
+                close();
+            }
+
+            /**
+             * 27.9.1.3: assign/swap:
+             */
+
+            basic_filebuf& operator=(const basic_filebuf&) = delete;
+
+            basic_filebuf& operator=(basic_filebuf&& other)
+            {
+                close();
+                swap(other);
+
+                return *this;
+            }
+
+            void swap(basic_filebuf& rhs)
+            {
+                std::swap(mode_, rhs.mode_);
+                std::swap(obuf_, rhs.obuf_);
+                std::swap(ibuf_, rhs.ibuf_);
+
+                basic_streambuf<char_type, traits_type>::swap(rhs);
+            }
+
+            /**
+             * 27.9.1.4, members:
+             */
+
+            bool is_open() const
+            {
+                return file_ != nullptr;
+            }
+
+            basic_filebuf<char_type, traits_type>* open(const char* name, ios_base::openmode mode)
+            {
+                if (file_)
+                    return nullptr;
+
+                mode_ = mode;
+                mode = (mode & (~ios_base::ate));
+                const char* mode_str = get_mode_str_(mode);
+
+                if (!mode_str)
+                    return nullptr;
+
+                file_ = fopen(name, mode_str);
+                if (!file_)
+                    return nullptr;
+
+                if ((mode_ & ios_base::ate) != 0)
+                {
+                    if (fseek(file_, 0, SEEK_END) != 0)
+                    {
+                        close();
+                        return nullptr;
+                    }
+                }
+
+                if (!ibuf_ && mode_is_in_(mode_))
+                    ibuf_ = new char_type[buf_size_];
+                if (!obuf_ && mode_is_out_(mode_))
+                    obuf_ = new char_type[buf_size_];
+                init_();
+
+                return this;
+            }
+
+            basic_filebuf<char_type, traits_type>* open(const string& name, ios_base::openmode mode)
+            {
+                return open(name.c_str(), mode);
+            }
+
+            basic_filebuf<char_type, traits_type>* close()
+            {
+                // TODO: caught exceptions are to be rethrown after closing the file
+                if (!file_)
+                    return nullptr;
+                // TODO: deallocate buffers?
+
+                if (this->output_next_ != this->output_begin_)
+                    overflow(traits_type::eof());
+                // TODO: unshift? (p. 1084 at the top)
+
+                fclose(file_);
+                file_ = nullptr;
+
+                return this;
+            }
+
+        protected:
+            /**
+             * 27.9.1.5, overriden virtual functions:
+             */
+
+            int_type underflow() override
+            {
+                // TODO: use codecvt
+                if (!mode_is_in_(mode_))
+                    return traits_type::eof();
+
+                if (!ibuf_)
+                {
+                    ibuf_ = new char_type[buf_size_];
+                    this->input_begin_ = this->input_next_ = this->input_end_ = ibuf_;
+                }
+
+                off_type i{};
+                if (this->input_next_ < this->input_end_)
+                {
+                    auto idx = static_cast<off_type>(this->input_next_ - this->input_begin_);
+                    auto count = static_cast<off_type>(buf_size_) - idx;
+
+                    for (; i < count; ++i, ++idx)
+                        ibuf_[i] = ibuf_[idx];
+                }
+
+                for (; i < static_cast<off_type>(buf_size_); ++i)
+                {
+                    auto c = fgetc(file_);
+                    if (c == traits_type::eof())
+                        break;
+
+                    ibuf_[i] = static_cast<char_type>(c);
+
+                    if (ibuf_[i] == '\n')
+                    {
+                        ++i;
+                        break;
+                    }
+                }
+
+                this->input_next_ = this->input_begin_;
+                this->input_end_ = this->input_begin_ + i;
+
+                if (i == 0)
+                    return traits_type::eof();
+
+                return traits_type::to_int_type(*this->input_next_);
+            }
+
+            int_type pbackfail(int_type c = traits_type::eof()) override
+            {
+                auto cc = traits_type::to_char_type(c);
+                if (!traits_type::eq_int_type(c, traits_type::eof()) &&
+                    this->putback_avail_() &&
+                    traits_type::eq(cc, this->gptr()[-1]))
+                {
+                    --this->input_next_;
+
+                    return c;
+                }
+                else if (!traits_type::eq_int_type(c, traits_type::eof()) &&
+                         this->putback_avail_() && (mode_ & ios_base::out) != 0)
+                {
+                    *--this->input_next_ = cc;
+
+                    return c;
+                }
+                else if (traits_type::eq_int_type(c, traits_type::eof()) &&
+                         this->putback_avail_())
+                {
+                    --this->input_next_;
+
+                    return traits_type::not_eof(c);
+                }
+
+                return traits_type::eof();
+            }
+
+            int_type overflow(int_type c = traits_type::eof()) override
+            {
+                // TODO: use codecvt
+                if (!mode_is_out_(mode_))
+                    return traits_type::eof();
+
+                auto count = static_cast<size_t>(this->output_next_ - this->output_begin_);
+                fwrite(obuf_, sizeof(char_type), count, file_);
+                fflush(file_);
+
+                this->output_next_ = this->output_begin_;
+
+                return traits_type::not_eof(c);
+            }
+
+            basic_streambuf<char_type, traits_type>*
+            setbuf(char_type* s, streamsize n) override
+            {
+                // TODO: implement
+                return nullptr;
+            }
+
+            pos_type seekoff(off_type off, ios_base::seekdir dir,
+                             ios_base::openmode mode = ios_base::in | ios_base::out) override
+            {
+                // TODO: implement
+                return pos_type{};
+            }
+
+            pos_type seekpos(pos_type pos,
+                             ios_base::openmode mode = ios_base::in | ios_base::out) override
+            {
+                // TODO: implement
+                return pos_type{};
+            }
+
+            int sync() override
+            {
+                if (mode_is_out_(mode_))
+                    overflow();
+
+                return 0; // TODO: what is the correct return value?
+            }
+
+            void imbue(const locale& loc) override
+            {
+                // TODO: codecvt should be cached when we start using it
+                basic_streambuf<char_type, traits_type>::imbue(loc);
+            }
+
+        private:
+            char_type* obuf_;
+            char_type* ibuf_;
+
+            ios_base::openmode mode_;
+
+            FILE* file_;
+
+            static constexpr size_t buf_size_{128};
+
+            const char* get_mode_str_(ios_base::openmode mode)
+            {
+                /**
+                 * See table 132.
+                 */
+                switch (mode)
+                {
+                    case ios_base::out:
+                    case ios_base::out | ios_base::trunc:
+                        return "w";
+                    case ios_base::out | ios_base::app:
+                    case ios_base::app:
+                        return "a";
+                    case ios_base::in:
+                        return "r";
+                    case ios_base::in | ios_base::out:
+                        return "r+";
+                    case ios_base::in | ios_base::out | ios_base::trunc:
+                        return "w+";
+                    case ios_base::in | ios_base::out | ios_base::app:
+                    case ios_base::in | ios_base::app:
+                        return "a+";
+                    case ios_base::binary | ios_base::out:
+                    case ios_base::binary | ios_base::out | ios_base::trunc:
+                        return "wb";
+                    case ios_base::binary | ios_base::out | ios_base::app:
+                    case ios_base::binary | ios_base::app:
+                        return "ab";
+                    case ios_base::binary | ios_base::in:
+                        return "rb";
+                    case ios_base::binary | ios_base::in | ios_base::out:
+                        return "r+b";
+                    case ios_base::binary | ios_base::in | ios_base::out | ios_base::trunc:
+                        return "w+b";
+                    case ios_base::binary | ios_base::in | ios_base::out | ios_base::app:
+                    case ios_base::binary | ios_base::in | ios_base::app:
+                        return "a+b";
+                    default:
+                        return nullptr;
+                }
+            }
+
+            bool mode_is_in_(ios_base::openmode mode)
+            {
+                return (mode & ios_base::in) != 0;
+            }
+
+            bool mode_is_out_(ios_base::openmode mode)
+            {
+                return (mode & (ios_base::out | ios_base::app | ios_base::trunc)) != 0;
+            }
+
+            void init_()
+            {
+                if (ibuf_)
+                    this->input_begin_ = this->input_next_ = this->input_end_ = ibuf_;
+
+                if (obuf_)
+                {
+                    this->output_begin_ = this->output_next_ = obuf_;
+                    this->output_end_ = obuf_ + buf_size_;
+                }
+            }
+    };
+
+    template<class Char, class Traits>
+    void swap(basic_filebuf<Char, Traits>& lhs, basic_filebuf<Char, Traits>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 27.9.1.6, class template basic_ifstream:
+     */
+
+    template<class Char, class Traits>
+    class basic_ifstream: public basic_istream<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.9.1.7, constructors:
+             */
+
+            basic_ifstream()
+                : basic_istream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            { /* DUMMY BODY */ }
+
+            explicit basic_ifstream(const char* name, ios_base::openmode mode = ios_base::in)
+                : basic_istream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode | ios_base::in))
+                    this->setstate(ios_base::failbit);
+            }
+
+            explicit basic_ifstream(const string& name, ios_base::openmode mode = ios_base::in)
+                : basic_istream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode | ios_base::in))
+                    this->setstate(ios_base::failbit);
+            }
+
+            basic_ifstream(const basic_ifstream&) = delete;
+
+            basic_ifstream(basic_ifstream&& other)
+                : basic_istream<char_type, traits_type>{move(other)},
+                  rdbuf_{other.rdbuf_}
+            {
+                basic_istream<char_type, traits_type>::set_rdbuf(&rdbuf_);
+            }
+
+            /**
+             * 27.9.1.8, assign/swap:
+             */
+
+            basic_ifstream& operator=(const basic_ifstream&) = delete;
+
+            basic_ifstream& operator=(basic_ifstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_ifstream& rhs)
+            {
+                basic_istream<char_type, traits_type>::swap(rhs);
+                rdbuf_.swap(rhs.rdbuf_);
+            }
+
+            /**
+             * 27.9.1.9, members:
+             */
+
+            basic_filebuf<char_type, traits_type>* rdbuf() const
+            {
+                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
+            }
+
+            bool is_open() const
+            {
+                return rdbuf_.is_open();
+            }
+
+            void open(const char* name, ios_base::openmode mode = ios_base::in)
+            {
+                if (!rdbuf_.open(name, mode | ios_base::in))
+                    this->setstate(ios_base::failbit);
+                else
+                    this->clear();
+            }
+
+            void open(const string& name, ios_base::openmode mode = ios_base::in)
+            {
+                open(name.c_str(), mode);
+            }
+
+            void close()
+            {
+                if (!rdbuf_.close())
+                    this->setstate(ios_base::failbit);
+            }
+
+        private:
+            basic_filebuf<char_type, traits_type> rdbuf_;
+    };
+
+    template<class Char, class Traits>
+    void swap(basic_ifstream<Char, Traits>& lhs,
+              basic_ifstream<Char, Traits>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 27.9.1.10, class template basic_ofstream:
+     */
+
+    template<class Char, class Traits>
+    class basic_ofstream: public basic_ostream<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.9.1.11, constructors:
+             */
+
+            basic_ofstream()
+                : basic_ostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            { /* DUMMY BODY */ }
+
+            explicit basic_ofstream(const char* name, ios_base::openmode mode = ios_base::out)
+                : basic_ostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode | ios_base::out))
+                    this->setstate(ios_base::failbit);
+            }
+
+            explicit basic_ofstream(const string& name, ios_base::openmode mode = ios_base::out)
+                : basic_ostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode | ios_base::out))
+                    this->setstate(ios_base::failbit);
+            }
+
+            basic_ofstream(const basic_ofstream&) = delete;
+
+            basic_ofstream(basic_ofstream&& other)
+                : basic_ostream<char_type, traits_type>{move(other)},
+                  rdbuf_{other.rdbuf_}
+            {
+                basic_ostream<char_type, traits_type>::set_rdbuf(&rdbuf_);
+            }
+
+            /**
+             * 27.9.1.12, assign/swap:
+             */
+
+            basic_ofstream& operator=(const basic_ofstream&) = delete;
+
+            basic_ofstream& operator=(basic_ofstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_ofstream& rhs)
+            {
+                basic_ostream<char_type, traits_type>::swap(rhs);
+                rdbuf_.swap(rhs.rdbuf_);
+            }
+
+            /**
+             * 27.9.1.13, members:
+             */
+
+            basic_filebuf<char_type, traits_type>* rdbuf() const
+            {
+                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
+            }
+
+            bool is_open() const
+            {
+                return rdbuf_.is_open();
+            }
+
+            void open(const char* name, ios_base::openmode mode = ios_base::out)
+            {
+                if (!rdbuf_.open(name, mode | ios_base::out))
+                    this->setstate(ios_base::failbit);
+                else
+                    this->clear();
+            }
+
+            void open(const string& name, ios_base::openmode mode = ios_base::out)
+            {
+                open(name.c_str(), mode);
+            }
+
+            void close()
+            {
+                if (!rdbuf_.close())
+                    this->setstate(ios_base::failbit);
+            }
+
+        private:
+            basic_filebuf<char_type, traits_type> rdbuf_;
+    };
+
+    template<class Char, class Traits>
+    void swap(basic_ofstream<Char, Traits>& lhs,
+              basic_ofstream<Char, Traits>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 27.9.1.14, class template basic_fstream:
+     */
+
+    template<class Char, class Traits>
+    class basic_fstream: public basic_iostream<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.9.1.15, constructors:
+             */
+
+            basic_fstream()
+                : basic_iostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            { /* DUMMY BODY */ }
+
+            explicit basic_fstream(const char* name,
+                                   ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_iostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode))
+                    this->setstate(ios_base::failbit);
+            }
+
+            explicit basic_fstream(const string& name,
+                                   ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_iostream<char_type, traits_type>{&rdbuf_},
+                  rdbuf_{}
+            {
+                if (!rdbuf_.open(name, mode))
+                    this->setstate(ios_base::failbit);
+            }
+
+            basic_fstream(const basic_fstream&) = delete;
+
+            basic_fstream(basic_fstream&& other)
+                : basic_iostream<char_type, traits_type>{move(other)},
+                  rdbuf_{other.rdbuf_}
+            {
+                basic_iostream<char_type, traits_type>::set_rdbuf(&rdbuf_);
+            }
+
+            /**
+             * 27.9.1.16, assign/swap:
+             */
+
+            basic_fstream& operator=(const basic_fstream&) = delete;
+
+            basic_fstream& operator=(basic_fstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_fstream& rhs)
+            {
+                basic_iostream<char_type, traits_type>::swap(rhs);
+                rdbuf_.swap(rhs.rdbuf_);
+            }
+
+            /**
+             * 27.9.1.17, members:
+             */
+
+            basic_filebuf<char_type, traits_type>* rdbuf() const
+            {
+                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
+            }
+
+            bool is_open() const
+            {
+                return rdbuf_.is_open();
+            }
+
+            void open(const char* name,
+                      ios_base::openmode mode = ios_base::in | ios_base::out)
+            {
+                if (!rdbuf_.open(name, mode))
+                    this->setstate(ios_base::failbit);
+                else
+                    this->clear();
+            }
+
+            void open(const string& name,
+                      ios_base::openmode mode = ios_base::in | ios_base::out)
+            {
+                open(name.c_str(), mode);
+            }
+
+            void close()
+            {
+                if (!rdbuf_.close())
+                    this->setstate(ios_base::failbit);
+            }
+
+        private:
+            basic_filebuf<char_type, traits_type> rdbuf_;
+    };
+
+    template<class Char, class Traits>
+    void swap(basic_fstream<Char, Traits>& lhs,
+              basic_fstream<Char, Traits>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/iomanip.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/iomanip.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/iomanip.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_IOMANIP
+#define LIBCPP_BITS_IO_IOMANIP
+
+#include <__bits/io/iomanip_objs.hpp>
+#include <iosfwd>
+
+namespace std
+{
+    /**
+     * 27.7.4, standard manipulators:
+     */
+
+    aux::manip_wrapper<aux::resetiosflags_t> resetiosflags(ios_base::fmtflags mask);
+    aux::manip_wrapper<aux::setiosflags_t> setiosflags(ios_base::fmtflags mask);
+    aux::manip_wrapper<aux::setbase_t> setbase(int base);
+
+    template<class Char>
+    aux::setfill_t<Char> setfill(Char c)
+    {
+        return aux::setfill_t<Char>{c};
+    }
+
+    aux::manip_wrapper<aux::setprecision_t> setprecision(int prec);
+    aux::manip_wrapper<aux::setw_t> setw(int width);
+
+    /**
+     * 27.7.5, extended manipulators:
+     */
+
+    // TODO: implement
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/iomanip_objs.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/iomanip_objs.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/iomanip_objs.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_IOMANIP_OBJS
+#define LIBCPP_BITS_IO_IOMANIP_OBJS
+
+#include <ios>
+#include <utility>
+
+namespace std::aux
+{
+    /**
+     * Note: This allows us to lower the amount
+     *       of code duplication in this module
+     *       as we can avoid operator<</>> overloading
+     *       for the manipulators.
+     */
+    template<class Manipulator>
+    struct manip_wrapper
+    {
+        template<class... Args>
+        manip_wrapper(Args&&... args)
+            : manipulator{forward<Args>(args)...}
+        { /* DUMMY BODY */ }
+
+        void operator()(ios_base& str)
+        {
+            manipulator(str);
+        }
+
+        Manipulator manipulator;
+    };
+
+    template<class Char, class Traits, class Manipulator>
+    basic_ostream<Char, Traits>& operator<<(
+        basic_ostream<Char, Traits>& os, manip_wrapper<Manipulator> manip
+    )
+    {
+        manip(os);
+
+        return os;
+    }
+
+    template<class Char, class Traits, class Manipulator>
+    basic_istream<Char, Traits>& operator>>(
+        basic_istream<Char, Traits>& is, manip_wrapper<Manipulator> manip
+    )
+    {
+        manip(is);
+
+        return is;
+    }
+
+    struct resetiosflags_t
+    {
+        resetiosflags_t(ios_base::fmtflags m);
+
+        void operator()(ios_base& str) const;
+
+        ios_base::fmtflags mask;
+    };
+
+    struct setiosflags_t
+    {
+        setiosflags_t(ios_base::fmtflags m);
+
+        void operator()(ios_base& str) const;
+
+        ios_base::fmtflags mask;
+    };
+
+    struct setbase_t
+    {
+        setbase_t(int b);
+
+        void operator()(ios_base& str) const;
+
+        int base;
+    };
+
+    /**
+     * Note: setfill is only for basic_ostream so
+     *       this is the only case where we overload
+     *       the appropriate operator again.
+     */
+    template<class Char>
+    struct setfill_t
+    {
+        setfill_t(Char c)
+            : fill{c}
+        { /* DUMMY BODY */ }
+
+        template<class Traits>
+        void operator()(basic_ios<Char, Traits>& str) const
+        {
+            str.fill(fill);
+        }
+
+        Char fill;
+    };
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(
+        basic_ostream<Char, Traits>& is,
+        setfill_t<Char> manip
+    )
+    {
+        manip(is);
+
+        return is;
+    }
+
+    struct setprecision_t
+    {
+        setprecision_t(int);
+
+        void operator()(ios_base&) const;
+
+        int prec;
+    };
+
+    struct setw_t
+    {
+        setw_t(int);
+
+        void operator()(ios_base&) const;
+
+        int width;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/ios.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ios.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/ios.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_IOS
+#define LIBCPP_BITS_IO_IOS
+
+#include <__bits/locale/locale.hpp>
+#include <__bits/locale/ctype.hpp>
+#include <cstdlib>
+#include <iosfwd>
+#include <system_error>
+#include <utility>
+#include <vector>
+
+namespace std
+{
+    using streamoff = long long;
+    using streamsize = hel::ssize_t;
+
+    /**
+     * 27.5.3, ios_base:
+     */
+
+    class ios_base
+    {
+        public:
+            virtual ~ios_base();
+
+            ios_base(const ios_base&) = delete;
+            ios_base& operator=(const ios_base&) = delete;
+
+            /**
+             * 27.5.3.1.1, failure:
+             */
+
+            class failure: public system_error
+            {
+                // TODO: implement
+            };
+
+            /**
+             * 27.5.3.1.2, fmtflags:
+             */
+
+            using fmtflags = uint16_t;
+            static constexpr fmtflags boolalpha   = 0b0000'0000'0000'0001;
+            static constexpr fmtflags dec         = 0b0000'0000'0000'0010;
+            static constexpr fmtflags fixed       = 0b0000'0000'0000'0100;
+            static constexpr fmtflags hex         = 0b0000'0000'0000'1000;
+            static constexpr fmtflags internal    = 0b0000'0000'0001'0000;
+            static constexpr fmtflags left        = 0b0000'0000'0010'0000;
+            static constexpr fmtflags oct         = 0b0000'0000'0100'0000;
+            static constexpr fmtflags right       = 0b0000'0000'1000'0000;
+            static constexpr fmtflags scientific  = 0b0000'0001'0000'0000;
+            static constexpr fmtflags showbase    = 0b0000'0010'0000'0000;
+            static constexpr fmtflags showpoint   = 0b0000'0100'0000'0000;
+            static constexpr fmtflags showpos     = 0b0000'1000'0000'0000;
+            static constexpr fmtflags skipws      = 0b0001'0000'0000'0000;
+            static constexpr fmtflags unitbuf     = 0b0010'0000'0000'0000;
+            static constexpr fmtflags uppercase   = 0b0100'0000'0000'0000;
+            static constexpr fmtflags adjustfield = left | right | internal;
+            static constexpr fmtflags basefield   = dec  | oct   | hex;
+            static constexpr fmtflags floatfield  = scientific   | fixed;
+
+            /**
+             * 27.5.3.1.3, iostate:
+             */
+
+            using iostate = uint8_t;
+            static constexpr iostate badbit  = 0b0001;
+            static constexpr iostate eofbit  = 0b0010;
+            static constexpr iostate failbit = 0b0100;
+            static constexpr iostate goodbit = 0b0000;
+
+            /**
+             * 27.5.3.1.4, openmode:
+             */
+
+            using openmode = uint8_t;
+            static constexpr openmode app    = 0b00'0001;
+            static constexpr openmode ate    = 0b00'0010;
+            static constexpr openmode binary = 0b00'0100;
+            static constexpr openmode in     = 0b00'1000;
+            static constexpr openmode out    = 0b01'0000;
+            static constexpr openmode trunc  = 0b10'0000;
+
+            /**
+             * 27.5.3.1.5, seekdir:
+             */
+
+            using seekdir = uint8_t;
+            static constexpr seekdir beg = 0b001;
+            static constexpr seekdir cur = 0b010;
+            static constexpr seekdir end = 0b100;
+
+            /**
+             * 27.5.3.1.6, class Init:
+             */
+
+            class Init
+            {
+                public:
+                    Init();
+                    ~Init();
+
+                private:
+                    static int init_cnt_;
+            };
+
+            /**
+             * 27.5.3.2, fmtflags state:
+             */
+
+            fmtflags flags() const;
+            fmtflags flags(fmtflags fmtfl);
+            fmtflags setf(fmtflags fmtfl);
+            fmtflags setf(fmtflags fmtfl, fmtflags mask);
+            void unsetf(fmtflags mask);
+
+            streamsize precision() const;
+            streamsize precision(streamsize prec);
+            streamsize width() const;
+            streamsize width(streamsize wide);
+
+            /**
+             * 27.5.3.3, locales:
+             */
+
+            locale imbue(const locale& loc);
+            locale getloc() const;
+
+            /**
+             * 27.5.3.5, storage:
+             */
+
+            static int xalloc()
+            {
+                // TODO: Concurrent access to this function
+                //       by multiple threads shall not result
+                //       in a data race.
+                return index_++;
+            }
+
+            long& iword(int index);
+            void*& pword(int index);
+
+            /**
+             * 27.5.3.6, callbacks:
+             */
+
+            enum event
+            {
+                erase_event,
+                imbue_event,
+                copyfmt_event
+            };
+
+            using event_callback = void (*)(event, ios_base&, int);
+            void register_callback(event_callback fn, int index);
+
+            static bool sync_with_stdio(bool sync = true)
+            {
+                auto old = sync_;
+                sync_ = sync;
+
+                return old;
+            }
+
+        protected:
+            ios_base();
+
+            static int index_;
+            static bool sync_;
+
+            static long ierror_;
+            static void* perror_;
+            static constexpr size_t initial_size_{10};
+
+            long* iarray_;
+            void** parray_;
+            size_t iarray_size_;
+            size_t parray_size_;
+
+            fmtflags flags_;
+            streamsize precision_;
+            streamsize width_;
+
+            locale locale_;
+
+            vector<pair<event_callback, int>> callbacks_;
+
+        private:
+            static constexpr size_t buffer_size_{64};
+            char buffer_[buffer_size_];
+
+            template<class Char, class Iterator>
+            friend class num_put;
+
+            template<class Char, class Iterator>
+            friend class num_get;
+    };
+
+    /**
+     * 27.5.4, fpos:
+     */
+
+    template<class State>
+    class fpos
+    {
+        public:
+            State state() const
+            {
+                return state_;
+            }
+
+            void state(State st)
+            {
+                state_ = st;
+            }
+
+        private:
+            State state_;
+    };
+
+    /**
+     * 27.5.4.2, fpos requirements:
+     */
+
+    // TODO: implement
+
+    /**
+     * 27.5.5, basic_ios:
+     */
+
+    template<class Char, class Traits>
+    class basic_ios: public ios_base
+    {
+        public:
+            using traits_type = Traits;
+            using char_type   = Char;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            basic_ios(const basic_ios&) = delete;
+            basic_ios& operator=(const basic_ios&) = delete;
+
+            explicit operator bool() const
+            {
+                return !fail();
+            }
+
+            bool operator!() const
+            {
+                return fail();
+            }
+
+            iostate rdstate() const
+            {
+                return rdstate_;
+            }
+
+            void clear(iostate state = goodbit)
+            {
+                if (rdbuf_)
+                    rdstate_ = state;
+                else
+                    rdstate_ = state | badbit;
+
+                if (((state | (rdbuf_ ? goodbit : badbit)) & exceptions_) == 0)
+                    return;
+                // TODO: Else throw failure.
+                return;
+            }
+
+            void setstate(iostate state)
+            {
+                clear(rdstate_ | state);
+            }
+
+            bool good() const
+            {
+                return rdstate_ == 0;
+            }
+
+            bool eof() const
+            {
+                return (rdstate_ & eofbit) != 0;
+            }
+
+            bool fail() const
+            {
+                return (rdstate_ & (failbit | badbit)) != 0;
+            }
+
+            bool bad() const
+            {
+                return (rdstate_ & badbit) != 0;
+            }
+
+            iostate exceptions() const
+            {
+                return exceptions_;
+            }
+
+            void exceptions(iostate except)
+            {
+                exceptions_ = except;
+                clear(rdstate_);
+            }
+
+            /**
+             * 27.5.5.2, constructor/destructor:
+             */
+
+            explicit basic_ios(basic_streambuf<Char, Traits>* sb)
+            {
+                init(sb);
+            }
+
+            virtual ~basic_ios()
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.5.5.3, members:
+             */
+
+            basic_ostream<Char, Traits>* tie() const
+            {
+                return tie_;
+            }
+
+            basic_ostream<Char, Traits>* tie(basic_ostream<Char, Traits>* tiestr)
+            {
+                auto old = tie_;
+                tie_ = tiestr;
+
+                return old;
+            }
+
+            basic_streambuf<Char, Traits>* rdbuf() const
+            {
+                return rdbuf_;
+            }
+
+            basic_streambuf<Char, Traits>* rdbuf(basic_streambuf<Char, Traits>* sb)
+            {
+                auto old = rdbuf_;
+                rdbuf_ = sb;
+
+                clear();
+
+                return old;
+            }
+
+            basic_ios& copyfmt(const basic_ios& rhs)
+            {
+                if (this == &rhs)
+                    return *this;
+
+                for (auto& callback: callbacks_)
+                    callback.first(erase_event, *this, index_);
+
+                tie_        = rhs.tie_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fill_      = rhs.fill_;
+                locale_     = rhs.locale_;
+
+                delete[] iarray_;
+                iarray_size_ = rhs.iarray_size_;
+                iarray_ = new long[iarray_size_];
+
+                for (size_t i = 0; i < iarray_size_; ++i)
+                    iarray_[i] = rhs.iarray_[i];
+
+                delete[] parray_;
+                parray_size_ = rhs.parray_size_;
+                parray_ = new long[parray_size_];
+
+                for (size_t i = 0; i < parray_size_; ++i)
+                    parray_[i] = rhs.parray_[i];
+
+                for (auto& callback: callbacks_)
+                    callback.first(copyfmt_event, *this, index_);
+
+                exceptions(rhs.exceptions());
+            }
+
+            char_type fill() const
+            {
+                return fill_;
+            }
+
+            char_type fill(char_type c)
+            {
+                char_type old;
+                traits_type::assign(old, fill_);
+                traits_type::assign(fill_, c);
+
+                return old;
+            }
+
+            locale imbue(const locale& loc)
+            {
+                auto res = ios_base::imbue(loc);
+
+                if (rdbuf_)
+                    rdbuf_->pubimbue(loc);
+
+                return res;
+            }
+
+            char narrow(char_type c, char def) const
+            {
+                return use_facet<ctype<char_type>>(locale_).narrow(c, def);
+            }
+
+            char_type widen(char c) const
+            {
+                return use_facet<ctype<char_type>>(locale_).widen(c);
+            }
+
+        protected:
+            basic_ios()
+            { /* DUMMY BODY */ }
+
+            void init(basic_streambuf<Char, Traits>* sb)
+            {
+                // Initialized according to Table 128.
+                rdbuf_ = sb;
+                tie_ = nullptr;
+                rdstate_ = sb ? goodbit : badbit;
+                exceptions_ = goodbit;
+                flags(skipws | dec);
+
+                width(0);
+                precision(6);
+
+                fill_ = widen(' ');
+                locale_ = locale();
+
+                iarray_ = nullptr;
+                parray_ = nullptr;
+            }
+
+            void move(basic_ios& rhs)
+            {
+                rdbuf_      = nullptr; // rhs keeps it!
+                tie_        = rhs.tie_;
+                exceptions_ = rhs.exceptions_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fill_       = rhs.fill_;
+                locale_     = move(rhs.locale_);
+                rdstate_    = rhs.rdstate_;
+                callbacks_  = move(rhs.callbacks_);
+
+                delete[] iarray_;
+                iarray_      = rhs.iarray_;
+                iarray_size_ = rhs.iarray_size_;
+
+                delete[] parray_;
+                parray_      = rhs.parray_;
+                parray_size_ = rhs.parray_size_;
+
+                rhs.tie_ = nullptr;
+                rhs.iarray_ = nullptr;
+                rhs.parray_ = nullptr;
+            }
+
+            void move(basic_ios&& rhs)
+            {
+                rdbuf_      = nullptr; // rhs keeps it!
+                tie_        = rhs.tie_;
+                exceptions_ = rhs.exceptions_;
+                flags_      = rhs.flags_;
+                width_      = rhs.width_;
+                precision_  = rhs.precision_;
+                fill_       = rhs.fill_;
+                locale_     = move(rhs.locale_);
+                rdstate_    = rhs.rdstate_;
+                callbacks_.swap(rhs.callbacks_);
+
+                delete[] iarray_;
+                iarray_      = rhs.iarray_;
+                iarray_size_ = rhs.iarray_size_;
+
+                delete[] parray_;
+                parray_      = rhs.parray_;
+                parray_size_ = rhs.parray_size_;
+
+                rhs.tie_ = nullptr;
+                rhs.iarray_ = nullptr;
+                rhs.parray_ = nullptr;
+            }
+
+            void swap(basic_ios& rhs) noexcept
+            {
+                // Swap everything but rdbuf_.
+                swap(tie_, rhs.tie_);
+                swap(exceptions_, rhs.exceptions_);
+                swap(flags_, rhs.flags_);
+                swap(width_, rhs.width_);
+                swap(precision_, rhs.precision_);
+                swap(fill_, rhs.fill_);
+                swap(locale_, rhs.locale_);
+                swap(rdstate_, rhs.rdstate_);
+                swap(callbacks_, rhs.callbacks_);
+                swap(iarray_);
+                swap(iarray_size_);
+                swap(parray_);
+                swap(parray_size_);
+            }
+
+            void set_rdbuf(basic_streambuf<Char, Traits>* sb)
+            {
+                // No call to clear is intentional.
+                rdbuf_ = sb;
+            }
+
+        private:
+            basic_streambuf<Char, Traits>* rdbuf_;
+            basic_ostream<Char, Traits>* tie_;
+            iostate rdstate_;
+            iostate exceptions_;
+            char_type fill_;
+    };
+
+    /**
+     * 27.5.6, ios_base manipulators:
+     */
+
+    /**
+     * 27.5.6.1, fmtflags manipulators:
+     */
+
+    ios_base& boolalpha(ios_base& str);
+    ios_base& noboolalpha(ios_base& str);
+    ios_base& showbase(ios_base& str);
+    ios_base& noshowbase(ios_base& str);
+    ios_base& showpoint(ios_base& str);
+    ios_base& noshowpoint(ios_base& str);
+    ios_base& showpos(ios_base& str);
+    ios_base& noshowpos(ios_base& str);
+    ios_base& skipws(ios_base& str);
+    ios_base& noskipws(ios_base& str);
+    ios_base& uppercase(ios_base& str);
+    ios_base& nouppercase(ios_base& str);
+    ios_base& unitbuf(ios_base& str);
+    ios_base& nounitbuf(ios_base& str);
+
+    /**
+     * 27.5.6.2, adjustfield manipulators:
+     */
+
+    ios_base& internal(ios_base& str);
+    ios_base& left(ios_base& str);
+    ios_base& right(ios_base& str);
+
+    /**
+     * 27.5.6.3, basefield manupulators:
+     */
+
+    ios_base& dec(ios_base& str);
+    ios_base& hex(ios_base& str);
+    ios_base& oct(ios_base& str);
+
+    /**
+     * 27.5.6.4, floatfield manupulators:
+     */
+
+    ios_base& fixed(ios_base& str);
+    ios_base& scientific(ios_base& str);
+    ios_base& hexfloat(ios_base& str);
+    ios_base& defaultfloat(ios_base& str);
+
+    /**
+     * 27.5.6.5, error reporting:
+     */
+
+    // TODO: implement
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/iosfwd.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/iosfwd.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/iosfwd.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_IOSFWD
+#define LIBCPP_BITS_IO_IOSFWD
+
+namespace std
+{
+    /**
+     * 27.3, forward declarations:
+     */
+
+    template<class Char>
+    class char_traits;
+
+    template<>
+    class char_traits<char>;
+
+    template<>
+    class char_traits<char16_t>;
+
+    template<>
+    class char_traits<char32_t>;
+
+    template<>
+    class char_traits<wchar_t>;
+
+
+
+    template<class T>
+    class allocator;
+
+
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_ios;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_streambuf;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_istream;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_ostream;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_iostream;
+
+
+
+    template<class Char, class Traits = char_traits<Char>,
+             class Allocator = allocator<Char>>
+    class basic_stringbuf;
+
+    template<class Char, class Traits = char_traits<Char>,
+             class Allocator = allocator<Char>>
+    class basic_istringstream;
+
+    template<class Char, class Traits = char_traits<Char>,
+             class Allocator = allocator<Char>>
+    class basic_ostringstream;
+
+    template<class Char, class Traits = char_traits<Char>,
+             class Allocator = allocator<Char>>
+    class basic_stringstream;
+
+
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_filebuf;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_ifstream;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_ofstream;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class basic_fstream;
+
+
+
+    template<class Char, class Traits = char_traits<Char>>
+    class istreambuf_iterator;
+
+    template<class Char, class Traits = char_traits<Char>>
+    class ostreambuf_iterator;
+
+    using ios  = basic_ios<char>;
+    using wios = basic_ios<wchar_t>;
+
+    using streambuf = basic_streambuf<char>;
+    using istream   = basic_istream<char>;
+    using ostream   = basic_ostream<char>;
+    using iostream  = basic_iostream<char>;
+
+    using stringbuf     = basic_stringbuf<char>;
+    using istringstream = basic_istringstream<char>;
+    using ostringstream = basic_ostringstream<char>;
+    using stringstream  = basic_stringstream<char>;
+
+    using filebuf  = basic_filebuf<char>;
+    using ifstream = basic_ifstream<char>;
+    using ofstream = basic_ofstream<char>;
+    using fstream  = basic_fstream<char>;
+
+    using wstreambuf = basic_streambuf<wchar_t>;
+    using wistream   = basic_istream<wchar_t>;
+    using wostream   = basic_ostream<wchar_t>;
+    using wiostream  = basic_iostream<wchar_t>;
+
+    using wstringbuf     = basic_stringbuf<wchar_t>;
+    using wistringstream = basic_istringstream<wchar_t>;
+    using wostringstream = basic_ostringstream<wchar_t>;
+    using wstringstream  = basic_stringstream<wchar_t>;
+
+    using wfilebuf  = basic_filebuf<wchar_t>;
+    using wifstream = basic_ifstream<wchar_t>;
+    using wofstream = basic_ofstream<wchar_t>;
+    using wfstream  = basic_fstream<wchar_t>;
+
+    template<class State>
+    class fpos;
+
+    // TODO: standard p. 1012, this is circular, it offers fix
+    /* using streampos  = fpos<char_traits<char>::state_type>; */
+    /* using wstreampos = fpos<char_traits<wchar_t>::state_type>; */
+    // Temporary workaround.
+    using streampos =  unsigned long long;
+    using wstreampos = unsigned long long;
+    // TODO: This should be in ios and not here?
+    using streamoff = long long;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/iostream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/iostream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/iostream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_IOSTREAM
+#define LIBCPP_BITS_IO_IOSTREAM
+
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+
+namespace std
+{
+    extern istream cin;
+    extern ostream cout;
+
+    // TODO: add the rest
+
+    namespace aux
+    {
+        extern ios_base::Init init;
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/istream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/istream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/istream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_ISTREAM
+#define LIBCPP_BITS_IO_ISTREAM
+
+#include <ios>
+#include <iosfwd>
+#include <limits>
+#include <locale>
+#include <ostream>
+#include <utility>
+
+namespace std
+{
+
+    /**
+     * 27.7.2.1, class template basic_stream:
+     */
+
+    template<class Char, class Traits>
+    class basic_istream: virtual public basic_ios<Char, Traits>
+    {
+        public:
+            using traits_type = Traits;
+            using char_type   = Char;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.7.2.1.1, constructor/destructor:
+             */
+
+            explicit basic_istream(basic_streambuf<Char, Traits>* sb)
+                : gcount_{0}
+            {
+                basic_ios<Char, Traits>::init(sb);
+            }
+
+            virtual ~basic_istream()
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.7.2.1.3, prefix/suffix:
+             */
+
+            class sentry
+            {
+                public:
+                    explicit sentry(basic_istream<Char, Traits>& is, bool noskipws = false)
+                        : ok_{false}
+                    {
+                        if (!is.good())
+                            is.setstate(ios_base::failbit);
+                        else
+                        {
+                            if (is.tie())
+                                is.tie()->flush();
+
+                            if (!noskipws && ((is.flags() & ios_base::skipws) != 0))
+                            {
+                                const auto& ct = use_facet<ctype<Char>>(is.getloc());
+                                while (true)
+                                {
+                                    auto i = is.rdbuf()->sgetc();
+                                    if (Traits::eq_int_type(i, Traits::eof()))
+                                    {
+                                        is.setstate(ios_base::failbit | ios_base::eofbit);
+                                        break;
+                                    }
+
+                                    auto c = Traits::to_char_type(i);
+                                    if (!ct.is(ctype_base::space, c))
+                                        break;
+                                    else
+                                        is.rdbuf()->sbumpc();
+                                }
+                            }
+                        }
+
+                        if (is.good())
+                            ok_ = true;
+                    }
+
+                    ~sentry() = default;
+
+                    explicit operator bool() const
+                    {
+                        return ok_;
+                    }
+
+                    sentry(const sentry&) = delete;
+                    sentry& operator=(const sentry&) = delete;
+
+                private:
+                    using traits_type = Traits;
+                    bool ok_;
+            };
+
+            /**
+             * 27.7.2.2, formatted input:
+             */
+
+            basic_istream<Char, Traits>& operator>>(
+                basic_istream<Char, Traits>& (*pf)(basic_istream<Char, Traits>&)
+            )
+            {
+                return pf(*this);
+            }
+
+            basic_istream<Char, Traits>& operator>>(
+                basic_ios<Char, Traits>& (*pf)(basic_ios<Char, Traits>&)
+            )
+            {
+                pf(*this);
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(
+                ios_base& (*pf)(ios_base&)
+            )
+            {
+                pf(*this);
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(bool& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(short& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    long tmp{};
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, tmp);
+
+                    if (tmp < numeric_limits<short>::min())
+                    {
+                        err |= ios_base::failbit;
+                        x = numeric_limits<short>::min();
+                    }
+                    else if (numeric_limits<short>::max() < tmp)
+                    {
+                        err |= ios_base::failbit;
+                        x = numeric_limits<short>::max();
+                    }
+                    else
+                        x = static_cast<short>(tmp);
+
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(unsigned short& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(int& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    long tmp{};
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, tmp);
+
+                    if (tmp < numeric_limits<int>::min())
+                    {
+                        err |= ios_base::failbit;
+                        x = numeric_limits<int>::min();
+                    }
+                    else if (numeric_limits<int>::max() < tmp)
+                    {
+                        err |= ios_base::failbit;
+                        x = numeric_limits<int>::max();
+                    }
+                    else
+                        x = static_cast<int>(tmp);
+
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(unsigned int& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(long& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(unsigned long& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(long long& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(unsigned long long& x)
+            {
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
+                    auto err = ios_base::goodbit;
+
+                    auto loc = this->getloc();
+                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
+                    this->setstate(err);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& operator>>(float& x)
+            {
+                // TODO: implement
+            }
+
+            basic_istream<Char, Traits>& operator>>(double& x)
+            {
+                // TODO: implement
+            }
+
+            basic_istream<Char, Traits>& operator>>(long double& x)
+            {
+                // TODO: implement
+            }
+
+            basic_istream<Char, Traits>& operator>>(void*& p)
+            {
+                // TODO: implement
+            }
+
+            basic_istream<Char, Traits>& operator>>(basic_streambuf<Char, Traits>* sb)
+            {
+                if (!sb)
+                {
+                    this->setstate(ios_base::failbit);
+                    return *this;
+                }
+
+                gcount_ = 0;
+                sentry sen{*this, false};
+
+                if (sen)
+                {
+                    while (true)
+                    {
+                        auto ic = this->rdbuf()->sgetc();
+                        if (traits_type::eq_int_type(ic, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::eofbit);
+                            break;
+                        }
+
+                        auto res = sb->sputc(traits_type::to_char_type(ic));
+                        if (traits_type::eq_int_type(res, traits_type::eof()))
+                            break;
+
+                        ++gcount_;
+                        this->rdbuf()->sbumpc();
+                    }
+                }
+
+                return *this;
+            }
+
+            /**
+             * 27.7.2.3, unformatted input:
+             * TODO: Once we have exceptions, implement
+             *       27.7.2.3 paragraph 1.
+             */
+
+            streamsize gcount() const
+            {
+                return gcount_;
+            }
+
+            int_type get()
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (sen)
+                {
+                    auto res = this->rdbuf()->sbumpc();
+                    if (!traits_type::eq_int_type(res, traits_type::eof()))
+                    {
+                        gcount_ = 1;
+                        return res;
+                    }
+
+                    this->setstate(ios_base::failbit | ios_base::eofbit);
+                }
+
+                return traits_type::eof();
+            }
+
+            basic_istream<Char, Traits>& get(char_type& c)
+            {
+                auto res = get();
+                if (res != traits_type::eof())
+                    c = traits_type::to_char_type(res);
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& get(char_type* s, streamsize n, char_type delim)
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (sen && n > 0)
+                {
+                    while(gcount_ < n - 1)
+                    {
+                        auto c = this->rdbuf()->sbumpc();
+
+                        if (traits_type::eq_int_type(c, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::eofbit);
+                            break;
+                        }
+
+                        s[gcount_++] = traits_type::to_char_type(c);
+
+                        auto peek = traits_type::to_char_type(this->rdbuf()->sgetc());
+                        if (traits_type::eq(peek, delim))
+                            break;
+                    }
+
+                    if (gcount_ == 0)
+                        this->setstate(ios_base::failbit);
+                    s[n] = char_type{};
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& get(char_type* s, streamsize n)
+            {
+                return get(s, n, this->widen('\n'));
+            }
+
+            basic_istream<Char, Traits>& get(basic_streambuf<Char, Traits>& sb)
+            {
+                get(sb, this->widen('\n'));
+            }
+
+            basic_istream<Char, Traits>& get(basic_streambuf<Char, Traits>& sb, char_type delim)
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (sen)
+                {
+                    while (true)
+                    {
+                        auto i = this->rdbuf()->sgetc();
+                        if (traits_type::eq_int_type(i, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::eofbit);
+                            break;
+                        }
+
+                        auto c = traits_type::to_char_type(i);
+                        if (traits_type::eq(c, delim))
+                            break;
+
+                        auto insert_ret = sb.sputc(c);
+                        if (traits_type::eq_int_type(insert_ret, traits_type::eof()))
+                            break;
+
+                        this->rdbuf()->sbumpc();
+                        ++gcount_;
+                    }
+
+                    if (gcount_ == 0)
+                        this->setstate(ios_base::failbit);
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& getline(char_type* s, streamsize n)
+            {
+                return getline(s, n, this->widen('\n'));
+            }
+
+            basic_istream<Char, Traits>& getline(char_type* s, streamsize n, char_type delim)
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (sen)
+                {
+                    while (true)
+                    { // We have exactly specified order of checks, easier to do them in the body.
+                        auto c = this->rdbuf()->sbumpc();
+
+                        if (traits_type::eq_int_type(c, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::eofbit);
+                            break;
+                        }
+
+                        if (traits_type::eq_int_type(c, traits_type::to_int_type(delim)))
+                            break;
+
+                        if (n < 1 || gcount_ >= n - 1)
+                        {
+                            this->setstate(ios_base::failbit);
+                            break;
+                        }
+
+                        s[gcount_++] = traits_type::to_char_type(c);
+                    }
+
+                    if (gcount_ == 0)
+                        this->setstate(ios_base::failbit);
+                    if (n > 0)
+                        s[gcount_] = char_type{};
+                }
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& ignore(streamsize n = 1, int_type delim = traits_type::eof())
+            {
+                sentry sen{*this, true};
+
+                if (sen)
+                {
+                    streamsize i{};
+                    while (n == numeric_limits<streamsize>::max() || i < n)
+                    {
+                        auto c = this->rdbuf()->sbumpc();
+
+                        if (traits_type::eq_int_type(c, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::eofbit);
+                            break;
+                        }
+
+                        if (traits_type::eq_int_type(c, delim))
+                            break;
+                    }
+                }
+
+                return *this;
+            }
+
+            int_type peek()
+            {
+                sentry sen{*this, true};
+
+                if (!this->good())
+                    return traits_type::eof();
+                else
+                    return this->rdbuf()->sgetc();
+            }
+
+            basic_istream<Char, Traits>& read(char_type* s, streamsize n)
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (!this->good())
+                {
+                    this->setstate(ios_base::failbit);
+                    return *this;
+                }
+
+                while (gcount_ < n)
+                {
+                    auto c = this->rdbuf()->sbumpc();
+                    if (traits_type::eq_int_type(c, traits_type::eof()))
+                    {
+                        this->setstate(ios_base::failbit | ios_base::eofbit);
+                        break;
+                    }
+
+                    s[gcount_++] = traits_type::to_char_type(c);
+                }
+
+                return *this;
+            }
+
+            streamsize readsome(char_type* s, streamsize n)
+            {
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (!this->good())
+                {
+                    this->setstate(ios_base::failbit);
+                    return streamsize{};
+                }
+
+                auto avail = this->rdbuf()->in_avail();
+                if (avail == -1)
+                {
+                    this->setstate(ios_base::eofbit);
+                    return streamsize{};
+                } else if (avail > 0)
+                {
+                    auto count = (avail < n ? avail : n);
+                    while (gcount_ < count)
+                        s[gcount_++] = traits_type::to_char_type(this->rdbuf()->sbumpc());
+                }
+
+                return gcount_;
+            }
+
+            basic_istream<Char, Traits>& putback(char_type c)
+            {
+                this->clear(this->rdstate() & (~ios_base::eofbit));
+
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (!this->good())
+                {
+                    this->setstate(ios_base::failbit);
+                    return *this;
+                }
+
+                if (this->rdbuf())
+                {
+                    auto ret = this->rdbuf()->sputbackc(c);
+                    if (traits_type::eq_int_type(ret, traits_type::eof()))
+                        this->setstate(ios_base::badbit);
+                }
+                else
+                    this->setstate(ios_base::badbit);
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& unget()
+            {
+                this->clear(this->rdstate() & (~ios_base::eofbit));
+
+                gcount_ = 0;
+                sentry sen{*this, true};
+
+                if (!this->good())
+                {
+                    this->setstate(ios_base::failbit);
+                    return *this;
+                }
+
+                if (this->rdbuf())
+                {
+                    auto ret = this->rdbuf()->sungetc();
+                    if (traits_type::eq_int_type(ret, traits_type::eof()))
+                        this->setstate(ios_base::badbit);
+                }
+                else
+                    this->setstate(ios_base::badbit);
+
+                return *this;
+            }
+
+            int sync()
+            {
+                sentry s{*this, true};
+
+                if (this->rdbuf())
+                {
+                    auto ret = this->rdbuf()->pubsync();
+                    if (ret == -1)
+                    {
+                        this->setstate(ios_base::badbit);
+                        return -1;
+                    }
+                    else
+                        return 0;
+                }
+                else
+                    return -1;
+            }
+
+            pos_type tellg()
+            {
+                sentry s{*this, true};
+
+                if (this->fail())
+                    return pos_type(-1);
+                else
+                    return this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
+            }
+
+            basic_istream<Char, Traits>& seekg(pos_type pos)
+            {
+                this->clear(this->rdstate() & (~ios_base::eofbit));
+
+                sentry sen{*this, true};
+
+                if (!this->fail())
+                    this->rdbuf()->pubseekoff(pos, ios_base::in);
+                else
+                    this->setstate(ios_base::failbit);
+
+                return *this;
+            }
+
+            basic_istream<Char, Traits>& seekg(off_type off, ios_base::seekdir dir)
+            {
+                sentry sen{*this, true};
+
+                if (!this->fail())
+                    this->rdbuf()->pubseekoff(off, dir, ios_base::in);
+                else
+                    this->setstate(ios_base::failbit);
+
+                return *this;
+            }
+
+        protected:
+            streamsize gcount_;
+
+            basic_istream(const basic_istream&) = delete;
+
+            basic_istream(basic_istream&& rhs)
+            {
+                gcount_ = rhs.gcout_;
+
+                basic_ios<Char, Traits>::move(rhs);
+
+                rhs.gcount_ = 0;
+            }
+
+            /**
+             * 27.7.2.1.2, assign/swap:
+             */
+
+            basic_istream& operator=(const basic_istream& rhs) = delete;
+
+            basic_istream& operator=(basic_istream&& rhs)
+            {
+                swap(rhs);
+
+                return *this;
+            }
+
+            void swap(basic_istream& rhs)
+            {
+                basic_ios<Char, Traits>::swap(rhs);
+                swap(gcount_, rhs.gcount_);
+            }
+    };
+
+    /**
+     * 27.7.2.2.3, character extraction templates:
+     */
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            Char& c)
+    {
+        typename basic_istream<Char, Traits>::sentry sen{is, false};
+
+        if (sen)
+        {
+            auto ic = is.rdbuf()->sgetc();
+            if (Traits::eq_int_type(ic, Traits::eof()))
+            {
+                is.setstate(ios_base::failbit | ios_base::eofbit);
+                return is;
+            }
+
+            c = Traits::to_char_type(is.rdbuf()->sbumpc());
+        }
+
+        return is;
+    }
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            unsigned char& c)
+    {
+        return is >> static_cast<char&>(c);
+    }
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            signed char& c)
+    {
+        return is >> static_cast<char&>(c);
+    }
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            Char* str)
+    {
+        typename basic_istream<Char, Traits>::sentry sen{is, false};
+
+        if (sen)
+        {
+            const auto& ct = use_facet<ctype<Char>>(is.getloc());
+
+            size_t n{};
+            if (is.width() > 0)
+                n = static_cast<size_t>(is.width());
+            else
+                n = (numeric_limits<size_t>::max() / sizeof(Char)) - sizeof(Char);
+
+            size_t i{};
+            for (; i < n - 1; ++i)
+            {
+                auto ic = is.rdbuf()->sgetc();
+                if (Traits::eq_int_type(ic, Traits::eof()))
+                    break;
+
+                auto c = Traits::to_char_type(ic);
+                if (ct.is(ctype_base::space, c))
+                    break;
+
+                str[i] = c;
+                is.rdbuf()->sbumpc();
+            }
+
+            str[i] = Char{};
+            if (i == 0)
+                is.setstate(ios_base::failbit);
+        }
+
+        return is;
+    }
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            unsigned char* str)
+    {
+        return is >> static_cast<char*>(str);
+    }
+
+    template<class Char, class Traits>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            signed char* str)
+    {
+        return is >> static_cast<char*>(str);
+    }
+
+    /**
+     * 27.7.2.4, standard basic_istream manipulators:
+     */
+
+    template<class Char, class Traits = char_traits<Char>>
+    basic_istream<Char, Traits>& ws(basic_istream<Char, Traits>& is)
+    {
+        using sentry = typename basic_istream<Char, Traits>::sentry;
+        sentry sen{is, true};
+
+        if (sen)
+        {
+            const auto& ct = use_facet<ctype<Char>>(is.getloc());
+            while (true)
+            {
+                auto i = is.rdbuf()->sgetc();
+                if (Traits::eq_int_type(i, Traits::eof()))
+                {
+                    is.setstate(ios_base::eofbit);
+                    break;
+                }
+
+                auto c = Traits::to_char_type(i);
+                if (!ct.is(c, ct.space))
+                    break;
+                else
+                    is.rdbuf()->sbumpc();
+            }
+        }
+
+        return is;
+    }
+
+    using istream  = basic_istream<char>;
+    using wistream = basic_istream<wchar_t>;
+
+    /**
+     * 27.7.2.5, class template basic_iostream:
+     */
+
+    template<class Char, class Traits>
+    class basic_iostream
+        : public basic_istream<Char, Traits>,
+          public basic_ostream<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            explicit basic_iostream(basic_streambuf<char_type, traits_type>* sb)
+                : basic_istream<char_type, traits_type>(sb),
+                  basic_ostream<char_type, traits_type>(sb)
+            { /* DUMMY BODY */ }
+
+            virtual ~basic_iostream()
+            { /* DUMMY BODY */ }
+
+        protected:
+            basic_iostream(const basic_iostream&) = delete;
+            basic_iostream& operator=(const basic_iostream&) = delete;
+
+            basic_iostream(basic_iostream&& other)
+                : basic_istream<char_type, traits_type>(move(other))
+            { /* DUMMY BODY */ }
+
+            basic_iostream& operator=(basic_iostream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_iostream& other)
+            {
+                basic_istream<char_type, traits_type>::swap(other);
+            }
+    };
+
+    using iostream  = basic_iostream<char>;
+    using wiostream = basic_iostream<wchar_t>;
+
+    /**
+     * 27.7.2.6, rvalue stream extraction:
+     */
+
+    template<class Char, class Traits, class T>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>&& is, T& x)
+    {
+        is >> x;
+
+        return is;
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/ostream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,813 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_OSTREAM
+#define LIBCPP_BITS_IO_OSTREAM
+
+#include <ios>
+#include <iosfwd>
+#include <locale>
+
+namespace std
+{
+    /**
+     * 27.7.3.1, class template basic_ostream:
+     */
+
+    template<class Char, class Traits>
+    class basic_ostream: virtual public basic_ios<Char, Traits>
+    {
+        public:
+            using char_type   = Char;
+            using traits_type = Traits;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            /**
+             * 27.7.3.2, constructor/destructor:
+             */
+
+            explicit basic_ostream(basic_streambuf<char_type, traits_type>* sb)
+            {
+                basic_ios<Char, Traits>::init(sb);
+            }
+
+            virtual ~basic_ostream()
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.7.3.4, prefix/suffix:
+             */
+
+            class sentry
+            {
+                public:
+                    explicit sentry(basic_ostream<Char, Traits>& os)
+                        : os_{os}, ok_{false}
+                    {
+                        if (os.good())
+                        {
+                            if (os.tie())
+                                os.tie()->flush();
+                        }
+
+                        ok_ = os.good();
+                    }
+
+                    ~sentry()
+                    {
+                        if ((os_.flags() & ios_base::unitbuf) && os_.good())
+                        {
+                            auto ret = os_.rdbuf()->pubsync();
+                            (void)ret;
+                            // TODO: if ret == -1, set badbit in rdstate
+                        }
+                    }
+
+                    explicit operator bool() const
+                    {
+                        return ok_;
+                    }
+
+                    sentry(const sentry&) = delete;
+                    sentry& operator=(const sentry&) = delete;
+
+                private:
+                    basic_ostream<Char, Traits>& os_;
+                    bool ok_;
+            };
+
+            /**
+             * 27.7.3.6, formatted output:
+             */
+
+            basic_ostream<Char, Traits>& operator<<(
+                basic_ostream<Char, Traits>& (*pf)(basic_ostream<Char, Traits>&)
+            )
+            {
+                return pf(*this);
+            }
+
+            basic_ostream<Char, Traits>& operator<<(
+                basic_ios<Char, Traits>& (*pf)(basic_ios<Char, Traits>&)
+            )
+            {
+                pf(*this);
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(
+                ios_base& (*pf)(ios_base&)
+            )
+            {
+                pf(*this);
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(bool x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(short x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    auto basefield = (this->flags() & ios_base::basefield);
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(),
+                                          (basefield == ios_base::oct || basefield == ios_base::hex)
+                                          ? static_cast<long>(static_cast<unsigned short>(x))
+                                          : static_cast<long>(x)).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(unsigned short x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(),
+                                          static_cast<unsigned long>(x)).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(int x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    auto basefield = (this->flags() & ios_base::basefield);
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(),
+                                          (basefield == ios_base::oct || basefield == ios_base::hex)
+                                          ? static_cast<long>(static_cast<unsigned int>(x))
+                                          : static_cast<long>(x)).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(unsigned int x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(),
+                                          static_cast<unsigned long>(x)).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(long x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(unsigned long x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(long long x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(unsigned long long x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(float x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), static_cast<double>(x)).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(double x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(long double x)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(const void* p)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    bool failed = use_facet<
+                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
+                    >(this->getloc()).put(*this, *this, this->fill(), p).failed();
+
+                    if (failed)
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& operator<<(basic_streambuf<Char, Traits>* sb)
+            {
+                if (!sb)
+                    return *this;
+
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    size_t count{};
+
+                    int_type c = sb->sgetc();
+                    while (!traits_type::eq_int_type(c, traits_type::eof()))
+                    {
+                        this->put(traits_type::to_char_type(c));
+
+                        if (!(*this))
+                            break;
+
+                        ++count;
+                        sb->sbumpc();
+                        c = sb->sgetc();
+                    }
+
+                    if (count == 0)
+                        this->setstate(ios_base::failbit);
+                }
+
+                return *this;
+            }
+
+            /**
+             * 27.7.3.7, unformatted output:
+             * TODO: when we have exceptions, complete these
+             */
+
+            basic_ostream<Char, Traits>& put(char_type c)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    auto ret = this->rdbuf()->sputc(c);
+                    if (traits_type::eq_int_type(ret, traits_type::eof()))
+                        this->setstate(ios_base::badbit);
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& write(const char_type* s, streamsize n)
+            {
+                sentry sen{*this};
+
+                if (sen)
+                {
+                    for (streamsize i = 0; i < n; ++i)
+                    {
+                        auto ret = this->rdbuf()->sputc(s[i]);
+                        if (traits_type::eq_int_type(ret, traits_type::eof()))
+                        {
+                            this->setstate(ios_base::badbit);
+                            break;
+                        }
+                    }
+                }
+
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& flush()
+            {
+                if (this->rdbuf())
+                {
+                    sentry sen{*this};
+
+                    if (sen)
+                    {
+                        auto ret = this->rdbuf()->pubsync();
+                        if (ret == -1)
+                            this->setstate(ios_base::badbit);
+                    }
+                }
+
+                return *this;
+            }
+
+            /**
+             * 27.7.3.5, seeks:
+             */
+
+            pos_type tellp()
+            {
+                // TODO: implement
+                return pos_type{};
+            }
+
+            basic_ostream<Char, Traits>& seekp(pos_type pos)
+            {
+                // TODO: implement
+                return *this;
+            }
+
+            basic_ostream<Char, Traits>& seekp(off_type off, ios_base::seekdir dir)
+            {
+                // TODO: implement
+                return *this;
+            }
+
+        protected:
+            basic_ostream(const basic_ostream&) = delete;
+
+            basic_ostream(basic_ostream&& other)
+            {
+                basic_ios<Char, Traits>::move(other);
+            }
+
+            /**
+             * 27.7.3.3, assign/swap:
+             */
+
+            basic_ostream& operator=(const basic_ostream&) = delete;
+
+            basic_ostream& operator=(basic_ostream&& other)
+            {
+                swap(other);
+
+                return *this;
+            }
+
+            void swap(basic_ostream& rhs)
+            {
+                basic_ios<Char, Traits>::swap(rhs);
+            }
+    };
+
+    using ostream  = basic_ostream<char>;
+    using wostream = basic_ostream<wchar_t>;
+
+    /**
+     * 27.7.6.3.4, character inserter function templates:
+     */
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            Char c)
+    {
+        typename basic_ostream<Char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            if (os.width() > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                    os.put(c);
+                }
+                else
+                {
+                    os.put(c);
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.put(c);
+
+            os.width(0);
+        }
+
+        return os;
+    }
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            char c)
+    {
+        typename basic_ostream<Char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            if (os.width() > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                    os.put(os.widen(c));
+                }
+                else
+                {
+                    os.put(os.widen(c));
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.put(os.widen(c));
+
+            os.width(0);
+        }
+        return os;
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            char c)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            if (os.width() > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                    os.put(c);
+                }
+                else
+                {
+                    os.put(c);
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.put(c);
+
+            os.width(0);
+            }
+
+        return os;
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            signed char c)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            if (os.width() > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                    os.put(c);
+                }
+                else
+                {
+                    os.put(c);
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.put(c);
+
+            os.width(0);
+        }
+
+        return os;
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            unsigned char c)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            if (os.width() > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                    os.put(c);
+                }
+                else
+                {
+                    os.put(c);
+                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.put(c);
+
+            os.width(0);
+        }
+
+        return os;
+    }
+
+    namespace aux
+    {
+        template<class Char, class Traits>
+        basic_ostream<Char, Traits>& insert(basic_ostream<Char, Traits>& os,
+                                            const Char* str, size_t len)
+        {
+            if (os.width() > 0 && static_cast<size_t>(os.width()) > len)
+            {
+                size_t to_pad = (static_cast<size_t>(os.width()) - len);
+
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (size_t i = 0; i < to_pad; ++i)
+                        os.put(os.fill());
+                    for (size_t i = 0; i < len; ++i)
+                        os.put(os.widen(str[i]));
+                }
+                else
+                {
+                    for (size_t i = 0; i < len; ++i)
+                        os.put(os.widen(str[i]));
+                    for (size_t i = 0; i < to_pad; ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+            {
+                for (size_t i = 0; i < len; ++i)
+                    os.put(os.widen(str[i]));
+            }
+
+            os.width(0);
+            return os;
+        }
+    }
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            const Char* str)
+    {
+        typename basic_ostream<Char, Traits>::sentry sen{os};
+
+        auto len = Traits::length(str);
+
+        return aux::insert(os, str, len);
+    }
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            const char* str)
+    {
+        typename basic_ostream<Char, Traits>::sentry sen{os};
+
+        auto len = std::char_traits<char>::length(str);
+
+        return aux::insert(os, str, len);
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            const char* str)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            auto len = Traits::length(str);
+
+            return aux::insert(os, str, len);
+        }
+        else
+            return os;
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            const signed char* str)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            auto len = Traits::length(reinterpret_cast<const char*>(str));
+
+            return aux::insert(os, str, len);
+        }
+        else
+            return os;
+    }
+
+    template<class Traits>
+    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
+                                            const unsigned char* str)
+    {
+        typename basic_ostream<char, Traits>::sentry sen{os};
+
+        if (sen)
+        {
+            auto len = Traits::length(reinterpret_cast<const char*>(str));
+
+            return aux::insert(os, str, len);
+        }
+        else
+            return os;
+    }
+
+    /**
+     * 27.7.3.8, standard basic_ostream manipulators:
+     */
+
+    template<class Char, class Traits = char_traits<Char>>
+    basic_ostream<Char, Traits>& endl(basic_ostream<Char, Traits>& os)
+    {
+        os.put(os.widen('\n'));
+        os.flush();
+
+        return os;
+    }
+
+    template<class Char, class Traits = char_traits<Char>>
+    basic_ostream<Char, Traits>& ends(basic_ostream<Char, Traits>& os)
+    {
+        os.put(Char{});
+
+        return os;
+    }
+
+    template<class Char, class Traits = char_traits<Char>>
+    basic_ostream<Char, Traits>& flush(basic_ostream<Char, Traits>& os)
+    {
+        os.flush();
+
+        return os;
+    }
+
+    template<class Char, class Traits = char_traits<Char>, class T>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>&& os, const T& x)
+    {
+        os << x;
+
+        return os;
+    }
+}
+
+#endif
+
Index: uspace/lib/cpp/include/__bits/io/sstream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/sstream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/sstream.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_SSTREAM
+#define LIBCPP_BITS_IO_SSTREAM
+
+#include <ios>
+#include <iosfwd>
+#include <iostream>
+#include <streambuf>
+#include <string>
+
+namespace std
+{
+    /**
+     * 27.8.2, class template basic_stringbuf:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    class basic_stringbuf: public basic_streambuf<Char, Traits>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using allocator_type = Allocator;
+            using int_type       = typename traits_type::int_type;
+            using pos_type       = typename traits_type::pos_type;
+            using off_type       = typename traits_type::off_type;
+
+            /**
+             * 27.8.2.1, constructors:
+             */
+
+            explicit basic_stringbuf(ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_streambuf<char_type, traits_type>(), mode_{mode}, str_{}
+            {
+                init_();
+            }
+
+            explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type> str,
+                                     ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_streambuf<char_type, traits_type>(), mode_{mode}, str_{str}
+            {
+                init_();
+            }
+
+            basic_stringbuf(const basic_stringbuf&) = delete;
+
+            basic_stringbuf(basic_stringbuf&& other)
+                : mode_{move(other.mode_)}, str_{move(other.str_)}
+            {
+                basic_streambuf<char_type, traits_type>::swap(other);
+            }
+
+            /**
+             * 27.8.2.2, assign and swap:
+             */
+
+            basic_stringbuf& operator=(const basic_stringbuf&) = delete;
+
+            basic_stringbuf& operator=(basic_stringbuf&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_stringbuf& rhs)
+            {
+                std::swap(mode_, rhs.mode_);
+                std::swap(str_, rhs.str_);
+
+                basic_streambuf<char_type, traits_type>::swap(rhs);
+            }
+
+            /**
+             * 27.8.2.3, get and set:
+             */
+
+            basic_string<char_type, traits_type, allocator_type> str() const
+            {
+                if (mode_ & ios_base::out)
+                    return basic_string<char_type, traits_type, allocator_type>{
+                        this->output_begin_, this->output_next_ - 1, str_.get_allocator()
+                    };
+                else if (mode_ == ios_base::in)
+                    return basic_string<char_type, traits_type, allocator_type>{
+                        this->eback(), this->egptr(), str_.get_allocator()
+                    };
+                else
+                    return basic_string<char_type, traits_type, allocator_type>{};
+            }
+
+            void str(const basic_string<char_type, traits_type, allocator_type>& str)
+            {
+                str_ = str;
+                init_();
+            }
+
+        protected:
+            /**
+             * 27.8.2.4, overriden virtual functions:
+             */
+
+            int_type underflow() override
+            {
+                if (this->read_avail_())
+                    return traits_type::to_int_type(*this->gptr());
+                else
+                    return traits_type::eof();
+            }
+
+            int_type pbackfail(int_type c = traits_type::eof()) override
+            {
+                if (!traits_type::eq_int_type(c, traits_type::eof()) &&
+                    this->putback_avail_() &&
+                    traits_type::eq(traits_type::to_char_type(c), this->gptr()[-1]))
+                {
+                    --this->input_next_;
+
+                    return c;
+                }
+                else if (!traits_type::eq_int_type(c, traits_type::eof()) &&
+                         this->putback_avail_() && (mode_ & ios_base::out) != 0)
+                {
+                    *--this->input_next_ = c;
+
+                    return c;
+                }
+                else if (traits_type::eq_int_type(c, traits_type::eof()) &&
+                         this->putback_avail_())
+                {
+                    --this->input_next_;
+
+                    return traits_type::not_eof(c);
+                }
+
+                return traits_type::eof();
+            }
+
+            int_type overflow(int_type c = traits_type::eof()) override
+            {
+                if ((mode_ & ios_base::out) == 0)
+                    return traits_type::eof();
+
+                if (!traits_type::eq_int_type(c, traits_type::eof()))
+                {
+                    if (this->output_next_ < this->output_end_)
+                        return c;
+
+                    auto size = static_cast<size_t>(this->output_next_ - this->output_begin_);
+                    str_.size_ = size;
+
+                    str_.push_back(traits_type::to_char_type(c));
+                    init_();
+
+                    return c;
+                }
+                else if (traits_type::eq_int_type(c, traits_type::eof()))
+                    return traits_type::not_eof(c);
+
+                return traits_type::eof();
+            }
+
+            basic_streambuf<char_type, traits_type>* setbuf(char_type* str, streamsize n) override
+            {
+                if (!str && n == 0)
+                    return this;
+
+                str_.assign(str, str + static_cast<size_t>(n));
+
+                return this;
+            }
+
+            pos_type seekoff(off_type off, ios_base::seekdir dir,
+                             ios_base::openmode mode = ios_base::in | ios_base::out)
+            {
+                if ((mode & ios_base::in) == ios_base::in)
+                {
+                    if (!this->input_next_)
+                        return pos_type(off_type(-1));
+
+                    return seekoff_(off, this->input_begin_, this->input_next_, this->input_end_, dir);
+                }
+                else if ((mode & ios_base::out) == ios_base::out)
+                {
+                    if (!this->output_next_)
+                        return pos_type(off_type(-1));
+
+                    return seekoff_(off, this->output_begin_, this->output_next_, this->output_end_, dir);
+                }
+                else if ((mode & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out) &&
+                          (dir == ios_base::beg || dir == ios_base::end))
+                {
+                    if (!this->input_next_ || !this->output_next_)
+                        return pos_type(off_type(-1));
+
+                    seekoff_(off, this->input_begin_, this->input_next_, this->input_end_, dir);
+                    return seekoff_(off, this->output_begin_, this->output_next_, this->output_end_, dir);
+                }
+
+                return pos_type(off_type(-1));
+            }
+
+            pos_type seekpos(pos_type pos, ios_base::openmode mode = ios_base::in | ios_base::out)
+            {
+                return seekoff(off_type(pos), ios_base::beg, mode);
+            }
+
+        private:
+            ios_base::openmode mode_;
+            basic_string<char_type, traits_type, allocator_type> str_;
+
+            void init_()
+            {
+                if ((mode_ & ios_base::in) != 0)
+                {
+                    this->input_begin_ = this->input_next_ = str_.begin();
+                    this->input_end_ = str_.end();
+                }
+
+                if ((mode_ & ios_base::out) != 0)
+                {
+                    this->output_begin_ = str_.begin();
+                    this->output_next_ = str_.end();
+                    this->output_end_ = str_.begin() + str_.size() + 1;
+                }
+            }
+
+            bool ensure_free_space_(size_t n = 1)
+            {
+                str_.ensure_free_space_(n);
+                this->output_end_ = str_.begin() + str_.capacity();
+
+                return true;
+            }
+
+            pos_type seekoff_(off_type off, char_type* begin, char_type*& next, char_type* end,
+                          ios_base::seekdir dir)
+            {
+                off_type new_off{};
+
+                if (dir == ios_base::beg)
+                    new_off = 0;
+                else if (dir == ios_base::cur)
+                    new_off = static_cast<off_type>(next - begin);
+                else if (dir == ios_base::end)
+                    new_off = static_cast<off_type>(end - begin);
+
+                if (new_off + off < 0 || begin + new_off + off >= end)
+                    return pos_type(off_type(-1));
+                else
+                    next = begin + new_off + off;
+
+                return pos_type(new_off);
+            }
+    };
+
+    template<class Char, class Traits, class Allocator>
+    void swap(basic_stringbuf<Char, Traits, Allocator>& lhs,
+              basic_stringbuf<Char, Traits, Allocator>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 27.8.3, class template basic_istringstream:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    class basic_istringstream: public basic_istream<Char, Traits>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using allocator_type = Allocator;
+            using int_type       = typename traits_type::int_type;
+            using pos_type       = typename traits_type::pos_type;
+            using off_type       = typename traits_type::off_type;
+
+            /**
+             * 27.8.3.1, constructors:
+             */
+
+            explicit basic_istringstream(ios_base::openmode mode = ios_base::in)
+                : basic_istream<char_type, traits_type>(&sb_),
+                  sb_(mode | ios_base::in)
+            { /* DUMMY BODY */ }
+
+            explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type> str,
+                                         ios_base::openmode mode = ios_base::in)
+                : basic_istream<char_type, traits_type>{&sb_},
+                  sb_(str, mode | ios_base::in)
+            { /* DUMMY BODY */ }
+
+            basic_istringstream(const basic_istringstream&) = delete;
+
+            basic_istringstream(basic_istringstream&& other)
+                : basic_istream<char_type, traits_type>{move(other)},
+                  sb_{move(other.sb_)}
+            {
+                basic_istream<char_type, traits_type>::set_rdbuf(&sb_);
+            }
+
+            /**
+             * 27.8.3.2, assign and swap:
+             */
+
+            basic_istringstream& operator=(const basic_istringstream&) = delete;
+
+            basic_istringstream& operator=(basic_istringstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_istringstream& rhs)
+            {
+                basic_istream<char_type, traits_type>::swap(rhs);
+                sb_.swap(rhs.sb_);
+            }
+
+            /**
+             * 27.8.3.3, members:
+             */
+
+            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
+            {
+                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
+            }
+
+            basic_string<char_type, traits_type, allocator_type> str() const
+            {
+                return sb_.str();
+            }
+
+            void str(const basic_string<char_type, traits_type, allocator_type>& str)
+            {
+                sb_.str(str);
+            }
+
+        private:
+            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
+    };
+
+    template<class Char, class Traits, class Allocator>
+    void swap(basic_istringstream<Char, Traits, Allocator>& lhs,
+              basic_istringstream<Char, Traits, Allocator>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class Char, class Traits, class Allocator>
+    class basic_ostringstream: public basic_ostream<Char, Traits>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using allocator_type = Allocator;
+            using int_type       = typename traits_type::int_type;
+            using pos_type       = typename traits_type::pos_type;
+            using off_type       = typename traits_type::off_type;
+
+            /**
+             * 27.8.4.1, constructors:
+             */
+
+            explicit basic_ostringstream(ios_base::openmode mode = ios_base::out)
+                : basic_ostream<char_type, traits_type>(&sb_),
+                  sb_(mode | ios_base::out)
+            { /* DUMMY BODY */ }
+
+            explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type> str,
+                                         ios_base::openmode mode = ios_base::out)
+                : basic_ostream<char_type, traits_type>{&sb_},
+                  sb_(str, mode | ios_base::out)
+            { /* DUMMY BODY */ }
+
+            basic_ostringstream(const basic_ostringstream&) = delete;
+
+            basic_ostringstream(basic_ostringstream&& other)
+                : basic_ostream<char_type, traits_type>{move(other)},
+                  sb_{move(other.sb_)}
+            {
+                basic_ostream<char_type, traits_type>::set_rdbuf(&sb_);
+            }
+
+            /**
+             * 27.8.4.2, assign and swap:
+             */
+
+            basic_ostringstream& operator=(const basic_ostringstream&) = delete;
+
+            basic_ostringstream& operator=(basic_ostringstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_ostringstream& rhs)
+            {
+                basic_ostream<char_type, traits_type>::swap(rhs);
+                sb_.swap(rhs.sb_);
+            }
+
+            /**
+             * 27.8.3.3, members:
+             */
+
+            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
+            {
+                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
+            }
+
+            basic_string<char_type, traits_type, allocator_type> str() const
+            {
+                return sb_.str();
+            }
+
+            void str(const basic_string<char_type, traits_type, allocator_type>& str)
+            {
+                sb_.str(str);
+            }
+
+        private:
+            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
+    };
+
+    /**
+     * 27.8.5, class template basic_stringstream:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    class basic_stringstream: public basic_iostream<Char, Traits>
+    {
+        public:
+            using char_type      = Char;
+            using traits_type    = Traits;
+            using allocator_type = Allocator;
+            using int_type       = typename traits_type::int_type;
+            using pos_type       = typename traits_type::pos_type;
+            using off_type       = typename traits_type::off_type;
+
+            /**
+             * 27.8.5.1, constructors:
+             */
+
+            explicit basic_stringstream(ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_iostream<char_type, traits_type>(&sb_),
+                  sb_(mode | ios_base::out)
+            { /* DUMMY BODY */ }
+
+            explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type> str,
+                                         ios_base::openmode mode = ios_base::in | ios_base::out)
+                : basic_iostream<char_type, traits_type>{&sb_},
+                  sb_(str, mode | ios_base::out)
+            { /* DUMMY BODY */ }
+
+            basic_stringstream(const basic_stringstream&) = delete;
+
+            basic_stringstream(basic_stringstream&& other)
+                : basic_iostream<char_type, traits_type>{move(other)},
+                  sb_{move(other.sb_)}
+            {
+                basic_iostream<char_type, traits_type>::set_rdbuf(&sb_);
+            }
+
+            /**
+             * 27.8.5.2, assign and swap:
+             */
+
+            basic_stringstream& operator=(const basic_stringstream&) = delete;
+
+            basic_stringstream& operator=(basic_stringstream&& other)
+            {
+                swap(other);
+            }
+
+            void swap(basic_stringstream& rhs)
+            {
+                basic_iostream<char_type, traits_type>::swap(rhs);
+                sb_.swap(rhs.sb_);
+            }
+
+            /**
+             * 27.8.5.3, members:
+             */
+
+            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
+            {
+                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
+            }
+
+            basic_string<char_type, traits_type, allocator_type> str() const
+            {
+                return sb_.str();
+            }
+
+            void str(const basic_string<char_type, traits_type, allocator_type>& str)
+            {
+                sb_.str(str);
+            }
+
+        private:
+            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/streambuf.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/streambuf.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/streambuf.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_STREAMBUF
+#define LIBCPP_BITS_IO_STREAMBUF
+
+#include <ios>
+#include <iosfwd>
+#include <locale>
+
+namespace std
+{
+
+    /**
+     * 27.6.3, class template basic_streambuf:
+     */
+
+    template<class Char, class Traits>
+    class basic_streambuf
+    {
+        public:
+            using traits_type = Traits;
+            using char_type   = Char;
+            using int_type    = typename traits_type::int_type;
+            using pos_type    = typename traits_type::pos_type;
+            using off_type    = typename traits_type::off_type;
+
+            virtual ~basic_streambuf()
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.6.3.2.1, locales:
+             */
+
+            locale pubimbue(const locale& loc)
+            {
+                imbue(loc);
+
+                return locale_;
+            }
+
+            locale& getloc() const
+            {
+                return locale_;
+            }
+
+            /**
+             * 27.6.3.2.2, buffer and positioning:
+             */
+
+            basic_streambuf<Char, Traits>* pubsetbuf(char_type* s, streamsize n)
+            {
+                return setbuf(s, n);
+            }
+
+            pos_type pubseekoff(off_type off, ios_base::seekdir way,
+                                ios_base::openmode which = ios_base::in | ios_base::out)
+            {
+                return seekoff(off, way, which);
+            }
+
+            pos_type pubseekpos(pos_type pos, ios_base::openmode which =
+                                ios_base::in | ios_base::out)
+            {
+                return seekpos(pos, which);
+            }
+
+            int pubsync()
+            {
+                return sync();
+            }
+
+            /**
+             * 27.6.3.2.3, get area:
+             */
+
+            streamsize in_avail()
+            {
+                if (read_avail_())
+                    return egptr() - gptr();
+                else
+                    return showmanyc();
+            }
+
+            int_type snextc()
+            {
+                if (traits_type::eq(sbumpc(), traits_type::eof()))
+                    return traits_type::eof();
+                else
+                    return sgetc();
+            }
+
+            int_type sbumpc()
+            {
+                if (read_avail_())
+                    return traits_type::to_int_type(*input_next_++);
+                else
+                    return uflow();
+            }
+
+            int_type sgetc()
+            {
+                if (read_avail_())
+                    return traits_type::to_int_type(*input_next_);
+                else
+                    return underflow();
+            }
+
+            streamsize sgetn(char_type* s, streamsize n)
+            {
+                return xsgetn(s, n);
+            }
+
+            /**
+             * 27.6.2.4, putback:
+             */
+
+            int_type sputbackc(char_type c)
+            {
+                if (!putback_avail_() || traits_type::eq(c, gptr()[-1]))
+                    return pbackfail(traits_type::to_int_type(c));
+                else
+                    return traits_type::to_int_type(*(--input_next_));
+            }
+
+            int_type sungetc()
+            {
+                if (!putback_avail_())
+                    return pbackfail();
+                else
+                    return traits_type::to_int_type(*(--input_next_));
+            }
+
+            /**
+             * 27.6.2.5, put area:
+             */
+
+            int_type sputc(char_type c)
+            {
+                if (!write_avail_())
+                    return overflow(traits_type::to_int_type(c));
+                else
+                {
+                    traits_type::assign(*output_next_++, c);
+
+                    return traits_type::to_int_type(c);
+                }
+            }
+
+            streamsize sputn(const char_type* s, streamsize n)
+            {
+                return xsputn(s, n);
+            }
+
+        protected:
+            basic_streambuf()
+                : input_begin_{}, input_next_{}, input_end_{},
+                  output_begin_{}, output_next_{}, output_end_{},
+                  locale_{locale()}
+            { /* DUMMY BODY */ }
+
+            basic_streambuf(const basic_streambuf& rhs)
+            {
+                input_begin_ = rhs.input_begin_;
+                input_next_ = rhs.input_next_;
+                input_end_ = rhs.input_end_;
+
+                output_begin_ = rhs.output_begin_;
+                output_next_ = rhs.output_next_;
+                output_end_ = rhs.output_end_;
+
+                locale_ = rhs.locale_;
+            }
+
+            basic_streambuf& operator=(const basic_streambuf& rhs)
+            {
+                input_begin_ = rhs.input_begin_;
+                input_next_  = rhs.input_next_;
+                input_end_   = rhs.input_end_;
+
+                output_begin_ = rhs.output_begin_;
+                output_next_  = rhs.output_next_;
+                output_end_   = rhs.output_end_;
+
+                locale_ = rhs.locale_;
+
+                return *this;
+            }
+
+            void swap(basic_streambuf& rhs)
+            {
+                swap(input_begin_, rhs.input_begin_);
+                swap(input_next_, rhs.input_next_);
+                swap(input_end_, rhs.input_end_);
+
+                swap(output_begin_, rhs.output_begin_);
+                swap(output_next_, rhs.output_next_);
+                swap(output_end_, rhs.output_end_);
+
+                swap(locale_, rhs.locale_);
+            }
+
+            /**
+             * 27.6.3.3.2, get area:
+             */
+
+            char_type* eback() const
+            {
+                return input_begin_;
+            }
+
+            char_type* gptr() const
+            {
+                return input_next_;
+            }
+
+            char_type* egptr() const
+            {
+                return input_end_;
+            }
+
+            void gbump(int n)
+            {
+                input_next_ += n;
+            }
+
+            void setg(char_type* gbeg, char_type* gnext, char_type* gend)
+            {
+                input_begin_ = gbeg;
+                input_next_  = gnext;
+                input_end_   = gend;
+            }
+
+            /**
+             * 27.6.3.3.3, put area:
+             */
+
+            char_type* pbase() const
+            {
+                return output_begin_;
+            }
+
+            char_type* pptr() const
+            {
+                return output_next_;
+            }
+
+            char_type* epptr() const
+            {
+                return output_end_;
+            }
+
+            void pbump(int n)
+            {
+                output_next_ += n;
+            }
+
+            void setp(char_type* pbeg, char_type* pend)
+            {
+                output_begin_ = pbeg;
+                output_next_  = pbeg;
+                output_end_   = pend;
+            }
+
+            /**
+             * 27.6.3.4.1, locales:
+             */
+
+            virtual void imbue(const locale& loc)
+            { /* DUMMY BODY */ }
+
+            /**
+             * 27.6.3.4.2, buffer management and positioning:
+             */
+
+            virtual basic_streambuf<Char, Traits>*
+            setbuf(char_type* s, streamsize n)
+            {
+                return this;
+            }
+
+            virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+                                     ios_base::openmode which = ios_base::in | ios_base::out)
+            {
+                return pos_type(off_type(-1));
+            }
+
+            virtual pos_type seekpos(pos_type pos, ios_base::openmode which =
+                                     ios_base::in | ios_base::out)
+            {
+                return pos_type(off_type(-1));
+            }
+
+            virtual int sync()
+            {
+                return 0;
+            }
+
+            /**
+             * 27.6.3.4.3, get area:
+             */
+
+            virtual streamsize showmanyc()
+            {
+                return 0;
+            }
+
+            virtual streamsize xsgetn(char_type* s, streamsize n)
+            {
+                if (!s || n == 0)
+                    return 0;
+
+                streamsize i{0};
+                auto eof = traits_type::eof();
+                for (; i <= n; ++i)
+                {
+                    if (!read_avail_() && traits_type::eq_int_type(uflow(), eof))
+                        break;
+
+                    *s++ = *input_next_++;
+                }
+
+                return i;
+            }
+
+            virtual int_type underflow()
+            {
+                return traits_type::eof();
+            }
+
+            virtual int_type uflow()
+            {
+                auto res = underflow();
+                if (traits_type::eq_int_type(res, traits_type::eof()))
+                    return traits_type::eof();
+                else
+                    return traits_type::to_int_type(*input_next_++);
+            }
+
+            /**
+             * 27.6.3.4.4, putback:
+             */
+
+            virtual int_type pbackfail(int_type c = traits_type::eof())
+            {
+                return traits_type::eof();
+            }
+
+            /**
+             * 27.6.3.4.5, put area:
+             */
+
+            virtual streamsize xsputn(const char_type* s, streamsize n)
+            {
+                if (!s || n == 0)
+                    return 0;
+
+                streamsize i{0};
+                for (; i <= n; ++i)
+                {
+                    if (!write_avail_() && traits_type::eq_int_type(overflow(), traits_type::eof()))
+                        break;
+
+                    *output_next_++ = *s++;
+                }
+
+                return i;
+            }
+
+            virtual int_type overflow(int_type c = traits_type::eof())
+            {
+                return traits_type::eof();
+            }
+
+        protected:
+            char_type* input_begin_;
+            char_type* input_next_;
+            char_type* input_end_;
+
+            char_type* output_begin_;
+            char_type* output_next_;
+            char_type* output_end_;
+
+            locale locale_;
+
+            bool write_avail_() const
+            {
+                return output_next_ && output_next_ < output_end_;
+            }
+
+            bool putback_avail_() const
+            {
+                return input_next_ && input_begin_ < input_next_;
+            }
+
+            bool read_avail_() const
+            {
+                return input_next_ && input_next_ < input_end_;
+            }
+    };
+
+    using streambuf  = basic_streambuf<char>;
+    using wstreambuf = basic_streambuf<wchar_t>;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/io/streambufs.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/streambufs.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/io/streambufs.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_IO_STREAMBUFS
+#define LIBCPP_BITS_IO_STREAMBUFS
+
+#include <iosfwd>
+#include <cstdio>
+#include <streambuf>
+
+namespace std::aux
+{
+    template<class Char, class Traits = char_traits<Char>>
+    class stdin_streambuf : public basic_streambuf<Char, Traits>
+    {
+        public:
+            stdin_streambuf()
+                : basic_streambuf<Char, Traits>{}, buffer_{nullptr}
+            { /* DUMMY BODY */ }
+
+            virtual ~stdin_streambuf()
+            {
+                if (buffer_)
+                    delete[] buffer_;
+            }
+
+        protected:
+            using traits_type = Traits;
+            using char_type   = typename traits_type::char_type;
+            using int_type    = typename traits_type::int_type;
+            using off_type    = typename traits_type::off_type;
+
+            using basic_streambuf<Char, Traits>::input_begin_;
+            using basic_streambuf<Char, Traits>::input_next_;
+            using basic_streambuf<Char, Traits>::input_end_;
+
+            int_type underflow() override
+            {
+                if (!this->gptr())
+                {
+                    buffer_ = new char_type[buf_size_];
+                    input_begin_ = input_next_ = input_end_ = buffer_;
+                }
+
+                off_type i{};
+                if (input_next_ < input_end_)
+                {
+                    auto idx = static_cast<off_type>(input_next_ - input_begin_);
+                    auto count = buf_size_ - idx;
+
+                    for (; i < count; ++i, ++idx)
+                        buffer_[i] = buffer_[idx];
+                }
+
+                for (; i < buf_size_; ++i)
+                {
+                    auto c = fgetc(in_);
+                    putchar(c); // TODO: Temporary source of feedback.
+                    if (c == traits_type::eof())
+                        break;
+
+                    buffer_[i] = static_cast<char_type>(c);
+
+                    if (buffer_[i] == '\n')
+                    {
+                        ++i;
+                        break;
+                    }
+                }
+
+                input_next_ = input_begin_;
+                input_end_ = input_begin_ + i;
+
+                if (i == 0)
+                    return traits_type::eof();
+
+                return traits_type::to_int_type(*input_next_);
+            }
+
+            int_type uflow() override
+            {
+                auto res = underflow();
+                ++input_next_;
+
+                return res;
+            }
+
+            void imbue(const locale& loc)
+            {
+                this->locale_ = loc;
+            }
+
+        private:
+            FILE* in_{stdin};
+
+            char_type* buffer_;
+
+            static constexpr off_type buf_size_{128};
+    };
+
+    template<class Char, class Traits = char_traits<Char>>
+    class stdout_streambuf: public basic_streambuf<Char, Traits>
+    {
+        public:
+            stdout_streambuf()
+                : basic_streambuf<Char, Traits>{}
+            { /* DUMMY BODY */ }
+
+            virtual ~stdout_streambuf()
+            { /* DUMMY BODY */ }
+
+        protected:
+            using traits_type = Traits;
+            using char_type   = typename traits_type::char_type;
+            using int_type    = typename traits_type::int_type;
+            using off_type    = typename traits_type::off_type;
+
+            int_type overflow(int_type c = traits_type::eof()) override
+            {
+                if (!traits_type::eq_int_type(c, traits_type::eof()))
+                {
+                    auto cc = traits_type::to_char_type(c);
+                    fwrite(&cc, sizeof(char_type), 1, out_);
+                }
+
+                return traits_type::not_eof(c);
+            }
+
+            streamsize xsputn(const char_type* s, streamsize n) override
+            {
+                return fwrite(s, sizeof(char_type), n, out_);
+            }
+
+            int sync() override
+            {
+                if (fflush(out_))
+                    return -1;
+                return 0;
+            }
+
+        private:
+            FILE* out_{stdout};
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/iomanip.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/iomanip.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_IOMANIP
-#define LIBCPP_BITS_IOMANIP
-
-#include <ios>
-#include <utility>
-
-namespace std::aux
-{
-    /**
-     * Note: This allows us to lower the amount
-     *       of code duplication in this module
-     *       as we can avoid operator<</>> overloading
-     *       for the manipulators.
-     */
-    template<class Manipulator>
-    struct manip_wrapper
-    {
-        template<class... Args>
-        manip_wrapper(Args&&... args)
-            : manipulator{forward<Args>(args)...}
-        { /* DUMMY BODY */ }
-
-        void operator()(ios_base& str)
-        {
-            manipulator(str);
-        }
-
-        Manipulator manipulator;
-    };
-    template<class Char, class Traits, class Manipulator>
-    basic_ostream<Char, Traits>& operator<<(
-        basic_ostream<Char, Traits>& os, manip_wrapper<Manipulator> manip
-    )
-    {
-        manip(os);
-
-        return os;
-    }
-
-    template<class Char, class Traits, class Manipulator>
-    basic_istream<Char, Traits>& operator>>(
-        basic_istream<Char, Traits>& is, manip_wrapper<Manipulator> manip
-    )
-    {
-        manip(is);
-
-        return is;
-    }
-
-    struct resetiosflags_t
-    {
-        resetiosflags_t(ios_base::fmtflags m);
-
-        void operator()(ios_base& str) const;
-
-        ios_base::fmtflags mask;
-    };
-
-    struct setiosflags_t
-    {
-        setiosflags_t(ios_base::fmtflags m);
-
-        void operator()(ios_base& str) const;
-
-        ios_base::fmtflags mask;
-    };
-
-    struct setbase_t
-    {
-        setbase_t(int b);
-
-        void operator()(ios_base& str) const;
-
-        int base;
-    };
-
-    /**
-     * Note: setfill is only for basic_ostream so
-     *       this is the only case where we overload
-     *       the appropriate operator again.
-     */
-    template<class Char>
-    struct setfill_t
-    {
-        setfill_t(Char c)
-            : fill{c}
-        { /* DUMMY BODY */ }
-
-        template<class Traits>
-        void operator()(basic_ios<Char, Traits>& str) const
-        {
-            str.fill(fill);
-        }
-
-        Char fill;
-    };
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(
-        basic_ostream<Char, Traits>& is,
-        setfill_t<Char> manip
-    )
-    {
-        manip(is);
-
-        return is;
-    }
-
-    struct setprecision_t
-    {
-        setprecision_t(int);
-
-        void operator()(ios_base&) const;
-
-        int prec;
-    };
-
-    struct setw_t
-    {
-        setw_t(int);
-
-        void operator()(ios_base&) const;
-
-        int width;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/iterator.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/iterator.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/iterator.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -30,39 +30,1164 @@
 #define LIBCPP_BITS_ITERATOR
 
-#include <__bits/aux.hpp>
-
-namespace std::aux
+#include <__bits/memory/addressof.hpp>
+#include <cstdlib>
+#include <initializer_list>
+#include <iosfwd>
+#include <type_traits>
+#include <utility>
+
+namespace std
 {
     /**
-     * Used for our custom iterators where we know
-     * that their references/const_references and
-     * pointers/const_pointers differ only in constness.
-     */
+     * 24.4.3, standard iterator tags:
+     */
+
+    struct input_iterator_tag
+    { /* DUMMY BODY */ };
+
+    struct output_iterator_tag
+    { /* DUMMY BODY */ };
+
+    struct forward_iterator_tag: input_iterator_tag
+    { /* DUMMY BODY */ };
+
+    struct bidirectional_iterator_tag: forward_iterator_tag
+    { /* DUMMY BODY */ };
+
+    struct random_access_iterator_tag: bidirectional_iterator_tag
+    { /* DUMMY BODY */ };
+
+    /**
+     * 24.4.1, iterator traits:
+     */
+
+    template<class Iterator>
+    struct iterator_traits
+    {
+        using difference_type   = typename Iterator::difference_type;
+        using value_type        = typename Iterator::value_type;
+        using iterator_category = typename Iterator::iterator_category;
+        using reference         = typename Iterator::reference;
+        using pointer           = typename Iterator::pointer;
+    };
 
     template<class T>
-    struct get_non_const_ref
-        : type_is<T>
-    { /* DUMMY BODY */ };
+    struct iterator_traits<T*>
+    {
+        using difference_type   = ptrdiff_t;
+        using value_type        = T;
+        using iterator_category = random_access_iterator_tag;
+        using reference         = T&;
+        using pointer           = T*;
+    };
 
     template<class T>
-    struct get_non_const_ref<const T&>
-        : type_is<T&>
-    { /* DUMMY BODY */ };
+    struct iterator_traits<const T*>
+    {
+        using difference_type   = ptrdiff_t;
+        using value_type        = T;
+        using iterator_category = random_access_iterator_tag;
+        using reference         = const T&;
+        using pointer           = const T*;
+    };
+
+    /**
+     * 24.4.2, basic iterator:
+     */
+
+    template<
+        class Category, class T, class Distance = ptrdiff_t,
+        class Pointer = T*, class Reference = T&
+    >
+    struct iterator
+    {
+        using difference_type   = Distance;
+        using value_type        = T;
+        using iterator_category = Category;
+        using reference         = Reference;
+        using pointer           = Pointer;
+    };
+
+    /**
+     * 24.4.4, iterator operations
+     */
+
+    template<class InputIterator, class Distance>
+    void advance(InputIterator& it, Distance n)
+    {
+        for (Distance i = Distance{}; i < n; ++i)
+            ++it;
+    }
+
+    template<class InputIterator>
+    typename iterator_traits<InputIterator>::difference_type
+    distance(InputIterator first, InputIterator last)
+    {
+        using cat_t = typename iterator_traits<InputIterator>::iterator_category;
+        using diff_t = typename iterator_traits<InputIterator>::difference_type;
+
+        if constexpr (is_same_v<cat_t, random_access_iterator_tag>)
+            return last - first;
+        else
+        {
+            diff_t diff{};
+            while (first != last)
+            {
+                ++diff;
+                ++first;
+            }
+
+            return diff;
+        }
+    }
+
+    template<class ForwardIterator>
+    ForwardIterator
+    next(ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1)
+    {
+        advance(it, n);
+
+        return it;
+    }
+
+    template<class BidirectionalIterator>
+    BidirectionalIterator
+    prev(BidirectionalIterator it,
+         typename iterator_traits<BidirectionalIterator>::difference_type n = 1)
+    {
+        advance(it, -n);
+
+        return it;
+    }
+
+    /**
+     * 24.5.1, reverse iterator:
+     */
+
+    template<class Iterator>
+    class reverse_iterator
+        : public iterator<
+            typename iterator_traits<Iterator>::iterator_category,
+            typename iterator_traits<Iterator>::value_type,
+            typename iterator_traits<Iterator>::difference_type,
+            typename iterator_traits<Iterator>::pointer,
+            typename iterator_traits<Iterator>::reference
+          >
+    {
+        public:
+            using iterator_type   = Iterator;
+            using difference_type = typename iterator_traits<Iterator>::difference_type;
+            using reference       = typename iterator_traits<Iterator>::reference;
+            using pointer         = typename iterator_traits<Iterator>::pointer;
+
+            reverse_iterator()
+                : current_{}
+            { /* DUMMY BODY */ }
+
+            explicit reverse_iterator(Iterator it)
+                : current_{it}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            reverse_iterator(const reverse_iterator<U>& other)
+                : current_{other.current_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            reverse_iterator& operator=(const reverse_iterator<U>& other)
+            {
+                current_ = other.base();
+
+                return *this;
+            }
+
+            Iterator base() const
+            {
+                return current_;
+            }
+
+            reference operator*() const
+            {
+                auto tmp = current_;
+
+                return *(--tmp);
+            }
+
+            pointer operator->() const
+            {
+                return addressof(operator*());
+            }
+
+            reverse_iterator& operator++()
+            {
+                --current_;
+
+                return *this;
+            }
+
+            reverse_iterator operator++(int)
+            {
+                auto tmp = *this;
+                --current_;
+
+                return tmp;
+            }
+
+            reverse_iterator& operator--()
+            {
+                ++current_;
+
+                return *this;
+            }
+
+            reverse_iterator operator--(int)
+            {
+                auto tmp = *this;
+                ++current_;
+
+                return tmp;
+            }
+
+            reverse_iterator operator+(difference_type n) const
+            {
+                return reverse_iterator{current_ - n};
+            }
+
+            reverse_iterator& operator+=(difference_type n)
+            {
+                current_ -= n;
+
+                return *this;
+            }
+
+            reverse_iterator operator-(difference_type n) const
+            {
+                return reverse_iterator{current_ + n};
+            }
+
+            reverse_iterator& operator-=(difference_type n)
+            {
+                current_ += n;
+
+                return *this;
+            }
+
+            auto operator[](difference_type n) const
+            {
+                return current_[-n - 1];
+            }
+
+        protected:
+            Iterator current_;
+    };
+
+    template<class Iterator1, class Iterator2>
+    bool operator==(const reverse_iterator<Iterator1>& lhs,
+                    const reverse_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() == rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator<(const reverse_iterator<Iterator1>& lhs,
+                   const reverse_iterator<Iterator2>& rhs)
+    {
+        // Remember: they are reversed!
+        return lhs.base() > rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator!=(const reverse_iterator<Iterator1>& lhs,
+                    const reverse_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() != rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator>(const reverse_iterator<Iterator1>& lhs,
+                   const reverse_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() < rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator>=(const reverse_iterator<Iterator1>& lhs,
+                    const reverse_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() <= rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator<=(const reverse_iterator<Iterator1>& lhs,
+                    const reverse_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() >= rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    auto operator-(const reverse_iterator<Iterator1>& lhs,
+                   const reverse_iterator<Iterator2>& rhs)
+        -> decltype(rhs.base() - lhs.base())
+    {
+        return rhs.base() - lhs.base();
+    }
+
+    template<class Iterator>
+    reverse_iterator<Iterator> operator+(
+        typename reverse_iterator<Iterator>::difference_type n,
+        const reverse_iterator<Iterator>& it
+    )
+    {
+        return reverse_iterator<Iterator>{it.base() - n};
+    }
+
+    template<class Iterator>
+    reverse_iterator<Iterator> make_reverse_iterator(Iterator it)
+    {
+        return reverse_iterator<Iterator>(it);
+    }
+
+    /**
+     * 24.5.2, insert iterators:
+     */
+
+    /**
+     * 24.5.2.1, back insert iterator:
+     */
+
+    template<class Container>
+    class back_insert_iterator
+        : public iterator<output_iterator_tag, void, void, void, void>
+    {
+        public:
+            using container_type = Container;
+
+            explicit back_insert_iterator(Container& cont)
+                : container{std::addressof(cont)}
+            { /* DUMMY BODY */ }
+
+            back_insert_iterator& operator=(const typename container_type::value_type& value)
+            {
+                container->push_back(value);
+                return *this;
+            }
+
+            back_insert_iterator& operator=(typename container_type::value_type&& value)
+            {
+                container->push_back(move(value));
+                return *this;
+            }
+
+            back_insert_iterator& operator*()
+            {
+                return *this;
+            }
+
+            back_insert_iterator& operator++()
+            {
+                return *this;
+            }
+
+            back_insert_iterator operator++(int)
+            {
+                return *this;
+            }
+
+        protected:
+            Container* container;
+    };
+
+    template<class Container>
+    back_insert_iterator<Container> back_inserter(Container& cont)
+    {
+        return back_insert_iterator<Container>(cont);
+    }
+
+    /**
+     * 24.5.2.3, front insert iterator:
+     */
+
+    template<class Container>
+    class front_insert_iterator
+        : public iterator<output_iterator_tag, void, void, void, void>
+    {
+        public:
+            using container_type = Container;
+
+            explicit front_insert_iterator(Container& cont)
+                : container{std::addressof(cont)}
+            { /* DUMMY BODY */ }
+
+            front_insert_iterator& operator=(const typename container_type::value_type& value)
+            {
+                container->push_front(value);
+                return *this;
+            }
+
+            front_insert_iterator& operator=(typename container_type::value_type&& value)
+            {
+                container->push_front(move(value));
+                return *this;
+            }
+
+            front_insert_iterator& operator*()
+            {
+                return *this;
+            }
+
+            front_insert_iterator& operator++()
+            {
+                return *this;
+            }
+
+            front_insert_iterator operator++(int)
+            {
+                return *this;
+            }
+
+        protected:
+            Container* container;
+    };
+
+    template<class Container>
+    front_insert_iterator<Container> front_inserter(Container& cont)
+    {
+        return front_insert_iterator<Container>(cont);
+    }
+
+    /**
+     * 24.5.2.5, front insert iterator:
+     */
+
+    template<class Container>
+    class insert_iterator
+        : public iterator<output_iterator_tag, void, void, void, void>
+    {
+        public:
+            using container_type = Container;
+
+            explicit insert_iterator(Container& cont, typename Container::iterator i)
+                : container{std::addressof(cont)}, iter{i}
+            { /* DUMMY BODY */ }
+
+            insert_iterator& operator=(const typename container_type::value_type& value)
+            {
+                iter = container.insert(iter, value);
+                ++iter;
+
+                return *this;
+            }
+
+            insert_iterator& operator=(typename container_type::value_type&& value)
+            {
+                iter = container.insert(iter, move(value));
+                ++iter;
+
+                return *this;
+            }
+
+            insert_iterator& operator*()
+            {
+                return *this;
+            }
+
+            insert_iterator& operator++()
+            {
+                return *this;
+            }
+
+            insert_iterator operator++(int)
+            {
+                return *this;
+            }
+
+        protected:
+            Container* container;
+            typename Container::iterator iter;
+    };
+
+    template<class Container>
+    insert_iterator<Container> inserter(Container& cont, typename Container::iterator i)
+    {
+        return insert_iterator<Container>(cont, i);
+    }
+
+    /**
+     * 24.5.3.1, move iterator:
+     */
+
+    namespace aux
+    {
+        template<class Iterator, class = void>
+        struct move_it_get_reference
+        {
+            using type = typename iterator_traits<Iterator>::reference;
+        };
+
+        template<class Iterator>
+        struct move_it_get_reference<
+            Iterator, enable_if_t<
+                is_reference<typename iterator_traits<Iterator>::reference>::value,
+                void
+            >
+        >
+        {
+            using type = remove_reference_t<typename iterator_traits<Iterator>::reference>&&;
+        };
+    }
+
+    template<class Iterator>
+    class move_iterator
+    {
+        public:
+            using iterator_type     = Iterator;
+            using pointer           = iterator_type;
+            using difference_type   = typename iterator_traits<iterator_type>::difference_type;
+            using value_type        = typename iterator_traits<iterator_type>::value_type;
+            using iterator_category = typename iterator_traits<iterator_type>::iterator_category;
+            using reference         = typename aux::move_it_get_reference<iterator_type>::type;
+
+            move_iterator()
+                : current_{}
+            { /* DUMMY BODY */ }
+
+            explicit move_iterator(iterator_type i)
+                : current_{i}
+            { /* DUMMY BODY */ }
+
+            // TODO: both require is_convertible
+            template<class U>
+            move_iterator(const move_iterator<U>& other)
+                : current_{other.current_}
+            { /* DUMMY BODY */ }
+
+            template<class U>
+            move_iterator& operator=(const move_iterator<U>& other)
+            {
+                current_ = other.current_;
+
+                return *this;
+            }
+
+            iterator_type base() const
+            {
+                return current_;
+            }
+
+            reference operator*() const
+            {
+                return static_cast<reference>(*current_);
+            }
+
+            pointer operator->() const
+            {
+                return current_;
+            }
+
+            move_iterator& operator++()
+            {
+                ++current_;
+
+                return *this;
+            }
+
+            move_iterator operator++(int)
+            {
+                auto tmp = *this;
+                ++current_;
+
+                return tmp;
+            }
+
+            move_iterator& operator--()
+            {
+                --current_;
+
+                return *this;
+            }
+
+            move_iterator operator--(int)
+            {
+                auto tmp = *this;
+                --current_;
+
+                return tmp;
+            }
+
+            move_iterator operator+(difference_type n) const
+            {
+                return move_iterator(current_ + n);
+            }
+
+            move_iterator& operator+=(difference_type n)
+            {
+                current_ += n;
+
+                return *this;
+            }
+
+            move_iterator operator-(difference_type n) const
+            {
+                return move_iterator(current_ - n);
+            }
+
+            move_iterator& operator-=(difference_type n)
+            {
+                current_ -= n;
+
+                return *this;
+            }
+
+            auto operator[](difference_type idx) const
+            {
+                return move(current_[idx]);
+            }
+
+        private:
+            iterator_type current_;
+    };
+
+    template<class Iterator1, class Iterator2>
+    bool operator==(const move_iterator<Iterator1>& lhs,
+                    const move_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() == rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator!=(const move_iterator<Iterator1>& lhs,
+                    const move_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() != rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator<(const move_iterator<Iterator1>& lhs,
+                   const move_iterator<Iterator2>& rhs)
+    {
+        return lhs.base() < rhs.base();
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator<=(const move_iterator<Iterator1>& lhs,
+                    const move_iterator<Iterator2>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator>(const move_iterator<Iterator1>& lhs,
+                   const move_iterator<Iterator2>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class Iterator1, class Iterator2>
+    bool operator>=(const move_iterator<Iterator1>& lhs,
+                    const move_iterator<Iterator2>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class Iterator1, class Iterator2>
+    auto operator-(const move_iterator<Iterator1>& lhs,
+                   const move_iterator<Iterator2>& rhs)
+        -> decltype(rhs.base() - lhs.base())
+    {
+        return lhs.base() - rhs.base();
+    }
+
+    template<class Iterator>
+    move_iterator<Iterator> operator+(
+        typename move_iterator<Iterator>::difference_type n,
+        const move_iterator<Iterator>& it
+    )
+    {
+        return it + n;
+    }
+
+    template<class Iterator>
+    move_iterator<Iterator> make_move_iterator(Iterator it)
+    {
+        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:
+                    proxy_type(int_type c, streambuf_type* sbuf)
+                        : char_{c}, sbuf_{sbuf}
+                    { /* DUMMY BODY */ }
+
+                    char_type operator*()
+                    {
+                        return traits_type::to_char_type(char_);
+                    }
+
+                private:
+                    int_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 */ // TODO: Should be 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>
-    using get_non_const_ref_t = typename get_non_const_ref<T>::type;
+    reverse_iterator<const T*> rbegin(initializer_list<T> init)
+    {
+        return reverse_iterator<const T*>{init.end()};
+    }
 
     template<class T>
-    struct get_non_const_ptr
-        : type_is<T>
-    { /* DUMMY BODY */ };
+    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>
-    struct get_non_const_ptr<const T*>
-        : type_is<T*>
-    { /* DUMMY BODY */ };
+    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>
-    using get_non_const_ptr_t = typename get_non_const_ptr<T>::type;
+    constexpr const T* data(initializer_list<T> init) noexcept
+    {
+        return init.begin();
+    }
 }
 
Index: uspace/lib/cpp/include/__bits/iterator_helpers.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/iterator_helpers.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/iterator_helpers.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_ITERATOR_HELPERS
+#define LIBCPP_BITS_ITERATOR_HELPERS
+
+#include <__bits/aux.hpp>
+
+namespace std::aux
+{
+    /**
+     * Used for our custom iterators where we know
+     * that their references/const_references and
+     * pointers/const_pointers differ only in constness.
+     */
+
+    template<class T>
+    struct get_non_const_ref
+        : type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct get_non_const_ref<const T&>
+        : type_is<T&>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using get_non_const_ref_t = typename get_non_const_ref<T>::type;
+
+    template<class T>
+    struct get_non_const_ptr
+        : type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct get_non_const_ptr<const T*>
+        : type_is<T*>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using get_non_const_ptr_t = typename get_non_const_ptr<T>::type;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/key_extractors.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/key_extractors.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_KEY_EXTRACTORS
-#define LIBCPP_BITS_KEY_EXTRACTORS
-
-#include <utility>
-
-namespace std::aux
-{
-    template<class Key, class Value>
-    struct key_value_key_extractor
-    {
-        const Key& operator()(const pair<const Key, Value>& p) const noexcept
-        {
-            return p.first;
-        }
-    };
-
-    template<class Key>
-    struct key_no_value_key_extractor
-    {
-        Key& operator()(Key& k) const noexcept
-        {
-            return k;
-        }
-
-        const Key& operator()(const Key& k) const noexcept
-        {
-            return k;
-        }
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/limits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/limits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/limits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,627 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_LIMITS
+#define LIBCPP_BITS_LIMITS
+
+#include <cstdint>
+#include <climits>
+
+namespace std
+{
+
+    /**
+     * 18.3.2.5, type float_round_style:
+     */
+
+    enum float_round_style
+    {
+        round_indeterminate       = -1,
+        round_toward_zero         =  0,
+        round_to_nearest          =  1,
+        round_toward_infinity     =  2,
+        round_toward_neg_infinity =  3
+    };
+
+    /**
+     * 18.3.2.6, type float_denorm_style:
+     */
+
+    enum float_denorm_style
+    {
+        denorm_indeterminate = -1,
+        denorm_absent        =  0,
+        denorm_present       =  1
+    };
+
+    /**
+     * 18.3.2.3, class template numeric_limits:
+     */
+
+    namespace aux
+    {
+        template<class T>
+        class numeric_limits
+        {
+            public:
+                static constexpr bool is_specialized = false;
+
+                static constexpr T min() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T max() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T lowest() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr int digits       = 0;
+                static constexpr int digits10     = 0;
+                static constexpr int max_digits10 = 0;
+
+                static constexpr bool is_signed  = false;
+                static constexpr bool is_integer = false;
+                static constexpr bool is_exact   = false;
+
+                static constexpr int radix = 0;
+
+                static constexpr T epsilon() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T round_error() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr int min_exponent   = 0;
+                static constexpr int min_exponent10 = 0;
+                static constexpr int max_exponent   = 0;
+                static constexpr int max_exponent10 = 0;
+
+                static constexpr bool has_infinity      = false;
+                static constexpr bool has_quiet_NaN     = false;
+                static constexpr bool has_signaling_NaN = false;
+
+                static constexpr float_denorm_style has_denorm = denorm_absent;
+                static constexpr bool has_denorm_loss          = false;
+
+                static constexpr T infinity() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T quiet_NaN() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T signaling_NaN() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr T denorm_min() noexcept
+                {
+                    return T{};
+                }
+
+                static constexpr bool is_iec559  = false;
+                static constexpr bool is_bounded = false;
+                static constexpr bool is_modulo  = false;
+
+                static constexpr bool traps           = false;
+                static constexpr bool tinyness_before = false;
+
+                static constexpr float_round_style round_style = round_toward_zero;
+        };
+    }
+
+    template<class T>
+    class numeric_limits: public aux::numeric_limits<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    class numeric_limits<const T>: public numeric_limits<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    class numeric_limits<volatile T>: public numeric_limits<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    class numeric_limits<const volatile T>: public numeric_limits<T>
+    { /* DUMMY BODY */ };
+
+    /**
+     * 18.3.2.3, class template numeric_limits:
+     */
+
+    template<>
+    class numeric_limits<float>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr float min() noexcept
+            {
+                return 1.17549435e-38f;
+            }
+
+            static constexpr float max() noexcept
+            {
+                return 3.40282347e+38f;
+            }
+
+            static constexpr float lowest() noexcept
+            {
+                return -3.40282347e+38f;
+            }
+
+            static constexpr int digits       = 24;
+            static constexpr int digits10     =  6;
+            static constexpr int max_digits10 =  9;
+
+            static constexpr bool is_signed  = true;
+            static constexpr bool is_integer = false;
+            static constexpr bool is_exact   = false;
+
+            static constexpr int radix = 2;
+
+            static constexpr float epsilon() noexcept
+            {
+                return 1.19209290e-07f;
+            }
+
+            static constexpr float round_error() noexcept
+            {
+                return 0.5f;
+            }
+
+            static constexpr int min_exponent   = -127;
+            static constexpr int min_exponent10 =  -37;
+            static constexpr int max_exponent   =  128;
+            static constexpr int max_exponent10 =   38;
+
+            static constexpr bool has_infinity      = true;
+            static constexpr bool has_quiet_NaN     = true;
+            static constexpr bool has_signaling_NaN = true;
+
+            static constexpr float_denorm_style has_denorm = denorm_absent;
+            static constexpr bool has_denorm_loss          = false;
+
+            static constexpr float infinity() noexcept
+            {
+                // TODO: implement
+                return 0.f;
+            }
+
+            static constexpr float quiet_NaN() noexcept
+            {
+                // TODO: implement
+                return 0.f;
+            }
+
+            static constexpr float signaling_NaN() noexcept
+            {
+                // TODO: implement
+                return 0.f;
+            }
+
+            static constexpr float denorm_min() noexcept
+            {
+                return min();
+            }
+
+            static constexpr bool is_iec559  = true;
+            static constexpr bool is_bounded = true;
+            static constexpr bool is_modulo  = false;
+
+            static constexpr bool traps           = true;
+            static constexpr bool tinyness_before = true;
+
+            static constexpr float_round_style round_style = round_to_nearest;
+    };
+
+    template<>
+    class numeric_limits<bool>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr bool min() noexcept
+            {
+                return false;
+            }
+
+            static constexpr bool max() noexcept
+            {
+                return true;
+            }
+
+            static constexpr bool lowest() noexcept
+            {
+                return false;
+            }
+
+            static constexpr int digits       = 1;
+            static constexpr int digits10     = 0;
+            static constexpr int max_digits10 = 0;
+
+            static constexpr bool is_signed  = false;
+            static constexpr bool is_integer = true;
+            static constexpr bool is_exact   = true;
+
+            static constexpr int radix = 2;
+
+            static constexpr bool epsilon() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr bool round_error() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr int min_exponent   = 0;
+            static constexpr int min_exponent10 = 0;
+            static constexpr int max_exponent   = 0;
+            static constexpr int max_exponent10 = 0;
+
+            static constexpr bool has_infinity      = false;
+            static constexpr bool has_quiet_NaN     = false;
+            static constexpr bool has_signaling_NaN = false;
+
+            static constexpr float_denorm_style has_denorm = denorm_absent;
+            static constexpr bool has_denorm_loss          = false;
+
+            static constexpr bool infinity() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr bool quiet_NaN() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr bool signaling_NaN() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr bool denorm_min() noexcept
+            {
+                return 0;
+            }
+
+            static constexpr bool is_iec559  = false;
+            static constexpr bool is_bounded = true;
+            static constexpr bool is_modulo  = false;
+
+            static constexpr bool traps           = false;
+            static constexpr bool tinyness_before = false;
+
+            static constexpr float_round_style round_style = round_toward_zero;
+    };
+
+    /**
+     * Note: Because of the limited state of limit.h, we define only
+     *       the most basic properties of the most basic types (that are likely
+     *       to be used in a program that is being ported to HelenOS).
+     */
+
+    template<>
+    class numeric_limits<char>: public aux::numeric_limits<char>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(char) * 8;
+
+            static constexpr char max()
+            {
+                return CHAR_MAX;
+            }
+
+            static constexpr char min()
+            {
+                return CHAR_MIN;
+            }
+
+            static constexpr char lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<signed char>: public aux::numeric_limits<signed char>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(signed char) * 8 - 1;
+
+            static constexpr signed char max()
+            {
+                return SCHAR_MAX;
+            }
+
+            static constexpr signed char min()
+            {
+                return SCHAR_MIN;
+            }
+
+            static constexpr signed char lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<short>: public aux::numeric_limits<short>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(short) * 8 - 1;
+
+            static constexpr short max()
+            {
+                return SHRT_MAX;
+            }
+
+            static constexpr short min()
+            {
+                return SHRT_MIN;
+            }
+
+            static constexpr short lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<int>: public aux::numeric_limits<int>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(int) * 8 - 1;
+
+            static constexpr int max()
+            {
+                return INT_MAX;
+            }
+
+            static constexpr int min()
+            {
+                return INT_MIN;
+            }
+
+            static constexpr int lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<long>: public aux::numeric_limits<long>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(long) * 8 - 1;
+
+            static constexpr long max()
+            {
+                return LONG_MAX;
+            }
+
+            static constexpr long min()
+            {
+                return LONG_MIN;
+            }
+
+            static constexpr long lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<long long>: public aux::numeric_limits<long long>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(long long) * 8 - 1;
+
+            static constexpr long long max()
+            {
+                return LLONG_MAX;
+            }
+
+            static constexpr long long min()
+            {
+                return LLONG_MIN;
+            }
+
+            static constexpr long long lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<unsigned char>: public aux::numeric_limits<unsigned char>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(unsigned char) * 8;
+
+            static constexpr unsigned char max()
+            {
+                return SCHAR_MAX;
+            }
+
+            static constexpr unsigned char min()
+            {
+                return SCHAR_MIN;
+            }
+
+            static constexpr unsigned char lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<unsigned short>: public aux::numeric_limits<unsigned short>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(unsigned short) * 8;
+
+            static constexpr unsigned short max()
+            {
+                return USHRT_MAX;
+            }
+
+            static constexpr unsigned short min()
+            {
+                return USHRT_MIN;
+            }
+
+            static constexpr unsigned short lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<unsigned int>: public aux::numeric_limits<unsigned int>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(unsigned int) * 8;
+
+            static constexpr unsigned int max()
+            {
+                return UINT_MAX;
+            }
+
+            static constexpr unsigned int min()
+            {
+                return UINT_MIN;
+            }
+
+            static constexpr unsigned int lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<unsigned long>: public aux::numeric_limits<unsigned long>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(unsigned long) * 8;
+
+            static constexpr unsigned long max()
+            {
+                return ULONG_MAX;
+            }
+
+            static constexpr unsigned long min()
+            {
+                return ULONG_MIN;
+            }
+
+            static constexpr unsigned long lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<unsigned long long>: public aux::numeric_limits<unsigned long long>
+    {
+        public:
+            static constexpr bool is_specialized = true;
+
+            static constexpr int digits = sizeof(unsigned long long) * 8;
+
+            static constexpr unsigned long long max()
+            {
+                return ULLONG_MAX;
+            }
+
+            static constexpr unsigned long long min()
+            {
+                return ULLONG_MIN;
+            }
+
+            static constexpr unsigned long long lowest()
+            {
+                return min();
+            }
+    };
+
+    template<>
+    class numeric_limits<double>: public aux::numeric_limits<double>
+    {
+        public:
+        // TODO: implement
+            static constexpr int digits = sizeof(short) * 8 - 1;
+    };
+
+    template<>
+    class numeric_limits<long double>: public aux::numeric_limits<long double>
+    {
+        public:
+        // TODO: implement
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/list_node.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/list_node.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,90 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_LIST_NODE
-#define LIBCPP_BITS_LIST_NODE
-
-namespace std::aux
-{
-    template<class T>
-    struct list_node
-    {
-        T value;
-        list_node* next;
-        list_node* prev;
-
-        template<class... Args>
-        list_node(Args&&... args)
-            : value{forward<Args>(args)...},
-              next{}, prev{}
-        {
-            next = this;
-            prev = this;
-        }
-
-        list_node(const T& val)
-            : value{val}, next{}, prev{}
-        {
-            next = this;
-            prev = this;
-        }
-
-        list_node(T&& val)
-            : value{forward<T>(val)}, next{}, prev{}
-        {
-            next = this;
-            prev = this;
-        }
-
-        void append(list_node* node)
-        {
-            node->next = next;
-            node->prev = this;
-            next->prev = node;
-            next = node;
-        }
-
-        void prepend(list_node* node)
-        {
-            node->next = this;
-            node->prev = prev;
-            prev->next = node;
-            prev = node;
-        }
-
-        void unlink()
-        {
-            prev->next = next;
-            next->prev = prev;
-            next = this;
-            prev = this;
-        }
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/locale.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,173 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_LOCALE
-#define LIBCPP_BITS_LOCALE
-
-#include <impl/string.hpp>
-
-namespace std
-{
-    class locale;
-
-    /**
-     * 22.3.1, class locale:
-     */
-
-    class locale
-    {
-        public:
-            class facet
-            {
-                protected:
-                    explicit facet(size_t refs = 0);
-
-                    virtual ~facet();
-
-                    facet(const facet&) = delete;
-                    void operator=(const facet&) = delete;
-            };
-
-            class id
-            {
-                public:
-                    id() = default;
-
-                    id(const id&) = delete;
-                    void operator=(const id&) = delete;
-            };
-
-            using category = int;
-
-            static const category none     = 0b000'0001;
-            static const category collate  = 0b000'0010;
-            static const category ctype    = 0b000'0100;
-            static const category monetary = 0b000'1000;
-            static const category numeric  = 0b001'0000;
-            static const category time     = 0b010'0000;
-            static const category messages = 0b100'0000;
-            static const category all      = collate | ctype | monetary |
-                                             numeric | time | messages;
-
-            locale() noexcept;
-
-            locale(const locale& other) noexcept;
-
-            explicit locale(const char* name);
-
-            explicit locale(const string& name);
-
-            locale(const locale& other, const char* name, category);
-
-            locale(const locale& other, const string& name, category);
-
-            template<class Facet>
-            locale(const locale& other, Facet* f)
-                : name_{other.name_}
-            { /* DUMMY BODY */ }
-
-            locale(const locale& other, const locale& one, category);
-
-            ~locale() = default;
-
-            const locale& operator=(const locale& other) noexcept;
-
-            template<class Facet>
-            locale combine(const locale& other) const
-            {
-                return other;
-            }
-
-            string name() const;
-
-            bool operator==(const locale& other) const;
-            bool operator!=(const locale& other) const;
-
-            template<class Char, class Traits, class Allocator>
-            bool operator()(const basic_string<Char, Traits, Allocator>& s1,
-                            const basic_string<Char, Traits, Allocator>& s2) const
-            {
-                // TODO: define outside locale
-                /* return use_facet<collate<Char>>(*this).compare( */
-                /*     s1.begin(), s1.end(), s2.begin(), s2.end() */
-                /* ) < 0; */
-                return false;
-            }
-
-            static locale global(const locale&)
-            {
-                return *the_locale_;
-            }
-
-            static const locale& classic()
-            {
-                return *the_locale_;
-            }
-
-        private:
-            string name_;
-
-            // TODO: implement the_locale_
-            static constexpr locale* the_locale_{nullptr};
-
-            template<class Facet>
-            friend bool has_facet(const locale&);
-
-            template<class Facet>
-            bool has_()
-            { // Our single locale atm has all facets.
-                return true;
-            }
-
-            template<class Facet>
-            /* friend const Facet& use_facet(const locale&); */
-            friend Facet use_facet(const locale&);
-
-            template<class Facet>
-            /* const Facet& get_() const */
-            Facet get_() const
-            {
-                return Facet{0U};
-            }
-    };
-
-    template<class Facet>
-    /* const Facet& use_facet(const locale& loc) */
-    Facet use_facet(const locale& loc)
-    {
-        return loc.get_<Facet>();
-    }
-
-    template<class Facet>
-    bool has_facet(const locale& loc)
-    {
-        return loc.has_<Facet>();
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/locale/codecvt.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/codecvt.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/locale/codecvt.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,5 +30,5 @@
 #define LIBCPP_BITS_LOCALE_CODECVT
 
-#include <intetnal/locale.hpp>
+#include <__bits/locale/locale.hpp>
 #include <string>
 
Index: uspace/lib/cpp/include/__bits/locale/ctype.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/ctype.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/locale/ctype.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,7 +30,7 @@
 #define LIBCPP_BITS_LOCALE_CTYPE
 
+#include <__bits/locale/locale.hpp>
+#include <__bits/string/string.hpp>
 #include <cctype>
-#include <__bits/locale.hpp>
-#include <impl/string.hpp>
 
 namespace std
Index: uspace/lib/cpp/include/__bits/locale/locale.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/locale.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/locale/locale.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_LOCALE
+#define LIBCPP_BITS_LOCALE
+
+#include <__bits/string/string.hpp>
+
+namespace std
+{
+    class locale;
+
+    /**
+     * 22.3.1, class locale:
+     */
+
+    class locale
+    {
+        public:
+            class facet
+            {
+                protected:
+                    explicit facet(size_t refs = 0);
+
+                    virtual ~facet();
+
+                    facet(const facet&) = delete;
+                    void operator=(const facet&) = delete;
+            };
+
+            class id
+            {
+                public:
+                    id() = default;
+
+                    id(const id&) = delete;
+                    void operator=(const id&) = delete;
+            };
+
+            using category = int;
+
+            static const category none     = 0b000'0001;
+            static const category collate  = 0b000'0010;
+            static const category ctype    = 0b000'0100;
+            static const category monetary = 0b000'1000;
+            static const category numeric  = 0b001'0000;
+            static const category time     = 0b010'0000;
+            static const category messages = 0b100'0000;
+            static const category all      = collate | ctype | monetary |
+                                             numeric | time | messages;
+
+            locale() noexcept;
+
+            locale(const locale& other) noexcept;
+
+            explicit locale(const char* name);
+
+            explicit locale(const string& name);
+
+            locale(const locale& other, const char* name, category);
+
+            locale(const locale& other, const string& name, category);
+
+            template<class Facet>
+            locale(const locale& other, Facet* f)
+                : name_{other.name_}
+            { /* DUMMY BODY */ }
+
+            locale(const locale& other, const locale& one, category);
+
+            ~locale() = default;
+
+            const locale& operator=(const locale& other) noexcept;
+
+            template<class Facet>
+            locale combine(const locale& other) const
+            {
+                return other;
+            }
+
+            string name() const;
+
+            bool operator==(const locale& other) const;
+            bool operator!=(const locale& other) const;
+
+            template<class Char, class Traits, class Allocator>
+            bool operator()(const basic_string<Char, Traits, Allocator>& s1,
+                            const basic_string<Char, Traits, Allocator>& s2) const
+            {
+                // TODO: define outside locale
+                /* return use_facet<collate<Char>>(*this).compare( */
+                /*     s1.begin(), s1.end(), s2.begin(), s2.end() */
+                /* ) < 0; */
+                return false;
+            }
+
+            static locale global(const locale&)
+            {
+                return *the_locale_;
+            }
+
+            static const locale& classic()
+            {
+                return *the_locale_;
+            }
+
+        private:
+            string name_;
+
+            // TODO: implement the_locale_
+            static constexpr locale* the_locale_{nullptr};
+
+            template<class Facet>
+            friend bool has_facet(const locale&);
+
+            template<class Facet>
+            bool has_()
+            { // Our single locale atm has all facets.
+                return true;
+            }
+
+            template<class Facet>
+            /* friend const Facet& use_facet(const locale&); */
+            friend Facet use_facet(const locale&);
+
+            template<class Facet>
+            /* const Facet& get_() const */
+            Facet get_() const
+            {
+                return Facet{0U};
+            }
+    };
+
+    template<class Facet>
+    /* const Facet& use_facet(const locale& loc) */
+    Facet use_facet(const locale& loc)
+    {
+        return loc.get_<Facet>();
+    }
+
+    template<class Facet>
+    bool has_facet(const locale& loc)
+    {
+        return loc.has_<Facet>();
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/locale/locale_misc.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/locale_misc.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/locale/locale_misc.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_LOCALE_MISC
+#define LIBCPP_BITS_LOCALE_MISC
+
+#include <__bits/locale/locale.hpp>
+#include <__bits/locale/ctype.hpp>
+#include <__bits/locale/num_get.hpp>
+#include <__bits/locale/num_put.hpp>
+#include <__bits/locale/numpunct.hpp>
+#include <cstdlib>
+#include <ios>
+#include <iosfwd>
+#include <string>
+
+namespace std
+{
+    /**
+     * Note: This is a very simplistic implementation of <locale>.
+     *       We have a single locale that has all of its facets.
+     *       This should behave correctly on the outside but will prevent
+     *       us from using multiple locales so if that becomes necessary
+     *       in the future, TODO: implement :)
+     */
+
+    /**
+     * 22.3.3, convenience interfaces:
+     */
+
+    /**
+     * 22.3.3.1, character classification:
+     */
+
+    template<class Char>
+    bool isspace(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::space, c);
+    }
+
+    template<class Char>
+    bool isprint(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::print, c);
+    }
+
+    template<class Char>
+    bool iscntrl(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::cntrl, c);
+    }
+
+    template<class Char>
+    bool isupper(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::upper, c);
+    }
+
+    template<class Char>
+    bool islower(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::lower, c);
+    }
+
+    template<class Char>
+    bool isalpha(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::alpha, c);
+    }
+
+    template<class Char>
+    bool isdigit(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::digit, c);
+    }
+
+    template<class Char>
+    bool ispunct(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::punct, c);
+    }
+
+    template<class Char>
+    bool isxdigit(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::xdigit, c);
+    }
+
+    template<class Char>
+    bool isalnum(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::alnum, c);
+    }
+
+    template<class Char>
+    bool isgraph(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::graph, c);
+    }
+
+    template<class Char>
+    bool isblank(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).is(ctype_base::blank, c);
+    }
+
+    /**
+     * 22.3.3.2, conversions:
+     */
+
+    /**
+     * 22.3.3.2.1, character conversions:
+     */
+
+    template<class Char>
+    Char toupper(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).toupper(c);
+    }
+
+    template<class Char>
+    Char tolower(Char c, const locale& loc)
+    {
+        return use_facet<ctype<Char>>(loc).tolower(c);
+    }
+
+    /**
+     * 22.3.3.2.2, string conversions:
+     */
+
+    // TODO: implement
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/locale/num_get.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,8 +30,8 @@
 #define LIBCPP_BITS_LOCALE_NUM_GET
 
+#include <__bits/locale/locale.hpp>
+#include <__bits/locale/numpunct.hpp>
 #include <cerrno>
 #include <cstring>
-#include <__bits/locale.hpp>
-#include <__bits/locale/numpunct.hpp>
 #include <ios>
 #include <iterator>
Index: uspace/lib/cpp/include/__bits/locale/num_put.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/num_put.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/locale/num_put.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,5 +30,5 @@
 #define LIBCPP_BITS_LOCALE_NUM_PUT
 
-#include <__bits/locale.hpp>
+#include <__bits/locale/locale.hpp>
 #include <__bits/locale/numpunct.hpp>
 #include <ios>
Index: uspace/lib/cpp/include/__bits/locale/numpunct.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/numpunct.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/locale/numpunct.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,5 +30,5 @@
 #define LIBCPP_BITS_LOCALE_NUMPUNCT
 
-#include <__bits/locale.hpp>
+#include <__bits/locale/locale.hpp>
 #include <string>
 
Index: uspace/lib/cpp/include/__bits/memory/allocator_traits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/memory/allocator_traits.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/memory/allocator_traits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -30,9 +30,9 @@
 #define LIBCPP_BITS_MEMORY_ALLOCATOR_TRAITS
 
-#include <cstddef>
 #include <__bits/aux.hpp>
 #include <__bits/memory/addressof.hpp>
 #include <__bits/memory/pointer_traits.hpp>
 #include <__bits/memory/type_getters.hpp>
+#include <cstddef>
 #include <limits>
 #include <type_traits>
Index: uspace/lib/cpp/include/__bits/memory/pointer_traits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/memory/pointer_traits.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/memory/pointer_traits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -30,7 +30,7 @@
 #define LIBCPP_BITS_MEMORY_POINTER_TRAITS
 
-#include <cstddef>
 #include <__bits/memory/addressof.hpp>
 #include <__bits/memory/type_getters.hpp>
+#include <cstddef>
 #include <type_traits>
 
Index: uspace/lib/cpp/include/__bits/memory/shared_ptr.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/memory/shared_ptr.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/memory/shared_ptr.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -30,5 +30,4 @@
 #define LIBCPP_BITS_MEMORY_SHARED_PTR
 
-#include <exception>
 #include <__bits/functional/arithmetic_operations.hpp>
 #include <__bits/functional/hash.hpp>
@@ -37,4 +36,5 @@
 #include <__bits/memory/unique_ptr.hpp>
 #include <__bits/trycatch.hpp>
+#include <exception>
 #include <type_traits>
 
Index: uspace/lib/cpp/include/__bits/memory/type_getters.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/memory/type_getters.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/memory/type_getters.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -39,6 +39,6 @@
  */
 
+#include <__bits/aux.hpp>
 #include <cstddef>
-#include <__bits/aux.hpp>
 #include <type_traits>
 
Index: uspace/lib/cpp/include/__bits/new.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/new.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/new.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_NEW
+#define LIBCPP_BITS_NEW
+
+#include <exception>
+
+namespace std
+{
+
+class bad_alloc: public std::exception
+{
+	public:
+		bad_alloc() = default;
+		bad_alloc(const bad_alloc&) = default;
+		bad_alloc& operator=(const bad_alloc&) = default;
+		virtual const char* what() const noexcept override;
+		virtual ~bad_alloc() = default;
+};
+
+struct nothrow_t {};
+extern const nothrow_t nothrow;
+
+using new_handler = void (*)();
+
+new_handler set_new_handler(new_handler);
+new_handler get_new_handler() noexcept;
+
+}
+
+void* operator new(std::size_t);
+void* operator new(std::size_t, void*);
+void* operator new(std::size_t, const std::nothrow_t&) noexcept;
+void* operator new[](std::size_t);
+void* operator new[](std::size_t, const std::nothrow_t&) noexcept;
+
+void operator delete(void*) noexcept;
+void operator delete(void*, std::size_t) noexcept;
+void operator delete[](void*) noexcept;
+void operator delete[](void*, std::size_t) noexcept;
+
+#endif
+
Index: uspace/lib/cpp/include/__bits/numeric.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/numeric.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/numeric.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_NUMERIC
+#define LIBCPP_BITS_NUMERIC
+
+#include <utility>
+
+namespace std
+{
+
+    /**
+     * 26.7.2, accumulate:
+     */
+
+    template<class InputIterator, class T>
+    T accumulate(InputIterator first, InputIterator last, T init)
+    {
+        auto acc{init};
+        while (first != last)
+            acc += *first++;
+
+        return acc;
+    }
+
+    template<class InputIterator, class T, class BinaryOperation>
+    T accumulate(InputIterator first, InputIterator last, T init,
+                 BinaryOperation op)
+    {
+        auto acc{init};
+        while (first != last)
+            acc = op(acc, *first++);
+
+        return acc;
+    }
+
+    /**
+     * 26.7.3, inner product:
+     */
+
+    template<class InputIterator1, class InputIterator2, class T>
+    T inner_product(InputIterator1 first1, InputIterator1 last1,
+                    InputIterator2 first2, T init)
+    {
+        auto res{init};
+        while (first1 != last1)
+            res += (*first1++) * (*first2++);
+
+        return res;
+    }
+
+    template<class InputIterator1, class InputIterator2, class T,
+             class BinaryOperation1, class BinaryOperation2>
+    T inner_product(InputIterator1 first1, InputIterator1 last1,
+                    InputIterator2 first2, T init,
+                    BinaryOperation1 op1, BinaryOperation2 op2)
+    {
+        auto res{init};
+        while (first1 != last1)
+            res = op1(res, op2(*first1++, *first2++));
+
+        return res;
+    }
+
+    /**
+     * 26.7.4, partial sum:
+     */
+
+    template<class InputIterator, class OutputIterator>
+    OutputIterator partial_sum(InputIterator first, InputIterator last,
+                               OutputIterator result)
+    {
+        if (first == last)
+            return result;
+
+        auto acc{*first++};
+        *result++ = acc;
+
+        while (first != last)
+            *result++ = acc = acc + *first++;
+
+        return result;
+    }
+
+    template<class InputIterator, class OutputIterator, class BinaryOperation>
+    OutputIterator partial_sum(InputIterator first, InputIterator last,
+                               OutputIterator result, BinaryOperation op)
+    {
+        if (first == last)
+            return result;
+
+        auto acc{*first++};
+        *result++ = acc;
+
+        while (first != last)
+            *result++ = acc = op(acc, *first++);
+
+        return result;
+    }
+
+    /**
+     * 26.7.5, adjacent difference:
+     */
+
+    template<class InputIterator, class OutputIterator>
+    OutputIterator adjacent_difference(InputIterator first, InputIterator last,
+                                       OutputIterator result)
+    {
+        if (first == last)
+            return result;
+
+        auto acc{*first++};
+        *result++ = acc;
+
+        while (first != last)
+        {
+            auto val = *first++;
+            *result++ = val - acc;
+            acc = move(val);
+        }
+
+        return result;
+    }
+
+    template<class InputIterator, class OutputIterator, class BinaryOperation>
+    OutputIterator adjacent_difference(InputIterator first, InputIterator last,
+                                       OutputIterator result, BinaryOperation op)
+    {
+        if (first == last)
+            return result;
+
+        auto acc{*first++};
+        *result++ = acc;
+
+        while (first != last)
+        {
+            auto val = *first++;
+            *result++ = op(val, acc);
+            acc = move(val);
+        }
+
+        return result;
+    }
+
+    /**
+     * 26.7.6, iota:
+     */
+
+    template<class ForwardIterator, class T>
+    void iota(ForwardIterator first, ForwardIterator last, T value)
+    {
+        while (first != last)
+            *first++ = value++;
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/random.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/random.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/random.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1583 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_RANDOM
+#define LIBCPP_BITS_RANDOM
+
+#include <__bits/builtins.hpp>
+#include <cstdint>
+#include <cstdlib>
+#include <ctime>
+#include <initializer_list>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+/**
+ * Note: Variables with one or two lettered
+ *       names here are named after their counterparts in
+ *       the standard. If one needs to understand their meaning,
+ *       they should seek the mentioned standard section near
+ *       the declaration of these variables.
+ * Note: There will be a lot of mathematical expressions in this header.
+ *       All of these are taken directly from the standard's requirements
+ *       and as such won't be commented here, check the appropriate
+ *       sections if you need explanation of these forumulae.
+ */
+
+namespace std
+{
+    namespace aux
+    {
+        /**
+         * This is the minimum requirement imposed by the
+         * standard for a type to qualify as a seed sequence
+         * in overloading resolutions.
+         * (This is because the engines have constructors
+         * that accept sequence and seed and without this
+         * minimal requirements overload resolution would fail.)
+         */
+        template<class Sequence, class ResultType>
+        struct is_seed_sequence
+            : aux::value_is<
+            bool, !is_convertible_v<Sequence, ResultType>
+        >
+        { /* DUMMY BODY */ };
+
+        template<class T, class Engine>
+        inline constexpr bool is_seed_sequence_v = is_seed_sequence<T, Engine>::value;
+    }
+
+    /**
+     * 26.5.3.1, class template linear_congruential_engine:
+     */
+
+    template<class UIntType, UIntType a, UIntType c, UIntType m>
+    class linear_congruential_engine
+    {
+        static_assert(m == 0 || (a < m && c < m));
+
+        public:
+            using result_type = UIntType;
+
+            static constexpr result_type multiplier = a;
+            static constexpr result_type increment = c;
+            static constexpr result_type modulus = m;
+
+            static constexpr result_type min()
+            {
+                return c == 0U ? 1U : 0U;
+            }
+
+            static constexpr result_type max()
+            {
+                return m - 1U;
+            }
+
+            static constexpr result_type default_seed = 1U;
+
+            explicit linear_congruential_engine(result_type s = default_seed)
+                : state_{}
+            {
+                seed(s);
+            }
+
+            linear_congruential_engine(const linear_congruential_engine& other)
+                : state_{other.state_}
+            { /* DUMMY BODY */ }
+
+            template<class Seq>
+            explicit linear_congruential_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : state_{}
+            {
+                seed(q);
+            }
+
+            void seed(result_type s = default_seed)
+            {
+                if (c % modulus_ == 0 && s % modulus_ == 0)
+                    state_ = 1;
+                else
+                    state_ = s % modulus_;
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                auto k = static_cast<size_t>(aux::ceil(aux::log2(modulus_) / 32));
+                auto arr = new result_type[k + 3];
+
+                q.generate(arr, arr + k + 3);
+
+                result_type s{};
+                for (size_t j = 0; j < k; ++j)
+                    s += arr[j + 3] * aux::pow2(32U * j);
+                s = s % modulus_;
+
+                if (c % modulus_ == 0 && s == 0)
+                    state_ = 1;
+                else
+                    state_ = s % modulus_;
+                delete[] arr;
+            }
+
+            result_type operator()()
+            {
+                return generate_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    transition_();
+            }
+
+            bool operator==(const linear_congruential_engine& rhs) const
+            {
+                return state_ = rhs.state_;
+            }
+
+            bool operator!=(const linear_congruential_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                os << state_;
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                result_type tmp{};
+                if (is >> tmp)
+                    state_ = tmp;
+                else
+                    is.setstate(ios::failbit);
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            result_type state_;
+
+            static constexpr result_type modulus_ =
+                (m == 0) ? (numeric_limits<result_type>::max() + 1) : m;
+
+            void transition_()
+            {
+                state_ = (a * state_ + c) % modulus_;
+            }
+
+            result_type generate_()
+            {
+                transition_();
+
+                return state_;
+            }
+    };
+
+    /**
+     * 26.5.3.2, class template mersenne_twister_engine:
+     */
+
+    template<
+        class UIntType, size_t w, size_t n, size_t m, size_t r,
+        UIntType a, size_t u, UIntType d, size_t s,
+        UIntType b, size_t t, UIntType c, size_t l, UIntType f
+    >
+    class mersenne_twister_engine
+    {
+        // TODO: fix these
+        /* static_assert(0 < m && m <= n); */
+        /* static_assert(2 * u < w); */
+        /* static_assert(r <= w && u <= w && s <= w && t <= w && l <= w); */
+        /* /1* static_assert(w <= numeric_limits<UIntType>::digits); *1/ */
+        /* static_assert(a <= (1U << w) - 1U); */
+        /* static_assert(b <= (1U << w) - 1U); */
+        /* static_assert(c <= (1U << w) - 1U); */
+        /* static_assert(d <= (1U << w) - 1U); */
+        /* static_assert(f <= (1U << w) - 1U); */
+
+        public:
+            using result_type = UIntType;
+
+            static constexpr size_t word_size = w;
+            static constexpr size_t state_size = n;
+            static constexpr size_t shift_size = m;
+            static constexpr size_t mask_bits = r;
+            static constexpr UIntType xor_mask = a;
+
+            static constexpr size_t tempering_u = u;
+            static constexpr UIntType tempering_d = d;
+            static constexpr size_t tempering_s = s;
+            static constexpr UIntType tempering_b = b;
+            static constexpr size_t tempering_t = t;
+            static constexpr UIntType tempering_c = c;
+            static constexpr size_t tempering_l = l;
+
+            static constexpr UIntType initialization_multiplier = f;
+
+            static constexpr result_type min()
+            {
+                return result_type{};
+            }
+
+            static constexpr result_type max()
+            {
+                return static_cast<result_type>(aux::pow2(w)) - 1U;
+            }
+
+            static constexpr result_type default_seed = 5489U;
+
+            explicit mersenne_twister_engine(result_type value = default_seed)
+                : state_{}, i_{}
+            {
+                seed(value);
+            }
+
+            template<class Seq>
+            explicit mersenne_twister_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : state_{}, i_{}
+            {
+                seed(q);
+            }
+
+            void seed(result_type value = default_seed)
+            {
+                state_[idx_(-n)] = value % aux::pow2u(w);;
+
+                for (long long i = 1 - n; i <= -1; ++i)
+                {
+                    state_[idx_(i)] = (f * (state_[idx_(i - 1)] ^
+                                      (state_[idx_(i - 1)] >> (w - 2))) + 1 % n) % aux::pow2u(w);
+                }
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                auto k = static_cast<size_t>(w / 32);
+                auto arr = new result_type[n * k];
+                q.generate(arr, arr + n * k);
+
+                for (long long i = -n; i <= -1; ++i)
+                {
+                    state_[idx_(i)] = result_type{};
+                    for (long long j = 0; j < k; ++j)
+                        state_[idx_(i)] += arr[k * (i + n) + j] * aux::pow2(32 * j);
+                    state_[idx_(i)] %= aux::pow2(w);
+                }
+
+                delete[] arr;
+            }
+
+            result_type operator()()
+            {
+                return generate_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    transition_();
+            }
+
+            bool operator==(const mersenne_twister_engine& rhs) const
+            {
+                if (i_ != rhs.i_)
+                    return false;
+
+                for (size_t i = 0; i < n; ++i)
+                {
+                    if (state_[i] != rhs.state_[i])
+                        return false;
+                }
+
+                return true;
+            }
+
+            bool operator!=(const mersenne_twister_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                for (size_t j = n + 1; j > 1; --j)
+                {
+                    os << state_[idx_(i_ - j - 1)];
+
+                    if (j > 2)
+                        os << os.widen(' ');
+                }
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                for (size_t j = n + 1; j > 1; --j)
+                {
+                    if (!(is >> state_[idx_(i_ - j - 1)]))
+                    {
+                        is.setstate(ios::failbit);
+                        break;
+                    }
+                }
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            result_type state_[n];
+            size_t i_;
+
+            void transition_()
+            {
+                auto mask = (result_type{1} << r) - 1;
+                auto y = (state_[idx_(i_ - n)] & ~mask) | (state_[idx_(i_ + 1 - n)] & mask);
+                auto alpha = a * (y & 1);
+                state_[i_] = state_[idx_(i_ + m - n)] ^ (y >> 1) ^ alpha;
+
+                i_ = (i_ + 1) % n;
+            }
+
+            result_type generate_()
+            {
+                auto z1 = state_[i_] ^ ((state_[i_] >> u) & d);
+                auto z2 = z1 ^ (lshift_(z1, s) & b);
+                auto z3 = z2 ^ (lshift_(z2, t) & c);
+                auto z4 = z3 ^ (z3 >> l);
+
+                transition_();
+
+                return z4;
+            }
+
+            size_t idx_(size_t idx) const
+            {
+                return idx % n;
+            }
+
+            result_type lshift_(result_type val, size_t count)
+            {
+                return (val << count) % aux::pow2u(w);
+            }
+    };
+
+    /**
+     * 26.5.3.3, class template subtract_with_carry_engine:
+     */
+
+    template<class UIntType, size_t w, size_t s, size_t r>
+    class subtract_with_carry_engine
+    {
+        // TODO: fix these
+        /* static_assert(0U < s); */
+        /* static_assert(s < r); */
+        /* static_assert(0U < w); */
+        /* static_assert(w <= numeric_limits<UIntType>::digits); */
+
+        public:
+            using result_type = UIntType;
+
+            static constexpr size_t word_size = w;
+            static constexpr size_t short_lag = s;
+            static constexpr size_t long_lag = r;
+
+            static constexpr result_type min()
+            {
+                return result_type{};
+            }
+
+            static constexpr result_type max()
+            {
+                return m_ - 1;
+            }
+
+            static constexpr result_type default_seed = 19780503U;
+
+            explicit subtract_with_carry_engine(result_type value = default_seed)
+                : state_{}, i_{}, carry_{}
+            {
+                seed(value);
+            }
+
+            template<class Seq>
+            explicit subtract_with_carry_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : state_{}, i_{}, carry_{}
+            {
+                seed(q);
+            }
+
+            void seed(result_type value = default_seed)
+            {
+                linear_congruential_engine<
+                    result_type, 40014U, 0U, 2147483563U
+                > e{value == 0U ? default_seed : value};
+
+                auto n = aux::ceil(w / 32.0);
+                auto z = new result_type[n];
+
+                for (long long i = -r; i <= -1; ++i)
+                {
+                    for (size_t i = 0; i < n; ++i)
+                        z[i] = e() % aux::pow2u(32);
+
+                    state_[idx_(i)] = result_type{};
+                    for (size_t j = 0; j < n; ++j)
+                        state_[idx_(i)] += z[j] * aux::pow2u(32 * j);
+                    state_[idx_(i)] %= m_;
+                }
+
+                if (state_[idx_(-1)] == 0)
+                    carry_ = 1;
+                else
+                    carry_ = 0;
+
+                delete[] z;
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                auto k = aux::ceil(w / 32.0);
+                auto arr = new result_type[r * k];
+
+                q.generate(arr, arr + r * k);
+
+                for (long long i = -r; i <= -1; ++i)
+                {
+                    state_[idx_(i)] = result_type{};
+                    for (long long j = 0; j < k; ++j)
+                        state_[idx_(i)] += arr[k * (i + r) + j] * aux::pow2(32 * j);
+                    state_[idx_(i)] %= m_;
+                }
+
+                delete[] arr;
+
+                if (state_[idx_(-1)] == 0)
+                    carry_ = 1;
+                else
+                    carry_ = 0;
+            }
+
+            result_type operator()()
+            {
+                return generate_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    transition_();
+            }
+
+            bool operator==(const subtract_with_carry_engine& rhs) const
+            {
+                if (i_ != rhs.i_)
+                    return false;
+
+                for (size_t i = 0; i < r; ++i)
+                {
+                    if (state_[i] != rhs.state_[i])
+                        return false;
+                }
+
+                return true;
+            }
+
+            bool operator!=(const subtract_with_carry_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                for (size_t j = r + 1; j > 1; --j)
+                {
+                    os << state_[idx_(i_ - j - 1)];
+                    os << os.widen(' ');
+                }
+
+                os << carry_;
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                for (size_t j = r + 1; j > 1; --j)
+                {
+                    if (!(is >> state_[idx_(i_ - j - 1)]))
+                    {
+                        is.setstate(ios::failbit);
+                        break;
+                    }
+                }
+
+                if (!(is >> carry_))
+                    is.setstate(ios::failbit);
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            result_type state_[r];
+            size_t i_;
+            uint8_t carry_;
+
+            static constexpr result_type m_ = aux::pow2u(w);
+
+            auto transition_()
+            {
+                auto y = static_cast<int64_t>(state_[idx_(i_ - s)]) - state_[idx_(i_ - r)] - carry_;
+                state_[i_] = y % m_;
+
+                i_ = (i_ + 1) % r;
+
+                return static_cast<result_type>(y % m_);
+            }
+
+            result_type generate_()
+            {
+                return transition_();
+            }
+
+            size_t idx_(size_t idx) const
+            {
+                return idx % r;
+            }
+    };
+
+    /**
+     * 26.5.4.2, class template discard_block_engine:
+     */
+
+    template<class Engine, size_t p, size_t r>
+    class discard_block_engine
+    {
+        static_assert(0 < r);
+        static_assert(r <= p);
+
+        public:
+            using result_type = typename Engine::result_type;
+
+            static constexpr size_t block_size = p;
+            static constexpr size_t used_block = r;
+
+            static constexpr result_type min()
+            {
+                return Engine::min();
+            }
+
+            static constexpr result_type max()
+            {
+                return Engine::max();
+            }
+
+            discard_block_engine()
+                : engine_{}, n_{}
+            { /* DUMMY BODY */ }
+
+            explicit discard_block_engine(const Engine& e)
+                : engine_{e}, n_{}
+            { /* DUMMY BODY */ }
+
+            explicit discard_block_engine(Engine&& e)
+                : engine_{move(e)}, n_{}
+            { /* DUMMY BODY */ }
+
+            explicit discard_block_engine(result_type s)
+                : engine_{s}, n_{}
+            { /* DUMMY BODY */ }
+
+            template<class Seq>
+            explicit discard_block_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : engine_{q}, n_{}
+            { /* DUMMY BODY */ }
+
+            void seed()
+            {
+                engine_.seed();
+            }
+
+            void seed(result_type s)
+            {
+                engine_.seed(s);
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                engine_.seed(q);
+            }
+
+            result_type operator()()
+            {
+                if (n_ > static_cast<int>(r))
+                {
+                    auto count = p - r;
+                    for (size_t i = 0; i < count; ++i)
+                        engine_();
+                    n_ = 0;
+                }
+                ++n_;
+
+                return engine_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    operator()(); // We need to discard our (), not engine's.
+            }
+
+            const Engine& base() const noexcept
+            {
+                return engine_;
+            }
+
+            bool operator==(const discard_block_engine& rhs) const
+            {
+                return engine_ == rhs.engine_ && n_ == rhs.n_;
+            }
+
+            bool operator!=(const discard_block_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                os << n_ << os.widen(' ') << engine_;
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                if (!(is >> n_) || !(is >> engine_))
+                    is.setstate(ios::failbit);
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            Engine engine_;
+            int n_;
+    };
+
+    /**
+     * 26.5.4.3, class template independent_bits_engine:
+     */
+
+    template<class Engine, size_t w, class UIntType>
+    class independent_bits_engine
+    {
+        static_assert(0U < w);
+        /* static_assert(w <= numeric_limits<result_type>::digits); */
+
+        public:
+            using result_type = UIntType;
+
+            static constexpr result_type min()
+            {
+                return result_type{};
+            }
+
+            static constexpr result_type max()
+            {
+                return aux::pow2u(w) - 1;
+            }
+
+            independent_bits_engine()
+                : engine_{}
+            { /* DUMMY BODY */ }
+
+            explicit independent_bits_engine(const Engine& e)
+                : engine_{e}
+            { /* DUMMY BODY */ }
+
+            explicit independent_bits_engine(Engine&& e)
+                : engine_{move(e)}
+            { /* DUMMY BODY */ }
+
+            explicit independent_bits_engine(result_type s)
+                : engine_{s}
+            { /* DUMMY BODY */ }
+
+            template<class Seq>
+            explicit independent_bits_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : engine_{q}
+            { /* DUMMY BODY */ }
+
+            void seed()
+            {
+                engine_.seed();
+            }
+
+            void seed(result_type s)
+            {
+                engine_.seed(s);
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                engine_.seed(q);
+            }
+
+            result_type operator()()
+            {
+                /* auto r = engine_.max() - engine_.min() + 1; */
+                /* auto m = aux::floor(aux::log2(r)); */
+                // TODO:
+
+                return engine_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    operator()();
+            }
+
+            const Engine& base() const noexcept
+            {
+                return engine_;
+            }
+
+            bool operator==(const independent_bits_engine& rhs) const
+            {
+                return engine_ == rhs.engine_;
+            }
+
+            bool operator!=(const independent_bits_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                return os << engine_;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                return is >> engine_;
+            }
+
+        private:
+            Engine engine_;
+    };
+
+    /**
+     * 26.5.4.4, class template shiffle_order_engine:
+     */
+
+    template<class Engine, size_t k>
+    class shuffle_order_engine
+    {
+        static_assert(0U < k);
+
+        public:
+            using result_type = typename Engine::result_type;
+
+            static constexpr size_t table_size = k;
+
+            static constexpr result_type min()
+            {
+                return Engine::min();
+            }
+
+            static constexpr result_type max()
+            {
+                return Engine::max();
+            }
+
+            shuffle_order_engine()
+                : engine_{}
+            { /* DUMMY BODY */ }
+
+            explicit shuffle_order_engine(const Engine& e)
+                : engine_{e}
+            { /* DUMMY BODY */ }
+
+            explicit shuffle_order_engine(Engine&& e)
+                : engine_{move(e)}
+            { /* DUMMY BODY */ }
+
+            explicit shuffle_order_engine(result_type s)
+                : engine_{s}
+            { /* DUMMY BODY */ }
+
+            template<class Seq>
+            explicit shuffle_order_engine(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+                : engine_{q}
+            { /* DUMMY BODY */ }
+
+            void seed()
+            {
+                engine_.seed();
+            }
+
+            void seed(result_type s)
+            {
+                engine_.seed(s);
+            }
+
+            template<class Seq>
+            void seed(
+                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
+            )
+            {
+                engine_.seed(q);
+            }
+
+            result_type operator()()
+            {
+                // TODO:
+
+                return engine_();
+            }
+
+            void discard(unsigned long long z)
+            {
+                for (unsigned long long i = 0ULL; i < z; ++i)
+                    operator()();
+            }
+
+            const Engine& base() const noexcept
+            {
+                return engine_;
+            }
+
+            bool operator==(const shuffle_order_engine& rhs) const
+            {
+                return engine_ == rhs.engine_;
+            }
+
+            bool operator!=(const shuffle_order_engine& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                return os << engine_;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                return is >> engine_;
+            }
+
+        private:
+            Engine engine_;
+            result_type y_;
+            result_type table_[k];
+    };
+
+    /**
+     * 26.5.5, engines and engine adaptors with predefined
+     * parameters:
+     * TODO: check their requirements for testing
+     */
+
+    using minstd_rand0  = linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>;
+    using minstd_rand   = linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>;
+    using mt19937       = mersenne_twister_engine<
+        uint_fast32_t, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7,
+        0x9d2c5680, 15, 0xefc60000, 18, 1812433253
+    >;
+    using mt19937_64    = mersenne_twister_engine<
+        uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9, 29,
+        0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000,
+        43, 6364136223846793005
+    >;
+    using ranlux24_base = subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;
+    using ranlux48_base = subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;
+    using ranlux24      = discard_block_engine<ranlux24_base, 223, 23>;
+    using ranlux48      = discard_block_engine<ranlux48_base, 389, 11>;
+    using knuth_b       = shuffle_order_engine<minstd_rand0, 256>;
+
+    using default_random_engine = minstd_rand0;
+
+    /**
+     * 26.5.6, class random_device:
+     */
+
+    class random_device
+    {
+        using result_type = unsigned int;
+
+        static constexpr result_type min()
+        {
+            return numeric_limits<result_type>::min();
+        }
+
+        static constexpr result_type max()
+        {
+            return numeric_limits<result_type>::max();
+        }
+
+        explicit random_device(const string& token = "")
+        {
+            /**
+             * Note: token can be used to choose between
+             *       random generators, but HelenOS only
+             *       has one :/
+             *       Also note that it is implementation
+             *       defined how this class generates
+             *       random numbers and I decided to use
+             *       time seeding with C stdlib random,
+             *       - feel free to change it if you know
+             *       something better.
+             */
+            hel::srandom(hel::time(nullptr));
+        }
+
+        result_type operator()()
+        {
+            return hel::random();
+        }
+
+        double entropy() const noexcept
+        {
+            return 0.0;
+        }
+
+        random_device(const random_device&) = delete;
+        random_device& operator=(const random_device&) = delete;
+    };
+
+    /**
+     * 26.5.7.1, class seed_seq:
+     */
+
+    class seed_seq
+    {
+        public:
+            using result_type = uint_least32_t;
+
+            seed_seq()
+                : vec_{}
+            { /* DUMMY BODY */ }
+
+            template<class T>
+            seed_seq(initializer_list<T> init)
+                : seed_seq(init.begin(), init.end())
+            { /* DUMMY BODY */ }
+
+            template<class InputIterator>
+            seed_seq(InputIterator first, InputIterator last)
+                : vec_{}
+            {
+                while (first != last)
+                    vec_.push_back((*first++) % aux::pow2u(32));
+            }
+
+            template<class RandomAccessGenerator>
+            void generate(RandomAccessGenerator first,
+                          RandomAccessGenerator last)
+            {
+                if (first == last)
+                    return;
+
+                auto s = vec_.size();
+                size_t n = last - first;
+                result_type t = (n >= 623) ? 11 : (n >= 68) ? 7 : (n >= 39) ? 5 : (n >= 7) ? 3 : (n - 1) / 2;
+                result_type p = (n - t) / 2;
+                result_type q = p + t;
+
+                auto current = first;
+                while (current != last)
+                    *current++ = 0x8b8b8b8b;
+
+                auto m = (s + 1 > n) ? (s + 1) : n;
+                decltype(m) k{};
+                for (; k < m; ++k)
+                {
+                    auto r1 = 1664525 * t_(first[k % n] ^ first[(k + p) % n] ^ first[(k - 1) % n]);
+                    auto r2 = r1;
+
+                    if (k == 0)
+                        r2 += s;
+                    else if (k > 0 && k <= s)
+                        r2 += (k % n) + vec_[(k - 1) % n];
+                    else if (s < k)
+                        r2 += (k % n);
+
+                    first[(k + p) % n] += r1;
+                    first[(k + q) % n] += r2;
+                    first[k % n] = r2;
+                }
+
+                for (; k < m + n - 1; ++k)
+                {
+                    auto r3 = 1566083941 * t_(first[k % n] + first[(k + p) % n] + first[(k - 1) % n]);
+                    auto r4 = r3 - (k % n);
+
+                    first[(k + p) % n] ^= r3;
+                    first[(k + q) % n] ^= r4;
+                    first[k % n] = r4;
+                }
+            }
+
+            size_t size() const
+            {
+                return vec_.size();
+            }
+
+            template<class OutputIterator>
+            void param(OutputIterator dest) const
+            {
+                for (const auto& x: vec_)
+                    *dest++ = x;
+            }
+
+            seed_seq(const seed_seq&) = delete;
+            seed_seq& operator=(const seed_seq&) = delete;
+
+        private:
+            vector<result_type> vec_;
+
+            result_type t_(result_type val) const
+            {
+                return val ^ (val >> 27);
+            }
+    };
+
+    /**
+     * 26.5.7.2, function template generate_canonical:
+     */
+
+    template<class RealType, size_t bits, class URNG>
+    RealType generate_canonical(URNG& g)
+    {
+        auto b = (bits < numeric_limits<RealType>::digits) ? bits : numeric_limits<RealType>::digits;
+        RealType r = g.max() - g.min() + 1;
+        size_t tmp = aux::ceil(b / aux::log2(r));
+        size_t k = (1U < tmp) ? tmp : 1U;
+
+        RealType s{};
+        for (size_t i = 0; i < k; ++i)
+            s += (g() - g.min()) * aux::pow(r, i);
+
+        return s / aux::pow(r, k);
+    }
+
+    /**
+     * 26.5.8.2.1, class template uniform_int_distribution:
+     */
+
+    template<class IntType = int>
+    class uniform_int_distribution
+    {
+        public:
+            using result_type = IntType;
+            using param_type  = pair<result_type, result_type>;
+
+            explicit uniform_int_distribution(result_type a = 0,
+                                              result_type b = numeric_limits<result_type>::max())
+                : a_{a}, b_{b}
+            { /* DUMMY BODY */ }
+
+            explicit uniform_int_distribution(const param_type& p)
+                : a_{p.first}, b_{p.second}
+            { /* DUMMY BODY */ }
+
+            void reset()
+            { /* DUMMY BODY */ }
+
+            template<class URNG>
+            result_type operator()(URNG& g)
+            {
+                auto range = b_ - a_ + 1;
+
+                return g() % range + a_;
+            }
+
+            template<class URNG>
+            result_type operator()(URNG& g, const param_type& p)
+            {
+                auto range = p.second - p.first + 1;
+
+                return g() % range + p.first;
+            }
+
+            result_type a() const
+            {
+                return a_;
+            }
+
+            result_type b() const
+            {
+                return b_;
+            }
+
+            param_type param() const
+            {
+                return param_type{a_, b_};
+            }
+
+            void param(const param_type& p)
+            {
+                a_ = p.first;
+                b_ = p.second;
+            }
+
+            result_type min() const
+            {
+                return a_;
+            }
+
+            result_type max() const
+            {
+                return b_;
+            }
+
+            bool operator==(const uniform_int_distribution& rhs) const
+            {
+                return a_ == rhs.a_ && b_ == rhs.b_;
+            }
+
+            bool operator!=(const uniform_int_distribution& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                os << a_ << os.widen(' ') << b_;
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                if (!(is >> a_) || !(is >> b_))
+                    is.setstate(ios::failbit);
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            result_type a_;
+            result_type b_;
+    };
+
+    /**
+     * 26.5.8.2.2, class template uniform_real_distribution:
+     */
+
+    template<class RealType = double>
+    class uniform_real_distribution
+    {
+        public:
+            using result_type = RealType;
+            using param_type  = pair<result_type, result_type>;
+
+            explicit uniform_real_distribution(result_type a = 0.0,
+                                               result_type b = 1.0)
+                : a_{a}, b_{b}
+            { /* DUMMY BODY */ }
+
+            explicit uniform_real_distribution(const param_type& p)
+                : a_{p.first}, b_{p.second}
+            { /* DUMMY BODY */ }
+
+            void reset()
+            { /* DUMMY BODY */ }
+
+            template<class URNG>
+            result_type operator()(URNG& g)
+            {
+                auto range = b_ - a_ + 1;
+
+                return generate_canonical<
+                    result_type, numeric_limits<result_type>::digits
+                >(g) * range + a_;
+            }
+
+            template<class URNG>
+            result_type operator()(URNG& g, const param_type& p)
+            {
+                auto range = p.second - p.first + 1;
+
+                return generate_canonical<
+                    result_type, numeric_limits<result_type>::digits
+                >(g) * range + p.first;
+            }
+
+            result_type a() const
+            {
+                return a_;
+            }
+
+            result_type b() const
+            {
+                return b_;
+            }
+
+            param_type param() const
+            {
+                return param_type{a_, b_};
+            }
+
+            void param(const param_type& p)
+            {
+                a_ = p.first;
+                b_ = p.second;
+            }
+
+            result_type min() const
+            {
+                return a_;
+            }
+
+            result_type max() const
+            {
+                return b_;
+            }
+
+            bool operator==(const uniform_real_distribution& rhs) const
+            {
+                return a_ == rhs.a_ && b_ == rhs.b_;
+            }
+
+            bool operator!=(const uniform_real_distribution& rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            // TODO: ostream/istream operators can't be members
+            template<class Char, class Traits>
+            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
+            {
+                auto flags = os.flags();
+                os.flags(ios_base::dec | ios_base::left);
+
+                os << a_ << os.widen(' ') << b_;
+
+                os.flags(flags);
+                return os;
+            }
+
+            template<class Char, class Traits>
+            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
+            {
+                auto flags = is.flags();
+                is.flags(ios_base::dec);
+
+                if (!(is >> a_) || !(is >> b_))
+                    is.setstate(ios::failbit);
+
+                is.flags(flags);
+                return is;
+            }
+
+        private:
+            result_type a_;
+            result_type b_;
+    };
+
+    /**
+     * 26.5.8.3.1, class bernoulli_distribution:
+     */
+
+    class bernoulli_distribution
+    {
+        public:
+            using result_type = bool;
+            using param_type  = float;
+
+            explicit bernoulli_distribution(double prob = 0.5)
+                : prob_{static_cast<float>(prob)}
+            { /* DUMMY BODY */ }
+
+            explicit bernoulli_distribution(const param_type& p)
+                : prob_{p}
+            { /* DUMMY BODY */ }
+
+            void reset()
+            { /* DUMMY BODY */ }
+
+            template<class URNG>
+            result_type operator()(URNG& g)
+            {
+                uniform_real_distribution<float> dist{};
+
+                return dist(g) < prob_;
+            }
+
+            template<class URNG>
+            result_type operator()(const param_type& p)
+            {
+                uniform_real_distribution<float> dist{};
+
+                return dist(p) < prob_;
+            }
+
+            double p() const
+            {
+                return prob_;
+            }
+
+            param_type param() const
+            {
+                return prob_;
+            }
+
+            void param(const param_type& p)
+            {
+                prob_ = p;
+            }
+
+            result_type min() const
+            {
+                return false;
+            }
+
+            result_type max() const
+            {
+                return true;
+            }
+
+        private:
+            /**
+             * Note: We use float because we do not
+             *       have the macro DBL_MANT_DIGITS
+             *       for generate_cannonical.
+             */
+            float prob_;
+    };
+
+    // TODO: complete the rest of the distributions
+
+    /**
+     * 26.5.8.3.2, class template binomial_distribution:
+     */
+
+    template<class IntType = int>
+    class binomial_distribution;
+
+    /**
+     * 26.5.8.3.3, class template geometric_distribution:
+     */
+
+    template<class IntType = int>
+    class geometric_distribution;
+
+    /**
+     * 26.5.8.3.4, class template negative_binomial_distribution:
+     */
+
+    template<class IntType = int>
+    class negative_binomial_distribution;
+
+    /**
+     * 26.5.8.4.1, class template poisson_distribution:
+     */
+
+    template<class IntType = int>
+    class poisson_distribution;
+
+    /**
+     * 26.5.8.4.2, class template exponential_distribution:
+     */
+
+    template<class RealType = double>
+    class exponential_distribution;
+
+    /**
+     * 26.5.8.4.3, class template gamma_distribution:
+     */
+
+    template<class RealType = double>
+    class gamma_distribution;
+
+    /**
+     * 26.5.8.4.4, class template weibull_distribution:
+     */
+
+    template<class RealType = double>
+    class weibull_distribution;
+
+    /**
+     * 26.5.8.4.5, class template extreme_value_distribution:
+     */
+
+    template<class RealType = double>
+    class extreme_value_distribution;
+
+    /**
+     * 26.5.8.5.1, class template normal_distribution:
+     */
+
+    template<class RealType = double>
+    class normal_distribution;
+
+    /**
+     * 26.5.8.5.2, class template lognormal_distribution:
+     */
+
+    template<class RealType = double>
+    class lognormal_distribution;
+
+    /**
+     * 26.5.8.5.3, class template chi_squared_distribution:
+     */
+
+    template<class RealType = double>
+    class chi_squared_distribution;
+
+    /**
+     * 26.5.8.5.4, class template cauchy_distribution:
+     */
+
+    template<class RealType = double>
+    class cauchy_distribution;
+
+    /**
+     * 26.5.8.5.5, class template fisher_f_distribution:
+     */
+
+    template<class RealType = double>
+    class fisher_f_distribution;
+
+    /**
+     * 26.5.8.5.6, class template student_t_distribution:
+     */
+
+    template<class RealType = double>
+    class student_t_distribution;
+
+    /**
+     * 26.5.8.6.1, class template discrete_distribution:
+     */
+
+    template<class IntType = int>
+    class discrete_distribution;
+
+    /**
+     * 26.5.8.6.2, class template piecewise_constant_distribution:
+     */
+
+    template<class RealType = double>
+    class piecewise_constant_distribution;
+
+    /**
+     * 26.5.8.6.3, class template piecewise_linear_distribution:
+     */
+
+    template<class RealType = double>
+    class piecewise_linear_distribution;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/ratio.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/ratio.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/ratio.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_RATIO
+#define LIBCPP_BITS_RATIO
+
+#include <cstdint>
+#include <type_traits>
+
+namespace std
+{
+    namespace aux
+    {
+        template<intmax_t A, intmax_t B>
+        struct gcd
+        {
+            static constexpr intmax_t value = gcd<B, A % B>::value;
+        };
+
+        template<intmax_t A>
+        struct gcd<A, 0>
+        {
+            static constexpr intmax_t value = A;
+        };
+
+        template<intmax_t A, intmax_t B>
+        inline constexpr intmax_t gcd_v = gcd<A, B>::value;
+
+        template<intmax_t A>
+        struct abs
+        {
+            static constexpr intmax_t value = (A > 0 ? A : -A);
+        };
+
+        template<intmax_t A>
+        inline constexpr intmax_t abs_v = abs<A>::value;
+
+        template<intmax_t A>
+        struct sign
+        {
+            static constexpr intmax_t value = (A == 0 ? 0: (A > 0 ? 1 : -1));
+        };
+
+        template<intmax_t A>
+        inline constexpr intmax_t sign_v = sign<A>::value;
+
+        // Not used here, but in <chrono>, better to keep them together.
+        template<intmax_t A, intmax_t B>
+        struct lcm
+        {
+            static constexpr intmax_t value = abs_v<A * B> / gcd_v<A, B>;
+        };
+
+        template<intmax_t A, intmax_t B>
+        inline constexpr intmax_t lcm_v = lcm<A, B>::value;
+    }
+
+    /**
+     * 20.11.3, class template ratio:
+     */
+
+    template<intmax_t N, intmax_t D = 1>
+    class ratio
+    {
+        public:
+            static_assert(D != 0, "ratio with denominator == 0");
+
+            static constexpr intmax_t num = aux::sign_v<N> * aux::sign_v<D>
+                                            * aux::abs_v<N> / aux::gcd_v<N, D>;
+
+            static constexpr intmax_t den = aux::abs_v<D> / aux::gcd_v<N, D>;
+
+            using type = ratio<num, den>;
+    };
+
+    /**
+     * 20.11.4, ratio arithmetic:
+     */
+
+    template<class R1, class R2>
+    using ratio_add = typename ratio<
+        R1::num * R2::den + R2::num * R1::den,
+        R1::den * R2::den
+    >::type;
+
+    template<class R1, class R2>
+    using ratio_subtract = typename ratio<
+        R1::num * R2::den - R2::num * R1::den,
+        R1::den * R2::den
+    >::type;
+
+    template<class R1, class R2>
+    using ratio_multiply = typename ratio<
+        R1::num * R2::num,
+        R1::den * R2::den
+    >::type;
+
+    template<class R1, class R2>
+    using ratio_divide = typename ratio<
+        R1::num * R2::den,
+        R1::den * R2::num
+    >::type;
+
+    /**
+     * 20.11.5, ratio comparison:
+     */
+
+    template<class R1, class R2>
+    struct ratio_equal: integral_constant<
+        bool, (R1::num == R2::num) && (R1::den == R2::den)
+    >
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
+
+    template<class R1, class R2>
+    struct ratio_not_equal: integral_constant<bool, !ratio_equal<R1, R2>::value>
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
+
+    template<class R1, class R2>
+    struct ratio_less: integral_constant<
+        bool, R1::num * R2::den < R2::num * R1::den
+    >
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
+
+    template<class R1, class R2>
+    struct ratio_less_equal: integral_constant<bool, !ratio_less<R2, R1>::value>
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
+
+    template<class R1, class R2>
+    struct ratio_greater: integral_constant<bool, ratio_less<R2, R1>::value>
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
+
+    template<class R1, class R2>
+    struct ratio_greater_equal: integral_constant<bool, !ratio_less<R1, R2>::value>
+    { /* DUMMY BODY */ };
+
+    template<class R1, class R2>
+    inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
+
+    /**
+     * 20.11.6, convenience SI typedefs:
+     */
+
+    // TODO: yocto/zepto and yotta/zetta should not be defined if intmax_t is too small
+
+    /* using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; */
+    /* using zepto = ratio<1,     1'000'000'000'000'000'000'000>; */
+    using atto  = ratio<1,         1'000'000'000'000'000'000>;
+    using femto = ratio<1,             1'000'000'000'000'000>;
+    using pico  = ratio<1,                 1'000'000'000'000>;
+    using nano  = ratio<1,                     1'000'000'000>;
+    using micro = ratio<1,                         1'000'000>;
+    using milli = ratio<1,                             1'000>;
+    using centi = ratio<1,                               100>;
+    using deci  = ratio<1,                                10>;
+    using deca  = ratio<                               10, 1>;
+    using hecto = ratio<                              100, 1>;
+    using kilo  = ratio<                            1'000, 1>;
+    using mega  = ratio<                        1'000'000, 1>;
+    using giga  = ratio<                    1'000'000'000, 1>;
+    using tera  = ratio<                1'000'000'000'000, 1>;
+    using peta  = ratio<            1'000'000'000'000'000, 1>;
+    using exa   = ratio<        1'000'000'000'000'000'000, 1>;
+    /* using zetta = ratio<    1'000'000'000'000'000'000'000, 1>; */
+    /* using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; */
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/rbtree.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/rbtree.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,491 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_RBTREE
-#define LIBCPP_BITS_RBTREE
-
-#include <__bits/key_extractors.hpp>
-#include <__bits/rbtree_iterators.hpp>
-#include <__bits/rbtree_node.hpp>
-#include <__bits/rbtree_policies.hpp>
-
-namespace std::aux
-{
-    template<
-        class Value, class Key, class KeyExtractor,
-        class KeyComp, class Alloc, class Size,
-        class Iterator, class ConstIterator,
-        class Policy, class Node
-    >
-    class rbtree
-    {
-        public:
-            using value_type     = Value;
-            using key_type       = Key;
-            using size_type      = Size;
-            using allocator_type = Alloc;
-            using key_compare    = KeyComp;
-            using key_extract    = KeyExtractor;
-
-            using iterator       = Iterator;
-            using const_iterator = ConstIterator;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            using node_type = Node;
-
-            rbtree(const key_compare& kcmp = key_compare{})
-                : root_{nullptr}, size_{}, key_compare_{},
-                  key_extractor_{}
-            { /* DUMMY BODY */ }
-
-            rbtree(const rbtree& other)
-                : rbtree{other.key_compare_}
-            {
-                for (const auto& x: other)
-                    insert(x);
-            }
-
-            rbtree(rbtree&& other)
-                : root_{other.root_}, size_{other.size_},
-                  key_compare_{move(other.key_compare_)},
-                  key_extractor_{move(other.key_extractor_)}
-            {
-                other.root_ = nullptr;
-                other.size_ = size_type{};
-            }
-
-            rbtree& operator=(const rbtree& other)
-            {
-                auto tmp{other};
-                tmp.swap(*this);
-
-                return *this;
-            }
-
-            rbtree& operator=(rbtree&& other)
-            {
-                rbtree tmp{move(other)};
-                tmp.swap(*this);
-
-                return *this;
-            }
-
-            bool empty() const noexcept
-            {
-                return size_ == 0U;
-            }
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type max_size(allocator_type& alloc)
-            {
-                return allocator_traits<allocator_type>::max_size(alloc);
-            }
-
-            iterator begin()
-            {
-                return iterator{find_smallest_(), false};
-            }
-
-            const_iterator begin() const
-            {
-                return cbegin();
-            }
-
-            iterator end()
-            {
-                /**
-                 * In case we have lists of nodes
-                 * we need to get the actual end
-                 * from the largest node.
-                 */
-                auto res = find_largest_();
-                if (res)
-                    return iterator{res->get_end(), true};
-                else
-                    return iterator{res, true};
-            }
-
-            const_iterator end() const
-            {
-                return cend();
-            }
-
-            reverse_iterator rbegin()
-            {
-                return make_reverse_iterator(end());
-            }
-
-            const_reverse_iterator rbegin() const
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            reverse_iterator rend()
-            {
-                return make_reverse_iterator(begin());
-            }
-
-            const_reverse_iterator rend() const
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            const_iterator cbegin() const
-            {
-                return const_iterator{find_smallest_(), false};
-            }
-
-            const_iterator cend() const
-            {
-                auto res = find_largest_();
-                if (res)
-                    return const_iterator{res->get_end(), true};
-                else
-                    return const_iterator{res, true};
-            }
-
-            const_reverse_iterator crbegin() const
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            const_reverse_iterator crend() const
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            template<class... Args>
-            auto emplace(Args&&... args)
-            {
-                return Policy::emplace(*this, forward<Args>(args)...);
-            }
-
-            auto insert(const value_type& val)
-            {
-                return Policy::insert(*this, val);
-            }
-
-            auto insert(value_type&& val)
-            {
-                return Policy::insert(*this, forward<value_type>(val));
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return Policy::erase(*this, key);
-            }
-
-            iterator erase(const_iterator it)
-            {
-                if (it == cend())
-                    return end();
-
-                auto node = const_cast<node_type*>(it.node());
-
-                node = delete_node(node);
-                if (!node)
-                    return iterator{find_largest_(), true};
-                else
-                    return iterator{const_cast<node_type*>(node), false};
-            }
-
-            void clear() noexcept
-            {
-                if (root_)
-                {
-                    delete root_;
-                    root_ = nullptr;
-                    size_ = size_type{};
-                }
-            }
-
-            void swap(rbtree& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(swap(declval<KeyComp&>(), declval<KeyComp&>())))
-            {
-                std::swap(root_, other.root_);
-                std::swap(size_, other.size_);
-                std::swap(key_compare_, other.key_compare_);
-                std::swap(key_extractor_, other.key_extractor_);
-            }
-
-            key_compare key_comp() const
-            {
-                return key_compare_;
-            }
-
-            iterator find(const key_type& key)
-            {
-                auto node = find_(key);
-                if (node)
-                    return iterator{node, false};
-                else
-                    return end();
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                auto node = find_(key);
-                if (node)
-                    return const_iterator{node, false};
-                else
-                    return end();
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return Policy::count(*this, key);
-            }
-
-            iterator upper_bound(const key_type& key)
-            {
-                return Policy::upper_bound(*this, key);
-            }
-
-            const_iterator upper_bound(const key_type& key) const
-            {
-                return Policy::upper_bound_const(*this, key);
-            }
-
-            iterator lower_bound(const key_type& key)
-            {
-                return Policy::lower_bound(*this, key);
-            }
-
-            const_iterator lower_bound(const key_type& key) const
-            {
-                return Policy::lower_bound_const(*this, key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return Policy::equal_range(*this, key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return Policy::equal_range_const(*this, key);
-            }
-
-            bool is_eq_to(const rbtree& other) const
-            {
-                if (size_ != other.size())
-                    return false;
-
-                auto it1 = begin();
-                auto it2 = other.begin();
-
-                // TODO: this doesn't compare values :/
-                while (keys_equal(*it1++, *it2++))
-                { /* DUMMY BODY */ }
-
-                return (it1 == end()) && (it2 == other.end());
-            }
-
-            const key_type& get_key(const value_type& val) const
-            {
-                return key_extractor_(val);
-            }
-
-            bool keys_comp(const key_type& key, const value_type& val) const
-            {
-                return key_compare_(key, key_extractor_(val));
-            }
-
-            bool keys_equal(const key_type& k1, const key_type& k2) const
-            {
-                return !key_compare_(k1, k2) && !key_compare_(k2, k1);
-            }
-
-            node_type* find_parent_for_insertion(const key_type& key) const
-            {
-                auto current = root_;
-                auto parent = current;
-
-                while (current)
-                {
-                    parent = current;
-                    if (key_compare_(key, key_extractor_(current->value)))
-                        current = current->left();
-                    else if (key_compare_(key_extractor_(current->value), key))
-                        current = current->right();
-                    else
-                        return current;
-                }
-
-                return parent;
-            }
-
-            node_type* delete_node(const node_type* n)
-            {
-                auto node = const_cast<node_type*>(n);
-                if (!node)
-                    return nullptr;
-
-                --size_;
-
-                auto succ = node->successor();
-                if (auto tmp = node->get_node_for_deletion(); tmp != nullptr)
-                {
-                    /**
-                     * This will kick in multi containers,
-                     * we popped one node from a list of nodes
-                     * with equivalent keys and we can delete it
-                     * and return the successor which was the next
-                     * in the list.
-                     */
-                    delete tmp;
-
-                    update_root_(succ); // Incase the first in list was root.
-                    return succ;
-                }
-                else if (node == root_)
-                { // Only executed if root_ is unique.
-                    root_ = nullptr;
-                    delete node;
-
-                    return nullptr;
-                }
-
-                if (node->left() && node->right())
-                {
-                    node->swap(succ);
-                    if (succ && !succ->parent())
-                        root_ = succ;
-
-                    // Node now has at most one child.
-                    // Also: If succ was nullptr, the swap
-                    //       didn't do anything and we can
-                    //       safely delete node.
-                    return delete_node(node);
-                }
-
-                auto child = node->right() ? node->right() : node->left();
-                if (!child)
-                {
-                    // Simply remove the node.
-                    // TODO: repair here too?
-                    node->unlink();
-                    delete node;
-                }
-                else
-                {
-                    // Replace with the child.
-                    child->parent(node->parent());
-                    if (node->is_left_child())
-                        child->parent()->left(child);
-                    else if (node->is_right_child())
-                        child->parent()->right(child);
-                    node->parent(nullptr);
-                    node->left(nullptr);
-                    node->right(nullptr);
-
-                    // Repair if needed.
-                    repair_after_erase_(node, child);
-                    update_root_(child);
-
-                    delete node;
-                }
-
-                return succ;
-            }
-
-            void insert_node(node_type* node, node_type* parent)
-            {
-                Policy::insert(*this, node, parent);
-            }
-
-        private:
-            node_type* root_;
-            size_type size_;
-            key_compare key_compare_;
-            key_extract key_extractor_;
-
-            node_type* find_(const key_type& key) const
-            {
-                auto current = root_;
-                while (current != nullptr)
-                {
-                    if (key_compare_(key, key_extractor_(current->value)))
-                        current = current->left();
-                    else if (key_compare_(key_extractor_(current->value), key))
-                        current = current->right();
-                    else
-                        return current;
-                }
-
-                return nullptr;
-            }
-
-            node_type* find_smallest_() const
-            {
-                if (root_)
-                    return root_->find_smallest();
-                else
-                    return nullptr;
-            }
-
-            node_type* find_largest_() const
-            {
-                if (root_)
-                    return root_->find_largest();
-                else
-                    return nullptr;
-            }
-
-            void update_root_(const node_type* node)
-            {
-                if (!node)
-                    return;
-
-                root_ = const_cast<node_type*>(node);
-                while (root_->parent())
-                    root_ = root_->parent();
-            }
-
-            void repair_after_insert_(const node_type* node)
-            {
-                // TODO: implement
-            }
-
-            void repair_after_erase_(const node_type* node, const node_type* child)
-            {
-                // TODO: implement
-            }
-
-            friend Policy;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/rbtree_iterators.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/rbtree_iterators.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,330 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_RBTREE_ITERATORS
-#define LIBCPP_BITS_RBTREE_ITERATORS
-
-#include <__bits/iterator.hpp>
-#include <__bits/rbtree_node.hpp>
-#include <iterator>
-
-namespace std::aux
-{
-    /**
-     * Note: In order for these iterators to be reversible,
-     *       the end state of an iterator is represented by a flag
-     *       which can be set from true to false in operator--
-     *       (i.e. decrementing end iterator) or set from false to
-     *       true in operator++ (i.e. incrementing last before end
-     *       iterator).
-     */
-
-    template<class Value, class Reference, class Pointer, class Size, class Node>
-    class rbtree_iterator
-    {
-        public:
-            using value_type      = Value;
-            using size_type       = Size;
-            using reference       = Reference;
-            using pointer         = Pointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = bidirectional_iterator_tag;
-
-            using node_type = Node;
-
-            rbtree_iterator(node_type* current = nullptr, bool end = true)
-                : current_{current}, end_{end}
-            { /* DUMMY BODY */ }
-
-            rbtree_iterator(const rbtree_iterator&) = default;
-            rbtree_iterator& operator=(const rbtree_iterator&) = default;
-
-            reference operator*() const
-            {
-                return current_->value;
-            }
-
-            pointer operator->() const
-            {
-                return &current_->value;
-            }
-
-            rbtree_iterator& operator++()
-            {
-                if (end_)
-                    return *this;
-
-                if (current_)
-                {
-                    auto next = current_->successor();
-                    if (next)
-                        current_ = next;
-                    else
-                        end_ = true;
-                }
-
-                return *this;
-            }
-
-            rbtree_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-            rbtree_iterator& operator--()
-            {
-                if (end_)
-                {
-                    end_ = false;
-
-                    return *this;
-                }
-
-                if (current_)
-                {
-                    auto next = current_->predecessor();
-                    if (next)
-                        current_ = next;
-                    else
-                        end_ = true;
-                }
-
-                return *this;
-            }
-
-            rbtree_iterator operator--(int)
-            {
-                auto tmp = *this;
-                --(*this);
-
-                return tmp;
-            }
-
-            const node_type* node() const
-            {
-                return current_;
-            }
-
-            node_type* node()
-            {
-                return current_;
-            }
-
-            bool end() const
-            {
-                return end_;
-            }
-
-        private:
-            node_type* current_;
-            bool end_;
-    };
-
-    template<class Val, class Ref, class Ptr, class Sz, class N>
-    bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
-                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
-    {
-        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-    }
-
-    template<class Val, class Ref, class Ptr, class Sz, class N>
-    bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
-                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Value, class ConstReference, class ConstPointer, class Size, class Node>
-    class rbtree_const_iterator
-    {
-        using non_const_iterator_type = rbtree_iterator<
-            Value, get_non_const_ref_t<ConstReference>,
-            get_non_const_ptr_t<ConstPointer>, Size, Node
-        >;
-
-        public:
-            using value_type      = Value;
-            using size_type       = Size;
-            using const_reference = ConstReference;
-            using const_pointer   = ConstPointer;
-            using difference_type = ptrdiff_t;
-
-            using iterator_category = bidirectional_iterator_tag;
-
-            // For iterator_traits.
-            using reference = ConstReference;
-            using pointer   = ConstPointer;
-
-            using node_type = Node;
-
-            rbtree_const_iterator(const node_type* current = nullptr, bool end = true)
-                : current_{current}, end_{end}
-            { /* DUMMY BODY */ }
-
-            rbtree_const_iterator(const rbtree_const_iterator&) = default;
-            rbtree_const_iterator& operator=(const rbtree_const_iterator&) = default;
-
-            rbtree_const_iterator(const non_const_iterator_type& other)
-                : current_{other.node()}, end_{other.end()}
-            { /* DUMMY BODY */ }
-
-            rbtree_const_iterator& operator=(const non_const_iterator_type& other)
-            {
-                current_ = other.node();
-                end_ = other.end();
-
-                return *this;
-            }
-
-            const_reference operator*() const
-            {
-                return current_->value;
-            }
-
-            const_pointer operator->() const
-            {
-                return &current_->value;
-            }
-
-            rbtree_const_iterator& operator++()
-            {
-                if (end_)
-                    return *this;
-
-                if (current_)
-                {
-                    auto next = current_->successor();
-                    if (next)
-                        current_ = next;
-                    else
-                        end_ = true;
-                }
-
-                return *this;
-            }
-
-            rbtree_const_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++(*this);
-
-                return tmp;
-            }
-
-            rbtree_const_iterator& operator--()
-            {
-                if (end_)
-                {
-                    end_ = false;
-
-                    return *this;
-                }
-
-                if (current_)
-                {
-                    auto next = current_->predecessor();
-                    if (next)
-                        current_ = next;
-                    else
-                        end_ = true;
-                }
-
-                return *this;
-            }
-
-            rbtree_const_iterator operator--(int)
-            {
-                auto tmp = *this;
-                --(*this);
-
-                return tmp;
-            }
-
-            const node_type* node() const
-            {
-                return current_;
-            }
-
-            bool end() const
-            {
-                return end_;
-            }
-
-        private:
-            const node_type* current_;
-            bool end_;
-    };
-
-    template<class Val, class CRef, class CPtr, class Sz, class N>
-    bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
-                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
-    {
-        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-    }
-
-    template<class Val, class CRef, class CPtr, class Sz, class N>
-    bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
-                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
-    bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
-                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
-    {
-        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-    }
-
-    template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
-    bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
-                    const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
-    bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
-                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
-    {
-        return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-    }
-
-    template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
-    bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
-                    const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/rbtree_node.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/rbtree_node.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,728 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_RBTREE_NODE
-#define LIBCPP_BITS_RBTREE_NODE
-
-#include <cassert>
-#include <utility>
-
-namespace std::aux
-{
-    enum class rbcolor
-    {
-        red, black
-    };
-
-    template<class Node>
-    struct rbtree_utils
-    {
-        static Node* grandparent(Node* node)
-        {
-            if (node && node->parent())
-                return node->parent()->parent();
-            else
-                return nullptr;
-        }
-
-        static Node* brother(Node* node)
-        {
-            if (node && node->parent())
-            {
-                if (node == node->parent()->left())
-                    return node->parent()->right();
-                else
-                    return node->parent()->left();
-            }
-            else
-                return nullptr;
-        }
-
-        static Node* uncle(Node* node)
-        {
-            auto gp = grandparent(node);
-            if (gp)
-            {
-                if (node->parent() == gp->left())
-                    return gp->right();
-                else
-                    return gp->left();
-            }
-            else
-                return nullptr;
-        }
-
-        static bool is_left_child(const Node* node)
-        {
-            if (!node)
-                return false;
-
-            if (node->parent())
-                return node->parent()->left() == node;
-            else
-                return false;
-        }
-
-        static bool is_right_child(const Node* node)
-        {
-            if (!node)
-                return false;
-
-            if (node->parent())
-                return node->parent()->right() == node;
-            else
-                return false;
-        }
-
-        static void rotate_left(Node* node)
-        {
-            // TODO: implement
-        }
-
-        static void rotate_right(Node* node)
-        {
-            // TODO: implement
-        }
-
-        static Node* find_smallest(Node* node)
-        {
-            return const_cast<Node*>(find_smallest(const_cast<const Node*>(node)));
-        }
-
-        static const Node* find_smallest(const Node* node)
-        {
-            if (!node)
-                return nullptr;
-
-            while (node->left())
-                node = node->left();
-
-            return node;
-        }
-
-        static Node* find_largest(Node* node)
-        {
-            return const_cast<Node*>(find_largest(const_cast<const Node*>(node)));
-        }
-
-        static const Node* find_largest(const Node* node)
-        {
-            if (!node)
-                return nullptr;
-
-            while (node->right())
-                node = node->right();
-
-            return node;
-        }
-
-        static Node* successor(Node* node)
-        {
-            return const_cast<Node*>(successor(const_cast<const Node*>(node)));
-        }
-
-        static const Node* successor(const Node* node)
-        {
-            if (!node)
-                return nullptr;
-
-            if (node->right())
-                return find_smallest(node->right());
-            else
-            {
-                while (node && !is_left_child(node))
-                    node = node->parent();
-
-                if (node)
-                    return node->parent();
-                else
-                    return node;
-            }
-        }
-
-        static Node* predecessor(Node* node)
-        {
-            return const_cast<Node*>(predecessor(const_cast<const Node*>(node)));
-        }
-
-        static const Node* predecessor(const Node* node)
-        {
-            if (!node)
-                return nullptr;
-
-            if (node->left())
-                return find_largest(node->left());
-            else
-            {
-                while (node && is_left_child(node))
-                    node = node->parent();
-
-                if (node)
-                    return node->parent();
-                else
-                    return node;
-            }
-        }
-
-        static void add_left_child(Node* node, Node* child)
-        {
-            if (!node || !child)
-                return;
-
-            node->left(child);
-            child->parent(node);
-        }
-
-        static void add_right_child(Node* node, Node* child)
-        {
-            if (!node || !child)
-                return;
-
-            node->right(child);
-            child->parent(node);
-        }
-
-        static void swap(Node* node1, Node* node2)
-        {
-            if (!node1 || !node2)
-                return;
-
-            auto parent1 = node1->parent();
-            auto left1 = node1->left();
-            auto right1 = node1->right();
-            auto is_right1 = is_right_child(node1);
-
-            auto parent2 = node2->parent();
-            auto left2 = node2->left();
-            auto right2 = node2->right();
-            auto is_right2 = is_right_child(node2);
-
-            assimilate(node1, parent2, left2, right2, is_right2);
-            assimilate(node2, parent1, left1, right1, is_right1);
-        }
-
-        static void assimilate(
-            Node* node, Node* p, Node* l, Node* r, bool is_r
-        )
-        {
-            if (!node)
-                return;
-
-            node->parent(p);
-            if (node->parent())
-            {
-                if (is_r)
-                    node->parent()->right(node);
-                else
-                    node->parent()->left(node);
-            }
-
-            node->left(l);
-            if (node->left())
-                node->left()->parent(node);
-
-            node->right(r);
-            if (node->right())
-                node->right()->parent(node);
-        }
-    };
-
-    template<class T>
-    struct rbtree_single_node
-    {
-        using utils = rbtree_utils<rbtree_single_node<T>>;
-
-        public:
-            T value;
-            rbcolor color;
-
-            template<class... Args>
-            rbtree_single_node(Args&&... args)
-                : value{forward<Args>(args)...}, color{rbcolor::red},
-                  parent_{}, left_{}, right_{}
-            { /* DUMMY BODY */ }
-
-            rbtree_single_node* parent() const
-            {
-                return parent_;
-            }
-
-            void parent(rbtree_single_node* node)
-            {
-                parent_ = node;
-            }
-
-            rbtree_single_node* left() const
-            {
-                return left_;
-            }
-
-            void left(rbtree_single_node* node)
-            {
-                left_ = node;
-            }
-
-            rbtree_single_node* right() const
-            {
-                return right_;
-            }
-
-            void right(rbtree_single_node* node)
-            {
-                right_ = node;
-            }
-
-            rbtree_single_node* grandparent()
-            {
-                return utils::grandparent(this);
-            }
-
-            rbtree_single_node* brother()
-            {
-                return utils::brother(this);
-            }
-
-            rbtree_single_node* uncle()
-            {
-                return utils::uncle(this);
-            }
-
-            bool is_left_child() const
-            {
-                return utils::is_left_child(this);
-            }
-
-            bool is_right_child() const
-            {
-                return utils::is_right_child(this);
-            }
-
-            void rotate_left()
-            {
-                utils::rotate_left(this);
-            }
-
-            void rotate_right()
-            {
-                utils::rotate_right(this);
-            }
-
-            rbtree_single_node* find_smallest()
-            {
-                return utils::find_smallest(this);
-            }
-
-            const rbtree_single_node* find_smallest() const
-            {
-                return utils::find_smallest(this);
-            }
-
-            rbtree_single_node* find_largest()
-            {
-                return utils::find_largest(this);
-            }
-
-            const rbtree_single_node* find_largest() const
-            {
-                return utils::find_largest(this);
-            }
-
-            rbtree_single_node* successor()
-            {
-                return utils::successor(this);
-            }
-
-            const rbtree_single_node* successor() const
-            {
-                return utils::successor(this);
-            }
-
-            rbtree_single_node* predecessor()
-            {
-                return utils::predecessor(this);
-            }
-
-            const rbtree_single_node* predecessor() const
-            {
-                return utils::predecessor(this);
-            }
-
-            void add_left_child(rbtree_single_node* node)
-            {
-                utils::add_left_child(this, node);
-            }
-
-            void add_right_child(rbtree_single_node* node)
-            {
-                utils::add_right_child(this, node);
-            }
-
-            void swap(rbtree_single_node* other)
-            {
-                utils::swap(this, other);
-            }
-
-            void unlink()
-            {
-                if (is_left_child())
-                    parent_->left_ = nullptr;
-                else if (is_right_child())
-                    parent_->right_ = nullptr;
-            }
-
-            rbtree_single_node* get_node_for_deletion()
-            {
-                return nullptr;
-            }
-
-            rbtree_single_node* get_end()
-            {
-                return this;
-            }
-
-            const rbtree_single_node* get_end() const
-            {
-                return this;
-            }
-
-            ~rbtree_single_node()
-            {
-                parent_ = nullptr;
-                if (left_)
-                    delete left_;
-                if (right_)
-                    delete right_;
-            }
-
-        private:
-            rbtree_single_node* parent_;
-            rbtree_single_node* left_;
-            rbtree_single_node* right_;
-    };
-
-    template<class T>
-    struct rbtree_multi_node
-    {
-        using utils = rbtree_utils<rbtree_multi_node<T>>;
-
-        public:
-            T value;
-            rbcolor color;
-
-            template<class... Args>
-            rbtree_multi_node(Args&&... args)
-                : value{forward<Args>(args)...}, color{rbcolor::red},
-                  parent_{}, left_{}, right_{}, next_{}, first_{}
-            {
-                first_ = this;
-            }
-
-            rbtree_multi_node* parent() const
-            {
-                return parent_;
-            }
-
-            void parent(rbtree_multi_node* node)
-            {
-                parent_ = node;
-
-                auto tmp = first_;
-                while (tmp)
-                {
-                    tmp->parent_ = node;
-                    tmp = tmp->next_;
-                }
-            }
-
-            rbtree_multi_node* left() const
-            {
-                return left_;
-            }
-
-            void left(rbtree_multi_node* node)
-            {
-                left_ = node;
-
-                auto tmp = first_;
-                while (tmp)
-                {
-                    tmp->left_ = node;
-                    tmp = tmp->next_;
-                }
-            }
-
-            rbtree_multi_node* right() const
-            {
-                return right_;
-            }
-
-            void right(rbtree_multi_node* node)
-            {
-                right_ = node;
-
-                auto tmp = first_;
-                while (tmp)
-                {
-                    tmp->right_ = node;
-                    tmp = tmp->next_;
-                }
-            }
-
-            rbtree_multi_node* grandparent()
-            {
-                return utils::grandparent(this);
-            }
-
-            rbtree_multi_node* brother()
-            {
-                return utils::brother(this);
-            }
-
-            rbtree_multi_node* uncle()
-            {
-                return utils::uncle(this);
-            }
-
-            bool is_left_child() const
-            {
-                return utils::is_left_child(this);
-            }
-
-            bool is_right_child()
-            {
-                return utils::is_right_child(this);
-            }
-
-            void rotate_left()
-            {
-                utils::rotate_left(this);
-            }
-
-            void rotate_right()
-            {
-                utils::rotate_right(this);
-            }
-
-            rbtree_multi_node* find_smallest()
-            {
-                return utils::find_smallest(this);
-            }
-
-            const rbtree_multi_node* find_smallest() const
-            {
-                return utils::find_smallest(this);
-            }
-
-            rbtree_multi_node* find_largest()
-            {
-                return utils::find_largest(this);
-            }
-
-            const rbtree_multi_node* find_largest() const
-            {
-                return utils::find_largest(this);
-            }
-
-            rbtree_multi_node* successor()
-            {
-                return const_cast<
-                    rbtree_multi_node*
-                >(const_cast<const rbtree_multi_node*>(this)->successor());
-            }
-
-            const rbtree_multi_node* successor() const
-            {
-                if (next_)
-                    return next_;
-                else
-                    return utils::successor(this);
-            }
-
-            rbtree_multi_node* predecessor()
-            {
-                return const_cast<
-                    rbtree_multi_node*
-                >(const_cast<const rbtree_multi_node*>(this)->predecessor());
-            }
-
-            const rbtree_multi_node* predecessor() const
-            {
-                if (this != first_)
-                {
-                    auto tmp = first_;
-                    while (tmp->next_ != this)
-                        tmp = tmp->next_;
-
-                    return tmp;
-                }
-                else
-                {
-                    auto tmp = utils::predecessor(this);
-
-                    /**
-                     * If tmp was duplicate, we got a pointer
-                     * to the first node in the list. So we need
-                     * to move to the end.
-                     */
-                    while (tmp->next_ != nullptr)
-                        tmp = tmp->next_;
-
-                    return tmp;
-                }
-            }
-
-            void add_left_child(rbtree_multi_node* node)
-            {
-                utils::add_left_child(this, node);
-            }
-
-            void add_right_child(rbtree_multi_node* node)
-            {
-                utils::add_right_child(this, node);
-            }
-
-            void swap(rbtree_multi_node* other)
-            {
-                utils::swap(this, other);
-            }
-
-            rbtree_multi_node* get_node_for_deletion()
-            {
-                /**
-                 * To make sure we delete nodes in
-                 * the order of their insertion
-                 * (not required, but sensical), we
-                 * update then list and return this
-                 * for deletion.
-                 */
-                if (next_)
-                {
-                    // Make next the new this.
-                    next_->first_ = next_;
-                    if (is_left_child())
-                        parent_->left_ = next_;
-                    else if (is_right_child())
-                        parent_->right_ = next_;
-
-                    if (left_)
-                        left_->parent_ = next_;
-                    if (right_)
-                        right_->parent_ = next_;
-
-                    /**
-                     * Update the first_ pointer
-                     * of the rest of the list.
-                     */
-                    auto tmp = next_->next_;
-                    while (tmp)
-                    {
-                        tmp->first_ = next_;
-                        tmp = tmp->next_;
-                    }
-
-                    /**
-                     * Otherwise destructor could
-                     * destroy them.
-                     */
-                    parent_ = nullptr;
-                    left_ = nullptr;
-                    right_ = nullptr;
-                    next_ = nullptr;
-                    first_ = nullptr;
-
-                    return this; // This will get deleted.
-                }
-                else
-                    return nullptr;
-            }
-
-            void unlink()
-            {
-                if (is_left_child())
-                    parent_->left_ = nullptr;
-                else if (is_right_child())
-                    parent_->right_ = nullptr;
-            }
-
-            void add(rbtree_multi_node* node)
-            {
-                if (next_)
-                    next_->add(node);
-                else
-                {
-                    next_ = node;
-                    next_->first_ = first_;
-                    next_->parent_ = parent_;
-                    next_->left_ = left_;
-                    next_->right_ = right_;
-                }
-            }
-
-            rbtree_multi_node* get_end()
-            {
-                return const_cast<rbtree_multi_node*>(
-                    const_cast<const rbtree_multi_node*>(this)->get_end()
-                );
-            }
-
-            const rbtree_multi_node* get_end() const
-            {
-                if (!next_)
-                    return this;
-                else
-                {
-                    auto tmp = next_;
-                    while (tmp->next_)
-                        tmp = tmp->next_;
-
-                    return tmp;
-                }
-            }
-
-            ~rbtree_multi_node()
-            {
-                parent_ = nullptr;
-                if (left_)
-                    delete left_;
-                if (right_)
-                    delete right_;
-
-                // TODO: delete the list
-            }
-
-        private:
-            rbtree_multi_node* parent_;
-            rbtree_multi_node* left_;
-            rbtree_multi_node* right_;
-
-            rbtree_multi_node* next_;
-            rbtree_multi_node* first_;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/rbtree_policies.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/rbtree_policies.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,458 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_RBTREE_POLICIES
-#define LIBCPP_BITS_RBTREE_POLICIES
-
-#include <__bits/rbtree_node.hpp>
-#include <utility>
-
-namespace std::aux
-{
-    struct rbtree_single_policy
-    {
-        template<class Tree, class Key>
-        static typename Tree::size_type count(const Tree& tree, const Key& key)
-        {
-            return tree.find(key) == tree.end() ? 0 : 1;
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::size_type erase(Tree& tree, const Key& key)
-        {
-            using size_type = typename Tree::size_type;
-
-            auto it = tree.find(key);
-            if (it == tree.end())
-                return size_type{};
-            else
-                tree.delete_node(it.node());
-            return size_type{1};
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::iterator lower_bound(const Tree& tree, const Key& key)
-        {
-            using iterator  = typename Tree::iterator;
-            using node_type = typename Tree::node_type;
-
-            auto it = lower_bound_const(tree, key);
-
-            return iterator{const_cast<node_type*>(it.node()), it.end()};
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::const_iterator lower_bound_const(const Tree& tree, const Key& key)
-        {
-            using const_iterator = typename Tree::const_iterator;
-
-            auto node = tree.find_parent_for_insertion(key);
-            const_iterator it{node, false};
-            auto beg = tree.begin();
-            auto end = tree.end();
-
-            if (tree.key_compare_(tree.get_key(*it), key))
-            {
-                // Predecessor.
-                if (it != end)
-                    return ++it;
-                else
-                    return it;
-            }
-            else if (tree.key_compare_(key, tree.get_key(*it)))
-            {
-                // Successor.
-                if (it != beg)
-                    return --it;
-                else
-                    return it;
-            }
-            else // Perfect match.
-                return it;
-
-            return it;
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::iterator upper_bound(const Tree& tree, const Key& key)
-        {
-            using iterator  = typename Tree::iterator;
-            using node_type = typename Tree::node_type;
-
-            auto it = upper_bound_const(tree, key);
-
-            return iterator{const_cast<node_type*>(it.node()), it.end()};
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::const_iterator upper_bound_const(const Tree& tree, const Key& key)
-        {
-            /**
-             * If key isn't in the tree, we get it's
-             * predecessor or tree.end(). If key is
-             * in the tree, we get it. So unless it
-             * is equal to end(), we can increment it
-             * to get the upper bound.
-             */
-            auto it = lower_bound_const(tree, key);
-            if (it == tree.end())
-                return it;
-            else
-                return ++it;
-        }
-
-        template<class Tree, class Key>
-        static pair<
-            typename Tree::iterator,
-            typename Tree::iterator
-        > equal_range(Tree& tree, const Key& key)
-        {
-            return make_pair(
-                lower_bound(tree, key),
-                upper_bound(tree, key)
-            );
-        }
-
-        template<class Tree, class Key>
-        static pair<
-            typename Tree::const_iterator,
-            typename Tree::const_iterator
-        > equal_range_const(const Tree& tree, const Key& key)
-        {
-            return make_pair(
-                lower_bound_const(tree, key),
-                upper_bound_const(tree, key)
-            );
-        }
-
-        /**
-         * Note: We have to duplicate code for emplace, insert(const&)
-         *       and insert(&&) here, because the node (which makes distinction
-         *       between the arguments) is only created if the value isn't
-         *       in the tree already.
-         */
-
-        template<class Tree, class... Args>
-        static pair<
-            typename Tree::iterator, bool
-        > emplace(Tree& tree, Args&&... args)
-        {
-            using value_type = typename Tree::value_type;
-            using iterator   = typename Tree::iterator;
-            using node_type  = typename Tree::node_type;
-
-            auto val = value_type{forward<Args>(args)...};
-            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
-
-            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
-                return make_pair(iterator{parent, false}, false);
-
-            auto node = new node_type{move(val)};
-
-            return insert(tree, node, parent);
-        }
-
-        template<class Tree, class Value>
-        static pair<
-            typename Tree::iterator, bool
-        > insert(Tree& tree, const Value& val)
-        {
-            using iterator  = typename Tree::iterator;
-            using node_type = typename Tree::node_type;
-
-            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
-            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
-                return make_pair(iterator{parent, false}, false);
-
-            auto node = new node_type{val};
-
-            return insert(tree, node, parent);
-        }
-
-        template<class Tree, class Value>
-        static pair<
-            typename Tree::iterator, bool
-        > insert(Tree& tree, Value&& val)
-        {
-            using iterator  = typename Tree::iterator;
-            using node_type = typename Tree::node_type;
-
-            auto parent = tree.find_parent_for_insertion(tree.get_key(val));
-            if (parent && tree.keys_equal(tree.get_key(parent->value), tree.get_key(val)))
-                return make_pair(iterator{parent, false}, false);
-
-            auto node = new node_type{forward<Value>(val)};
-
-            return insert(tree, node, parent);
-        }
-
-        template<class Tree>
-        static pair<
-            typename Tree::iterator, bool
-        > insert(
-            Tree& tree, typename Tree::node_type* node,
-            typename Tree::node_type* parent
-        )
-        {
-            using iterator  = typename Tree::iterator;
-
-            if (!node)
-                return make_pair(tree.end(), false);
-
-            ++tree.size_;
-            if (!parent)
-            {
-                node->color = rbcolor::black;
-                tree.root_ = node;
-            }
-            else
-            {
-                if (tree.keys_comp(tree.get_key(node->value), parent->value))
-                    parent->add_left_child(node);
-                else
-                    parent->add_right_child(node);
-
-                tree.repair_after_insert_(node);
-                tree.update_root_(node);
-            }
-
-            return make_pair(iterator{node, false}, true);
-        }
-    };
-
-    struct rbtree_multi_policy
-    {
-        template<class Tree, class Key>
-        static typename Tree::size_type count(const Tree& tree, const Key& key)
-        {
-            using size_type = typename Tree::size_type;
-
-            auto it = tree.find(key);
-            if (it == tree.end())
-                return size_type{};
-
-            size_type res{};
-            while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
-            {
-                ++res;
-                ++it;
-            }
-
-            return res;
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::size_type erase(Tree& tree, const Key& key)
-        {
-            using size_type = typename Tree::size_type;
-
-            auto it = tree.find(key);
-            if (it == tree.end())
-                return size_type{};
-
-            size_type res{};
-            while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
-            {
-                ++res;
-                it = tree.erase(it);
-            }
-
-            return res;
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::iterator lower_bound(const Tree& tree, const Key& key)
-        {
-            auto it = lower_bound_const(tree, key);
-
-            return typename Tree::iterator{
-                const_cast<typename Tree::node_type*>(it.node()), it.end()
-            };
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::const_iterator lower_bound_const(const Tree& tree, const Key& key)
-        {
-            using const_iterator = typename Tree::const_iterator;
-
-            auto node = tree.find_parent_for_insertion(key);
-            const_iterator it{node, false};
-            auto beg = tree.begin();
-            auto end = tree.end();
-
-            if (tree.keys_comp(key, *it))
-                --it; // Incase we are on a successor.
-            while (tree.keys_equal(tree.get_key(*it), key) && it != beg)
-                --it; // Skip keys that are equal.
-            if (it != beg)
-                ++it; // If we moved all the way to the start, key is the smallest.
-
-            if (tree.key_compare_(tree.get_key(*it), key))
-            {
-                // Predecessor.
-                if (it != end)
-                    return ++it;
-                else
-                    return it;
-            }
-
-            return it;
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::iterator upper_bound(const Tree& tree, const Key& key)
-        {
-            auto it = upper_bound_const(tree, key);
-
-            return typename Tree::iterator{
-                const_cast<typename Tree::node_type*>(it.node()), it.end()
-            };
-        }
-
-        template<class Tree, class Key>
-        static typename Tree::const_iterator upper_bound_const(const Tree& tree, const Key& key)
-        {
-            /**
-             * If key isn't in the tree, we get it's
-             * predecessor or tree.end(). If key is
-             * in the tree, we get it. So unless it
-             * is equal to end(), we keep incrementing
-             * until we get to the next key.
-             */
-            auto it = lower_bound(tree, key);
-            if (it == tree.end())
-                return it;
-            else if (tree.keys_equal(tree.get_key(*it), key))
-            {
-                while (it != tree.end() && tree.keys_equal(tree.get_key(*it), key))
-                    ++it;
-
-                return it;
-            }
-
-            return it;
-        }
-
-        template<class Tree, class Key>
-        static pair<
-            typename Tree::iterator,
-            typename Tree::iterator
-        > equal_range(const Tree& tree, const Key& key)
-        {
-            return make_pair(
-                lower_bound(tree, key),
-                upper_bound(tree, key)
-            );
-        }
-
-        template<class Tree, class Key>
-        static pair<
-            typename Tree::const_iterator,
-            typename Tree::const_iterator
-        > equal_range_const(const Tree& tree, const Key& key)
-        {
-            return make_pair(
-                lower_bound_const(tree, key),
-                upper_bound_const(tree, key)
-            );
-        }
-
-        template<class Tree, class... Args>
-        static typename Tree::iterator emplace(Tree& tree, Args&&... args)
-        {
-            using node_type  = typename Tree::node_type;
-
-            auto node = new node_type{forward<Args>(args)...};
-
-            return insert(tree, node);
-        }
-
-        template<class Tree, class Value>
-        static typename Tree::iterator insert(Tree& tree, const Value& val)
-        {
-            using node_type = typename Tree::node_type;
-
-            auto node = new node_type{val};
-
-            return insert(tree, node);
-        }
-
-        template<class Tree, class Value>
-        static typename Tree::iterator insert(Tree& tree, Value&& val)
-        {
-            using node_type = typename Tree::node_type;
-
-            auto node = new node_type{forward<Value>(val)};
-
-            return insert(tree, node);
-        }
-
-        template<class Tree>
-        static typename Tree::iterator insert(
-            Tree& tree, typename Tree::node_type* node,
-            typename Tree::node_type* = nullptr
-        )
-        {
-            using iterator  = typename Tree::iterator;
-
-            if (!node)
-                return tree.end();
-
-            auto parent = tree.find_parent_for_insertion(tree.get_key(node->value));
-
-            ++tree.size_;
-            if (!parent)
-            {
-                node->color = rbcolor::black;
-                tree.root_ = node;
-            }
-            else
-            {
-                if (tree.keys_comp(tree.get_key(node->value), parent->value))
-                    parent->add_left_child(node);
-                else if (tree.keys_comp(tree.get_key(parent->value), node->value))
-                    parent->add_right_child(node);
-                else
-                {
-                    parent->add(node); // List of nodes with equivalent keys.
-                    tree.update_root_(parent);
-
-                    return iterator{node, false};
-                }
-
-                tree.repair_after_insert_(node);
-                tree.update_root_(node);
-            }
-
-            return iterator{node, false};
-        }
-    };
-}
-
-#endif
-
Index: uspace/lib/cpp/include/__bits/regex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/regex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/regex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_REGEX
+#define LIBCPP_BITS_REGEX
+
+#error "<regex> is not implemented"
+
+#endif
Index: uspace/lib/cpp/include/__bits/result_of.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/result_of.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/result_of.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -30,4 +30,8 @@
 #define LIBCPP_BITS_RESULT_OF
 
+/**
+ * TODO: We have two implementations and I can't remember which
+ *       one is the correnct one, investigate!
+ */
 #include <__bits/invoke.hpp>
 
Index: uspace/lib/cpp/include/__bits/scoped_allocator.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/scoped_allocator.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/scoped_allocator.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_SCOPED_ALLOCATOR
+#define LIBCPP_BITS_SCOPED_ALLOCATOR
+
+#error "<scoped_allocator> is not implemented"
+
+#endif
Index: uspace/lib/cpp/include/__bits/stdexcept.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/stdexcept.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/stdexcept.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_STDEXCEPT
+#define LIBCPP_BITS_STDEXCEPT
+
+#include <__bits/string/stringfwd.hpp>
+#include <__bits/trycatch.hpp>
+#include <exception>
+#include <iosfwd>
+
+namespace std
+{
+    class logic_error: public exception
+    {
+        public:
+            explicit logic_error(const string&);
+            explicit logic_error(const char*);
+            logic_error(const logic_error&) noexcept;
+            logic_error& operator=(const logic_error&);
+            ~logic_error() override;
+
+            const char* what() const noexcept override;
+
+        protected:
+            const char* what_;
+    };
+
+    class domain_error: public logic_error
+    {
+        public:
+            explicit domain_error(const string&);
+            explicit domain_error(const char*);
+            domain_error(const domain_error&) noexcept;
+    };
+
+    class invalid_argument: public logic_error
+    {
+        public:
+            explicit invalid_argument(const string&);
+            explicit invalid_argument(const char*);
+            invalid_argument(const invalid_argument&) noexcept;
+    };
+
+    class length_error: public logic_error
+    {
+        public:
+            explicit length_error(const string&);
+            explicit length_error(const char*);
+            length_error(const length_error&) noexcept;
+    };
+
+    class out_of_range: public logic_error
+    {
+        public:
+            explicit out_of_range(const string&);
+            explicit out_of_range(const char*);
+            out_of_range(const out_of_range&) noexcept;
+    };
+
+    class runtime_error: public exception
+    {
+        public:
+            explicit runtime_error(const string&);
+            explicit runtime_error(const char*);
+            runtime_error(const runtime_error&) noexcept;
+            runtime_error& operator=(const runtime_error&);
+            ~runtime_error() override;
+
+            const char* what() const noexcept override;
+
+        protected:
+            const char* what_;
+    };
+
+    class range_error: public runtime_error
+    {
+        public:
+            explicit range_error(const string&);
+            explicit range_error(const char*);
+            range_error(const range_error&) noexcept;
+    };
+
+    class overflow_error: public runtime_error
+    {
+        public:
+            explicit overflow_error(const string&);
+            explicit overflow_error(const char*);
+            overflow_error(const overflow_error&) noexcept;
+    };
+
+    class underflow_error: public runtime_error
+    {
+        public:
+            explicit underflow_error(const string&);
+            explicit underflow_error(const char*);
+            underflow_error(const underflow_error&) noexcept;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/streambufs.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/streambufs.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,171 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_STREAMBUFS
-#define LIBCPP_STREAMBUFS
-
-#include <iosfwd>
-#include <cstdio>
-#include <streambuf>
-
-namespace std::aux
-{
-    template<class Char, class Traits = char_traits<Char>>
-    class stdin_streambuf : public basic_streambuf<Char, Traits>
-    {
-        public:
-            stdin_streambuf()
-                : basic_streambuf<Char, Traits>{}, buffer_{nullptr}
-            { /* DUMMY BODY */ }
-
-            virtual ~stdin_streambuf()
-            {
-                if (buffer_)
-                    delete[] buffer_;
-            }
-
-        protected:
-            using traits_type = Traits;
-            using char_type   = typename traits_type::char_type;
-            using int_type    = typename traits_type::int_type;
-            using off_type    = typename traits_type::off_type;
-
-            using basic_streambuf<Char, Traits>::input_begin_;
-            using basic_streambuf<Char, Traits>::input_next_;
-            using basic_streambuf<Char, Traits>::input_end_;
-
-            int_type underflow() override
-            {
-                if (!this->gptr())
-                {
-                    buffer_ = new char_type[buf_size_];
-                    input_begin_ = input_next_ = input_end_ = buffer_;
-                }
-
-                off_type i{};
-                if (input_next_ < input_end_)
-                {
-                    auto idx = static_cast<off_type>(input_next_ - input_begin_);
-                    auto count = buf_size_ - idx;
-
-                    for (; i < count; ++i, ++idx)
-                        buffer_[i] = buffer_[idx];
-                }
-
-                for (; i < buf_size_; ++i)
-                {
-                    auto c = fgetc(in_);
-                    putchar(c); // TODO: Temporary source of feedback.
-                    if (c == traits_type::eof())
-                        break;
-
-                    buffer_[i] = static_cast<char_type>(c);
-
-                    if (buffer_[i] == '\n')
-                    {
-                        ++i;
-                        break;
-                    }
-                }
-
-                input_next_ = input_begin_;
-                input_end_ = input_begin_ + i;
-
-                if (i == 0)
-                    return traits_type::eof();
-
-                return traits_type::to_int_type(*input_next_);
-            }
-
-            int_type uflow() override
-            {
-                auto res = underflow();
-                ++input_next_;
-
-                return res;
-            }
-
-            void imbue(const locale& loc)
-            {
-                this->locale_ = loc;
-            }
-
-        private:
-            FILE* in_{stdin};
-
-            char_type* buffer_;
-
-            static constexpr off_type buf_size_{128};
-    };
-
-    template<class Char, class Traits = char_traits<Char>>
-    class stdout_streambuf: public basic_streambuf<Char, Traits>
-    {
-        public:
-            stdout_streambuf()
-                : basic_streambuf<Char, Traits>{}
-            { /* DUMMY BODY */ }
-
-            virtual ~stdout_streambuf()
-            { /* DUMMY BODY */ }
-
-        protected:
-            using traits_type = Traits;
-            using char_type   = typename traits_type::char_type;
-            using int_type    = typename traits_type::int_type;
-            using off_type    = typename traits_type::off_type;
-
-            int_type overflow(int_type c = traits_type::eof()) override
-            {
-                if (!traits_type::eq_int_type(c, traits_type::eof()))
-                {
-                    auto cc = traits_type::to_char_type(c);
-                    fwrite(&cc, sizeof(char_type), 1, out_);
-                }
-
-                return traits_type::not_eof(c);
-            }
-
-            streamsize xsputn(const char_type* s, streamsize n) override
-            {
-                return fwrite(s, sizeof(char_type), n, out_);
-            }
-
-            int sync() override
-            {
-                if (fflush(out_))
-                    return -1;
-                return 0;
-            }
-
-        private:
-            FILE* out_{stdout};
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/string/string.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string/string.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/string/string.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1977 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_STRING
+#define LIBCPP_BITS_STRING
+
+#include <__bits/string/stringfwd.hpp>
+#include <algorithm>
+#include <initializer_list>
+#include <iosfwd>
+#include <iterator>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cwchar>
+#include <memory>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 21.2, char_traits:
+     */
+
+    template<class Char>
+    struct char_traits;
+
+    /**
+     * 21.2.3, char_traits specializations:
+     */
+
+    template<>
+    struct char_traits<char>
+    {
+        using char_type  = char;
+        using int_type   = int;
+        using off_type   = streamoff;
+        using pos_type   = streampos;
+        /* using state_type = mbstate_t; */
+
+        static void assign(char_type& c1, const char_type& c2) noexcept
+        {
+            c1 = c2;
+        }
+
+        static constexpr bool eq(char_type c1, char_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr bool lt(char_type c1, char_type c2) noexcept
+        {
+            return c1 < c2;
+        }
+
+        static int compare(const char_type* s1, const char_type* s2, size_t n)
+        {
+            return hel::str_lcmp(s1, s2, n);
+        }
+
+        static size_t length(const char_type* s)
+        {
+            return hel::str_size(s);
+        }
+
+        static const char_type* find(const char_type* s, size_t n, const char_type& c)
+        {
+            size_t i{};
+            while (i++ < n)
+            {
+                if (s[i] == c)
+                    return s + i;
+            }
+
+            return nullptr;
+        }
+
+        static char_type* move(char_type* s1, const char_type* s2, size_t n)
+        {
+            return static_cast<char_type*>(memmove(s1, s2, n));
+        }
+
+        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
+        {
+            return static_cast<char_type*>(memcpy(s1, s2, n));
+        }
+
+        static char_type* assign(char_type* s, size_t n, char_type c)
+        {
+            /**
+             * Note: Even though memset accepts int as its second argument,
+             *       the actual implementation assigns that int to a dereferenced
+             *       char pointer.
+             */
+            return static_cast<char_type*>(memset(s, static_cast<int>(c), n));
+        }
+
+        static constexpr int_type not_eof(int_type c) noexcept
+        {
+            if (!eq_int_type(c, eof()))
+                return c;
+            else
+                return to_int_type('a'); // We just need something that is not eof.
+        }
+
+        static constexpr char_type to_char_type(int_type c) noexcept
+        {
+            return static_cast<char_type>(c);
+        }
+
+        static constexpr int_type to_int_type(char_type c) noexcept
+        {
+            return static_cast<int_type>(c);
+        }
+
+        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr int_type eof() noexcept
+        {
+            return static_cast<int_type>(EOF);
+        }
+    };
+
+    template<>
+    struct char_traits<char16_t>
+    {
+        // TODO: implement
+        using char_type  = char16_t;
+        using int_type   = int16_t;
+        using off_type   = streamoff;
+        using pos_type   = streampos;
+        /* using state_type = mbstate_t; */
+
+        static void assign(char_type& c1, const char_type& c2) noexcept
+        {
+            c1 = c2;
+        }
+
+        static constexpr bool eq(char_type c1, char_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr bool lt(char_type c1, char_type c2) noexcept
+        {
+            return c1 < c2;
+        }
+
+        static int compare(const char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return 0;
+        }
+
+        static size_t length(const char_type* s)
+        {
+            // TODO: implement
+            return 0;
+        }
+
+        static const char_type* find(const char_type* s, size_t n, const char_type& c)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* move(char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* assign(char_type* s, size_t n, char_type c)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static constexpr int_type not_eof(int_type c) noexcept
+        {
+            // TODO: implement
+            return int_type{};
+        }
+
+        static constexpr char_type to_char_type(int_type c) noexcept
+        {
+            return static_cast<char_type>(c);
+        }
+
+        static constexpr int_type to_int_type(char_type c) noexcept
+        {
+            return static_cast<int_type>(c);
+        }
+
+        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr int_type eof() noexcept
+        {
+            return static_cast<int_type>(EOF);
+        }
+    };
+
+    template<>
+    struct char_traits<char32_t>
+    {
+        // TODO: implement
+        using char_type  = char32_t;
+        using int_type   = int32_t;
+        using off_type   = streamoff;
+        using pos_type   = streampos;
+        /* using state_type = mbstate_t; */
+
+        static void assign(char_type& c1, const char_type& c2) noexcept
+        {
+            c1 = c2;
+        }
+
+        static constexpr bool eq(char_type c1, char_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr bool lt(char_type c1, char_type c2) noexcept
+        {
+            return c1 < c2;
+        }
+
+        static int compare(const char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return 0;
+        }
+
+        static size_t length(const char_type* s)
+        {
+            // TODO: implement
+            return 0;
+        }
+
+        static const char_type* find(const char_type* s, size_t n, const char_type& c)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* move(char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static char_type* assign(char_type* s, size_t n, char_type c)
+        {
+            // TODO: implement
+            return nullptr;
+        }
+
+        static constexpr int_type not_eof(int_type c) noexcept
+        {
+            // TODO: implement
+            return int_type{};
+        }
+
+        static constexpr char_type to_char_type(int_type c) noexcept
+        {
+            return static_cast<char_type>(c);
+        }
+
+        static constexpr int_type to_int_type(char_type c) noexcept
+        {
+            return static_cast<int_type>(c);
+        }
+
+        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr int_type eof() noexcept
+        {
+            return static_cast<int_type>(EOF);
+        }
+    };
+
+    template<>
+    struct char_traits<wchar_t>
+    {
+        using char_type  = wchar_t;
+        using int_type   = wint_t;
+        using off_type   = streamoff;
+        using pos_type   = wstreampos;
+        /* using state_type = mbstate_t; */
+
+        static void assign(char_type& c1, const char_type& c2) noexcept
+        {
+            c1 = c2;
+        }
+
+        static constexpr bool eq(char_type c1, char_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr bool lt(char_type c1, char_type c2) noexcept
+        {
+            return c1 < c2;
+        }
+
+        static int compare(const char_type* s1, const char_type* s2, size_t n)
+        {
+            // TODO: This function does not exits...
+            //return hel::wstr_lcmp(s1, s2, n);
+            return 0;
+        }
+
+        static size_t length(const char_type* s)
+        {
+            return hel::wstr_size(s);
+        }
+
+        static const char_type* find(const char_type* s, size_t n, const char_type& c)
+        {
+            size_t i{};
+            while (i++ < n)
+            {
+                if (s[i] == c)
+                    return s + i;
+            }
+
+            return nullptr;
+        }
+
+        static char_type* move(char_type* s1, const char_type* s2, size_t n)
+        {
+            return static_cast<char_type*>(memmove(s1, s2, n * sizeof(wchar_t)));
+        }
+
+        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
+        {
+            return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(wchar_t)));
+        }
+
+        static char_type* assign(char_type* s, size_t n, char_type c)
+        {
+            return static_cast<char_type*>(memset(s, static_cast<int>(c), n * sizeof(wchar_t)));
+        }
+
+        static constexpr int_type not_eof(int_type c) noexcept
+        {
+            if (!eq_int_type(c, eof()))
+                return c;
+            else
+                return to_int_type(L'a'); // We just need something that is not eof.
+        }
+
+        static constexpr char_type to_char_type(int_type c) noexcept
+        {
+            return static_cast<char_type>(c);
+        }
+
+        static constexpr int_type to_int_type(char_type c) noexcept
+        {
+            return static_cast<int_type>(c);
+        }
+
+        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
+        {
+            return c1 == c2;
+        }
+
+        static constexpr int_type eof() noexcept
+        {
+            return static_cast<int_type>(EOF);
+        }
+    };
+
+    /**
+     * 21.4, class template basic_string:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    class basic_string
+    {
+        public:
+            using traits_type     = Traits;
+            using value_type      = typename traits_type::char_type;
+            using allocator_type  = Allocator;
+            using size_type       = typename allocator_traits<allocator_type>::size_type;
+            using difference_type = typename allocator_traits<allocator_type>::difference_type;
+
+            using reference       = value_type&;
+            using const_reference = const value_type&;
+            using pointer         = typename allocator_traits<allocator_type>::pointer;
+            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
+
+            using iterator               = pointer;
+            using const_iterator         = const_pointer;
+            using reverse_iterator       = std::reverse_iterator<iterator>;
+            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+            static constexpr size_type npos = -1;
+
+            /**
+             * 21.4.2, construct/copy/destroy:
+             * TODO: tagged constructor that moves the char*
+             *       and use that with asprintf in to_string
+             */
+
+            basic_string() noexcept
+                : basic_string(allocator_type{})
+            { /* DUMMY BODY */ }
+
+            explicit basic_string(const allocator_type& alloc)
+                : data_{}, size_{}, capacity_{}, allocator_{alloc}
+            {
+                /**
+                 * Postconditions:
+                 *  data() = non-null copyable value that can have 0 added to it.
+                 *  size() = 0
+                 *  capacity() = unspecified
+                 */
+                data_ = allocator_.allocate(default_capacity_);
+                capacity_ = default_capacity_;
+            }
+
+            basic_string(const basic_string& other)
+                : data_{}, size_{other.size_}, capacity_{other.capacity_},
+                  allocator_{other.allocator_}
+            {
+                init_(other.data(), size_);
+            }
+
+            basic_string(basic_string&& other)
+                : data_{other.data_}, size_{other.size_},
+                  capacity_{other.capacity_}, allocator_{move(other.allocator_)}
+            {
+                other.data_ = nullptr;
+                other.size_ = 0;
+                other.capacity_ = 0;
+            }
+
+            basic_string(const basic_string& other, size_type pos, size_type n = npos,
+                         const allocator_type& alloc = allocator_type{})
+                : data_{}, size_{}, capacity_{}, allocator_{alloc}
+            {
+                // TODO: if pos < other.size() throw out_of_range.
+                auto len = min(n, other.size() - pos);
+                init_(other.data() + pos, len);
+            }
+
+            basic_string(const value_type* str, size_type n, const allocator_type& alloc = allocator_type{})
+                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
+            {
+                init_(str, size_);
+            }
+
+            basic_string(const value_type* str, const allocator_type& alloc = allocator_type{})
+                : data_{}, size_{}, capacity_{}, allocator_{alloc}
+            {
+                init_(str, traits_type::length(str));
+            }
+
+            basic_string(size_type n, value_type c, const allocator_type& alloc = allocator_type{})
+                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
+            {
+                data_ = allocator_.allocate(capacity_);
+                for (size_type i = 0; i < size_; ++i)
+                    traits_type::assign(data_[i], c);
+                ensure_null_terminator_();
+            }
+
+            template<class InputIterator>
+            basic_string(InputIterator first, InputIterator last,
+                         const allocator_type& alloc = allocator_type{})
+                : data_{}, size_{}, capacity_{}, allocator_{alloc}
+            {
+                if constexpr (is_integral<InputIterator>::value)
+                { // Required by the standard.
+                    size_ = static_cast<size_type>(first);
+                    capacity_ = size_;
+                    data_ = allocator_.allocate(capacity_);
+
+                    for (size_type i = 0; i < size_; ++i)
+                        traits_type::assign(data_[i], static_cast<value_type>(last));
+                    ensure_null_terminator_();
+                }
+                else
+                {
+                    auto len = static_cast<size_type>(last - first);
+                    init_(first, len);
+                }
+            }
+
+            basic_string(initializer_list<value_type> init, const allocator_type& alloc = allocator_type{})
+                : basic_string{init.begin(), init.size(), alloc}
+            { /* DUMMY BODY */ }
+
+            basic_string(const basic_string& other, const allocator_type& alloc)
+                : data_{}, size_{other.size_}, capacity_{other.capacity_}, allocator_{alloc}
+            {
+                init_(other.data(), size_);
+            }
+
+            basic_string(basic_string&& other, const allocator_type& alloc)
+                : data_{other.data_}, size_{other.size_}, capacity_{other.capacity_}, allocator_{alloc}
+            {
+                other.data_ = nullptr;
+                other.size_ = 0;
+                other.capacity_ = 0;
+            }
+
+            ~basic_string()
+            {
+                allocator_.deallocate(data_, capacity_);
+            }
+
+            basic_string& operator=(const basic_string& other)
+            {
+                if (this != &other)
+                {
+                    basic_string tmp{other};
+                    swap(tmp);
+                }
+
+                return *this;
+            }
+
+            basic_string& operator=(basic_string&& other)
+                noexcept(allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
+                         allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                if (this != &other)
+                    swap(other);
+
+                return *this;
+            }
+
+            basic_string& operator=(const value_type* other)
+            {
+                *this = basic_string{other};
+
+                return *this;
+            }
+
+            basic_string& operator=(value_type c)
+            {
+                *this = basic_string{1, c};
+
+                return *this;
+            }
+
+            basic_string& operator=(initializer_list<value_type> init)
+            {
+                *this = basic_string{init};
+
+                return *this;
+            }
+
+            /**
+             * 21.4.3, iterators:
+             */
+
+            iterator begin() noexcept
+            {
+                return &data_[0];
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return &data_[0];
+            }
+
+            iterator end() noexcept
+            {
+                return begin() + size_;
+            }
+
+            const_iterator end() const noexcept
+            {
+                return begin() + size_;
+            }
+
+            reverse_iterator rbegin() noexcept
+            {
+                return make_reverse_iterator(end());
+            }
+
+            const_reverse_iterator rbegin() const noexcept
+            {
+                return make_reverse_iterator(cend());
+            }
+
+            reverse_iterator rend() noexcept
+            {
+                return make_reverse_iterator(begin());
+            }
+
+            const_reverse_iterator rend() const noexcept
+            {
+                return make_reverse_iterator(cbegin());
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return &data_[0];
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return cbegin() + size_;
+            }
+
+            const_reverse_iterator crbegin() const noexcept
+            {
+                return rbegin();
+            }
+
+            const_reverse_iterator crend() const noexcept
+            {
+                return rend();
+            }
+
+            /**
+             * 21.4.4, capacity:
+             */
+
+            size_type size() const noexcept
+            {
+                return size_;
+            }
+
+            size_type length() const noexcept
+            {
+                return size();
+            }
+
+            size_type max_size() const noexcept
+            {
+                return 0x7FFF; // TODO: just temporary
+                /* return allocator_traits<allocator_type>::max_size(allocator_); */
+            }
+
+            void resize(size_type new_size, value_type c)
+            {
+                // TODO: if new_size > max_size() throw length_error.
+                if (new_size > size_)
+                {
+                    ensure_free_space_(new_size - size_ + 1);
+                    for (size_type i = size_; i < new_size; ++i)
+                        traits_type::assign(data_[i], i);
+                }
+
+                size_ = new_size;
+                ensure_null_terminator_();
+            }
+
+            void resize(size_type new_size)
+            {
+                resize(new_size, value_type{});
+            }
+
+            size_type capacity() const noexcept
+            {
+                return capacity_;
+            }
+
+            void reserve(size_type new_capacity = 0)
+            {
+                // TODO: if new_capacity > max_size() throw
+                //       length_error (this function shall have no
+                //       effect in such case)
+                if (new_capacity > capacity_)
+                    resize_with_copy_(size_, new_capacity);
+                else if (new_capacity < capacity_)
+                    shrink_to_fit(); // Non-binding request, but why not.
+            }
+
+            void shrink_to_fit()
+            {
+                if (size_ != capacity_)
+                    resize_with_copy_(size_, capacity_);
+            }
+
+            void clear() noexcept
+            {
+                size_ = 0;
+            }
+
+            bool empty() const noexcept
+            {
+                return size_ == 0;
+            }
+
+            /**
+             * 21.4.5, element access:
+             */
+
+            const_reference operator[](size_type idx) const
+            {
+                return data_[idx];
+            }
+
+            reference operator[](size_type idx)
+            {
+                return data_[idx];
+            }
+
+            const_reference at(size_type idx) const
+            {
+                // TODO: bounds checking
+                return data_[idx];
+            }
+
+            reference at(size_type idx)
+            {
+                // TODO: bounds checking
+                return data_[idx];
+            }
+
+            const_reference front() const
+            {
+                return at(0);
+            }
+
+            reference front()
+            {
+                return at(0);
+            }
+
+            const_reference back() const
+            {
+                return at(size_ - 1);
+            }
+
+            reference back()
+            {
+                return at(size_ - 1);
+            }
+
+            /**
+             * 21.4.6, modifiers:
+             */
+
+            basic_string& operator+=(const basic_string& str)
+            {
+                return append(str);
+            }
+
+            basic_string& operator+=(const value_type* str)
+            {
+                return append(str);
+            }
+
+            basic_string& operator+=(value_type c)
+            {
+                push_back(c);
+                return *this;
+            }
+
+            basic_string& operator+=(initializer_list<value_type> init)
+            {
+                return append(init.begin(), init.size());
+            }
+
+            basic_string& append(const basic_string& str)
+            {
+                return append(str.data(), str.size());
+            }
+
+            basic_string& append(const basic_string& str, size_type pos,
+                                 size_type n = npos)
+            {
+                if (pos < str.size())
+                {
+                    auto len = min(n, str.size() - pos);
+
+                    return append(str.data() + pos, len);
+                }
+                // TODO: Else throw out_of_range.
+            }
+
+            basic_string& append(const value_type* str, size_type n)
+            {
+                // TODO: if (size_ + n > max_size()) throw length_error
+                ensure_free_space_(n);
+                traits_type::copy(data_ + size(), str, n);
+                size_ += n;
+                ensure_null_terminator_();
+
+                return *this;
+            }
+
+            basic_string& append(const value_type* str)
+            {
+                return append(str, traits_type::length(str));
+            }
+
+            basic_string& append(size_type n, value_type c)
+            {
+                return append(basic_string(n, c));
+            }
+
+            template<class InputIterator>
+            basic_string& append(InputIterator first, InputIterator last)
+            {
+                return append(basic_string(first, last));
+            }
+
+            basic_string& append(initializer_list<value_type> init)
+            {
+                return append(init.begin(), init.size());
+            }
+
+            void push_back(value_type c)
+            {
+                ensure_free_space_(1);
+                traits_type::assign(data_[size_++], c);
+                ensure_null_terminator_();
+            }
+
+            basic_string& assign(const basic_string& str)
+            {
+                return assign(str, 0, npos);
+            }
+
+            basic_string& assign(basic_string&& str)
+            {
+                swap(str);
+
+                return *this;
+            }
+
+            basic_string& assign(const basic_string& str, size_type pos,
+                                 size_type n = npos)
+            {
+                if (pos < str.size())
+                {
+                    auto len = min(n, str.size() - pos);
+                    ensure_free_space_(len);
+
+                    return assign(str.data() + pos, len);
+                }
+                // TODO: Else throw out_of_range.
+
+                return *this;
+            }
+
+            basic_string& assign(const value_type* str, size_type n)
+            {
+                // TODO: if (n > max_size()) throw length_error.
+                resize_without_copy_(n);
+                traits_type::copy(begin(), str, n);
+                size_ = n;
+                ensure_null_terminator_();
+
+                return *this;
+            }
+
+            basic_string& assign(const value_type* str)
+            {
+                return assign(str, traits_type::length(str));
+            }
+
+            basic_string& assign(size_type n, value_type c)
+            {
+                return assign(basic_string(n, c));
+            }
+
+            template<class InputIterator>
+            basic_string& assign(InputIterator first, InputIterator last)
+            {
+                return assign(basic_string(first, last));
+            }
+
+            basic_string& assign(initializer_list<value_type> init)
+            {
+                return assign(init.begin(), init.size());
+            }
+
+            basic_string& insert(size_type pos, const basic_string& str)
+            {
+                // TODO: if (pos > str.size()) throw out_of_range.
+                return insert(pos, str.data(), str.size());
+            }
+
+            basic_string& insert(size_type pos1, const basic_string& str,
+                                 size_type pos2, size_type n = npos)
+            {
+                // TODO: if (pos1 > size() or pos2 > str.size()) throw
+                //       out_of_range.
+                auto len = min(n, str.size() - pos2);
+
+                return insert(pos1, str.data() + pos2, len);
+            }
+
+            basic_string& insert(size_type pos, const value_type* str, size_type n)
+            {
+                // TODO: throw out_of_range if pos > size()
+                // TODO: throw length_error if size() + n > max_size()
+                ensure_free_space_(n);
+
+                copy_backward_(begin() + pos, end(), end() + n);
+                copy_(str, str + n, begin() + pos);
+                size_ += n;
+
+                ensure_null_terminator_();
+                return *this;
+            }
+
+            basic_string& insert(size_type pos, const value_type* str)
+            {
+                return insert(pos, str, traits_type::length(str));
+            }
+
+            basic_string& insert(size_type pos, size_type n, value_type c)
+            {
+                return insert(pos, basic_string(n, c));
+            }
+
+            iterator insert(const_iterator pos, value_type c)
+            {
+                auto idx = static_cast<size_type>(pos - begin());
+
+                ensure_free_space_(1);
+                copy_backward_(begin() + idx, end(), end() + 1);
+                traits_type::assign(data_[idx], c);
+
+                ++size_;
+                ensure_null_terminator_();
+
+                return begin() + idx;
+            }
+
+            iterator insert(const_iterator pos, size_type n, value_type c)
+            {
+                if (n == 0)
+                    return const_cast<iterator>(pos);
+
+                auto idx = static_cast<size_type>(pos - begin());
+
+                ensure_free_space_(n);
+                copy_backward_(begin() + idx, end(), end() + n);
+
+                auto it = begin() + idx;
+                for (size_type i = 0; i < n; ++i)
+                    traits_type::assign(*it++, c);
+                size_ += n;
+                ensure_null_terminator_();
+
+                return begin() + idx;
+            }
+
+            template<class InputIterator>
+            iterator insert(const_iterator pos, InputIterator first,
+                            InputIterator last)
+            {
+                if (first == last)
+                    return const_cast<iterator>(pos);
+
+                auto idx = static_cast<size_type>(pos - begin());
+                auto str = basic_string{first, last};
+                insert(idx, str);
+
+                return begin() + idx;
+            }
+
+            iterator insert(const_iterator pos, initializer_list<value_type> init)
+            {
+                return insert(pos, init.begin(), init.end());
+            }
+
+            basic_string& erase(size_type pos = 0, size_type n = npos)
+            {
+                auto len = min(n, size_ - pos);
+                copy_(begin() + pos + n, end(), begin() + pos);
+                size_ -= len;
+                ensure_null_terminator_();
+
+                return *this;
+            }
+
+            iterator erase(const_iterator pos)
+            {
+                auto idx = static_cast<size_type>(pos - cbegin());
+                erase(idx, 1);
+
+                return begin() + idx;
+            }
+
+            iterator erase(const_iterator first, const_iterator last)
+            {
+                auto idx = static_cast<size_type>(first - cbegin());
+                auto count = static_cast<size_type>(last - first);
+                erase(idx, count);
+
+                return begin() + idx;
+            }
+
+            void pop_back()
+            {
+                --size_;
+                ensure_null_terminator_();
+            }
+
+            basic_string& replace(size_type pos, size_type n, const basic_string& str)
+            {
+                // TODO: throw out_of_range if pos > size()
+                return replace(pos, n, str.data(), str.size());
+            }
+
+            basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
+                                  size_type pos2, size_type n2 = npos)
+            {
+                // TODO: throw out_of_range if pos1 > size() or pos2 > str.size()
+                auto len = min(n2, str.size() - pos2);
+                return replace(pos1, n1, str.data() + pos2, len);
+            }
+
+            basic_string& replace(size_type pos, size_type n1, const value_type* str,
+                                  size_type n2)
+            {
+                // TODO: throw out_of_range if pos > size()
+                // TODO: if size() - len > max_size() - n2 throw length_error
+                auto len = min(n1, size_ - pos);
+
+                basic_string tmp{};
+                tmp.resize_without_copy_(size_ - len + n2);
+
+                // Prefix.
+                copy_(begin(), begin() + pos, tmp.begin());
+
+                // Substitution.
+                traits_type::copy(tmp.begin() + pos, str, n2);
+
+                // Suffix.
+                copy_(begin() + pos + len, end(), tmp.begin() + pos + n2);
+
+                tmp.size_ = size_ - len + n2;
+                swap(tmp);
+                return *this;
+            }
+
+            basic_string& replace(size_type pos, size_type n, const value_type* str)
+            {
+                return replace(pos, n, str, traits_type::length(str));
+            }
+
+            basic_string& replace(size_type pos, size_type n1, size_type n2,
+                                  value_type c)
+            {
+                return replace(pos, n1, basic_string(n2, c));
+            }
+
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  const basic_string& str)
+            {
+                return replace(i1 - begin(), i2 - i1, str);
+            }
+
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  const value_type* str, size_type n)
+            {
+                return replace(i1 - begin(), i2 - i1, str, n);
+            }
+
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  const value_type* str)
+            {
+                return replace(i1 - begin(), i2 - i1, str, traits_type::length(str));
+            }
+
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  size_type n, value_type c)
+            {
+                return replace(i1 - begin(), i2 - i1, basic_string(n, c));
+            }
+
+            template<class InputIterator>
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  InputIterator j1, InputIterator j2)
+            {
+                return replace(i1 - begin(), i2 - i1, basic_string(j1, j2));
+            }
+
+            basic_string& replace(const_iterator i1, const_iterator i2,
+                                  initializer_list<value_type> init)
+            {
+                return replace(i1 - begin(), i2 - i1, init.begin(), init.size());
+            }
+
+            size_type copy(value_type* str, size_type n, size_type pos = 0) const
+            {
+                auto len = min(n , size_ - pos);
+                for (size_type i = 0; i < len; ++i)
+                    traits_type::assign(str[i], data_[pos + i]);
+
+                return len;
+            }
+
+            void swap(basic_string& other)
+                noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+                         allocator_traits<allocator_type>::is_always_equal::value)
+            {
+                std::swap(data_, other.data_);
+                std::swap(size_, other.size_);
+                std::swap(capacity_, other.capacity_);
+            }
+
+            /**
+             * 21.4.7, string operations:
+             */
+
+            const value_type* c_str() const noexcept
+            {
+                return data_;
+            }
+
+            const value_type* data() const noexcept
+            {
+                return data_;
+            }
+
+            allocator_type get_allocator() const noexcept
+            {
+                return allocator_type{allocator_};
+            }
+
+            /**
+             * Note: The following find functions have 4 versions each:
+             *       (1) takes basic_string
+             *       (2) takes c string and length
+             *       (3) takes c string
+             *       (4) takes value_type
+             *       According to the C++14 standard, only (1) is marked as
+             *       noexcept and the other three return the first one with
+             *       a newly allocated strings (and thus cannot be noexcept).
+             *       However, allocating a new string results in memory
+             *       allocation and copying of the source and thus we have
+             *       decided to follow C++17 signatures of these functions
+             *       (i.e. all of them being marked as noexcept) and use
+             *       (2) for the actual implementation (and avoiding any
+             *       allocations or copying in the process and also providing
+             *       stronger guarantees to the user).
+             */
+
+            size_type find(const basic_string& str, size_type pos = 0) const noexcept
+            {
+                return find(str.c_str(), pos, str.size());
+            }
+
+            size_type find(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty() || len == 0 || len + pos > size())
+                    return npos;
+
+                size_type idx{pos};
+
+                while (idx + len < size_)
+                {
+                    if (substr_starts_at_(idx, str, len))
+                        return idx;
+                    ++idx;
+                }
+
+                return npos;
+            }
+
+            size_type find(const value_type* str, size_type pos = 0) const noexcept
+            {
+                return find(str, pos, traits_type::length(str));
+            }
+
+            size_type find(value_type c, size_type pos = 0) const noexcept
+            {
+                if (empty())
+                    return npos;
+
+                for (size_type i = pos; i < size_; ++i)
+                {
+                    if (traits_type::eq(c, data_[i]))
+                        return i;
+                }
+
+                return npos;
+            }
+
+            size_type rfind(const basic_string& str, size_type pos = npos) const noexcept
+            {
+                return rfind(str.c_str(), pos, str.size());
+            }
+
+            size_type rfind(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty() || len == 0 || len + pos > size())
+                    return npos;
+
+                size_type idx{min(pos, size_ - 1) + 1};
+
+                while (idx > 0)
+                {
+                    if (substr_starts_at_(idx - 1, str, len))
+                        return idx - 1;
+                    --idx;
+                }
+
+                return npos;
+            }
+
+            size_type rfind(const value_type* str, size_type pos = npos) const noexcept
+            {
+                return rfind(str, pos, traits_type::length(str));
+            }
+
+            size_type rfind(value_type c, size_type pos = npos) const noexcept
+            {
+                if (empty())
+                    return npos;
+
+                for (size_type i = min(pos + 1, size_ - 1) + 1; i > 0; --i)
+                {
+                    if (traits_type::eq(c, data_[i - 1]))
+                        return i - 1;
+                }
+
+                return npos;
+            }
+
+            size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept
+            {
+                return find_first_of(str.c_str(), pos, str.size());
+            }
+
+            size_type find_first_of(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty() || len == 0 || pos >= size())
+                    return npos;
+
+                size_type idx{pos};
+
+                while (idx < size_)
+                {
+                    if (is_any_of_(idx, str, len))
+                        return idx;
+                    ++idx;
+                }
+
+                return npos;
+            }
+
+            size_type find_first_of(const value_type* str, size_type pos = 0) const noexcept
+            {
+                return find_first_of(str, pos, traits_type::length(str));
+            }
+
+            size_type find_first_of(value_type c, size_type pos = 0) const noexcept
+            {
+                return find(c, pos);
+            }
+
+            size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept
+            {
+                return find_last_of(str.c_str(), pos, str.size());
+            }
+
+            size_type find_last_of(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty() || len == 0)
+                    return npos;
+
+                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
+                {
+                    if (is_any_of_(i - 1, str, len))
+                        return i - 1;
+                }
+
+                return npos;
+            }
+
+            size_type find_last_of(const value_type* str, size_type pos = npos) const noexcept
+            {
+                return find_last_of(str, pos, traits_type::length(str));
+            }
+
+            size_type find_last_of(value_type c, size_type pos = npos) const noexcept
+            {
+                return rfind(c, pos);
+            }
+
+            size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept
+            {
+                return find_first_not_of(str.c_str(), pos, str.size());
+            }
+
+            size_type find_first_not_of(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty() || pos >= size())
+                    return npos;
+
+                size_type idx{pos};
+
+                while (idx < size_)
+                {
+                    if (!is_any_of_(idx, str, len))
+                        return idx;
+                    ++idx;
+                }
+
+                return npos;
+            }
+
+            size_type find_first_not_of(const value_type* str, size_type pos = 0) const noexcept
+            {
+                return find_first_not_of(str, pos, traits_type::length(str));
+            }
+
+            size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept
+            {
+                if (empty())
+                    return npos;
+
+                for (size_type i = pos; i < size_; ++i)
+                {
+                    if (!traits_type::eq(c, data_[i]))
+                        return i;
+                }
+
+                return npos;
+            }
+
+            size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept
+            {
+                return find_last_not_of(str.c_str(), pos, str.size());
+            }
+
+            size_type find_last_not_of(const value_type* str, size_type pos, size_type len) const noexcept
+            {
+                if (empty())
+                    return npos;
+
+                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
+                {
+                    if (!is_any_of_(i - 1, str, len))
+                        return i - 1;
+                }
+
+                return npos;
+            }
+
+            size_type find_last_not_of(const value_type* str, size_type pos = npos) const noexcept
+            {
+                return find_last_not_of(str, pos, traits_type::length(str));
+            }
+
+            size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept
+            {
+                if (empty())
+                    return npos;
+
+                pos = min(pos, size_ - 1);
+
+                for (size_type i = min(pos, size_ - 1) + 1; i > 1; --i)
+                {
+                    if (!traits_type::eq(c, data_[i - 1]))
+                        return i - 1;
+                }
+
+                return npos;
+            }
+
+            basic_string substr(size_type pos = 0, size_type n = npos) const
+            {
+                // TODO: throw out_of_range if pos > size().
+                auto len = min(n, size_ - pos);
+                return basic_string{data() + pos, len};
+            }
+
+            int compare(const basic_string& other) const noexcept
+            {
+                auto len = min(size(), other.size());
+                auto comp = traits_type::compare(data_, other.data(), len);
+
+                if (comp != 0)
+                    return comp;
+                else if (size() == other.size())
+                    return 0;
+                else if (size() > other.size())
+                    return 1;
+                else
+                    return -1;
+            }
+
+            int compare(size_type pos, size_type n, const basic_string& other) const
+            {
+                return basic_string{*this, pos, n}.compare(other);
+            }
+
+            int compare(size_type pos1, size_type n1, const basic_string& other,
+                        size_type pos2, size_type n2 = npos) const
+            {
+                return basic_string{*this, pos1, n1}.compare(basic_string{other, pos2, n2});
+            }
+
+            int compare(const value_type* other) const
+            {
+                return compare(basic_string(other));
+            }
+
+            int compare(size_type pos, size_type n, const value_type* other) const
+            {
+                return basic_string{*this, pos, n}.compare(basic_string{other});
+            }
+
+            int compare(size_type pos, size_type n1,
+                        const value_type* other, size_type n2) const
+            {
+                return basic_string{*this, pos, n1}.compare(basic_string{other, n2});
+            }
+
+        private:
+            value_type* data_;
+            size_type size_;
+            size_type capacity_;
+            allocator_type allocator_;
+
+            template<class C, class T, class A>
+            friend class basic_stringbuf;
+
+            /**
+             * Arbitrary value, standard just requires
+             * data() to have some capacity.
+             * (Well, we could've done data_ = &data_ and
+             * set capacity to 0, but that would be too cryptic.)
+             */
+            static constexpr size_type default_capacity_{4};
+
+            void init_(const value_type* str, size_type size)
+            {
+                if (data_)
+                    allocator_.deallocate(data_, capacity_);
+
+                size_ = size;
+                capacity_ = size + 1;
+
+                data_ = allocator_.allocate(capacity_);
+                traits_type::copy(data_, str, size);
+                ensure_null_terminator_();
+            }
+
+            size_type next_capacity_(size_type hint = 0) const noexcept
+            {
+                if (hint != 0)
+                    return max(capacity_ * 2, hint);
+                else
+                    return max(capacity_ * 2, 2ul);
+            }
+
+            void ensure_free_space_(size_type n)
+            {
+                /**
+                 * Note: We cannot use reserve like we
+                 *       did in vector, because in string
+                 *       reserve can cause shrinking.
+                 */
+                if (size_ + 1 + n > capacity_)
+                    resize_with_copy_(size_, max(size_ + 1 + n, next_capacity_()));
+            }
+
+            void resize_without_copy_(size_type capacity)
+            {
+                if (data_)
+                    allocator_.deallocate(data_, capacity_);
+
+                data_ = allocator_.allocate(capacity);
+                size_ = 0;
+                capacity_ = capacity;
+                ensure_null_terminator_();
+            }
+
+            void resize_with_copy_(size_type size, size_type capacity)
+            {
+                if(capacity_ == 0 || capacity_ < capacity)
+                {
+                    auto new_data = allocator_.allocate(capacity);
+
+                    auto to_copy = min(size, size_);
+                    traits_type::move(new_data, data_, to_copy);
+
+                    std::swap(data_, new_data);
+
+                    allocator_.deallocate(new_data, capacity_);
+                }
+
+                capacity_ = capacity;
+                size_ = size;
+                ensure_null_terminator_();
+            }
+
+            template<class Iterator1, class Iterator2>
+            Iterator2 copy_(Iterator1 first, Iterator1 last,
+                            Iterator2 result)
+            {
+                while (first != last)
+                    traits_type::assign(*result++, *first++);
+
+                return result;
+            }
+
+            template<class Iterator1, class Iterator2>
+            Iterator2 copy_backward_(Iterator1 first, Iterator1 last,
+                                     Iterator2 result)
+            {
+                while (last != first)
+                    traits_type::assign(*--result, *--last);
+
+                return result;
+            }
+
+            void ensure_null_terminator_()
+            {
+                value_type c{};
+                traits_type::assign(data_[size_], c);
+            }
+
+            bool is_any_of_(size_type idx, const value_type* str, size_type len) const
+            {
+                for (size_type i = 0; i < len; ++i)
+                {
+                    if (traits_type::eq(data_[idx], str[i]))
+                        return true;
+                }
+
+                return false;
+            }
+
+            bool substr_starts_at_(size_type idx, const value_type* str, size_type len) const
+            {
+                size_type i{};
+                for (i = 0; i < len; ++i)
+                {
+                    if (!traits_type::eq(data_[idx + i], str[i]))
+                        break;
+                }
+
+                return i == len;
+            }
+    };
+
+    using string    = basic_string<char>;
+    using u16string = basic_string<char16_t>;
+    using u32string = basic_string<char32_t>;
+    using wstring   = basic_string<wchar_t>;
+
+    /**
+     * 21.4.8, basic_string non-member functions:
+     */
+
+    /**
+     * 21.4.8.1, operator+:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const basic_string<Char, Traits, Allocator>& lhs,
+              const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return basic_string<Char, Traits, Allocator>{lhs}.append(rhs);
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(basic_string<Char, Traits, Allocator>&& lhs,
+              const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return move(lhs.append(rhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const basic_string<Char, Traits, Allocator>& lhs,
+              basic_string<Char, Traits, Allocator>&& rhs)
+    {
+        return move(rhs.insert(0, lhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(basic_string<Char, Traits, Allocator>&& lhs,
+              basic_string<Char, Traits, Allocator>&& rhs)
+    {
+        return move(lhs.append(rhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const Char* lhs,
+              const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return basic_string<Char, Traits, Allocator>{lhs} + rhs;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const Char* lhs,
+              basic_string<Char, Traits, Allocator>&& rhs)
+    {
+        return move(rhs.insert(0, lhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(Char lhs,
+              const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return basic_string<Char, Traits, Allocator>{1, lhs}.append(rhs);
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(Char lhs,
+              basic_string<Char, Traits, Allocator>&& rhs)
+    {
+        return move(rhs.insert(0, 1, lhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const basic_string<Char, Traits, Allocator>& lhs,
+              const Char* rhs)
+    {
+        return lhs + basic_string<Char, Traits, Allocator>{rhs};
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(basic_string<Char, Traits, Allocator>&& lhs,
+              const Char* rhs)
+    {
+        return move(lhs.append(rhs));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(const basic_string<Char, Traits, Allocator>& lhs,
+              Char rhs)
+    {
+        return lhs + basic_string<Char, Traits, Allocator>{1, rhs};
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_string<Char, Traits, Allocator>
+    operator+(basic_string<Char, Traits, Allocator>&& lhs,
+              Char rhs)
+    {
+        return move(lhs.append(1, rhs));
+    }
+
+    /**
+     * 21.4.8.2, operator==:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator==(const basic_string<Char, Traits, Allocator>& lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return lhs.compare(rhs) == 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator==(const Char* lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs == lhs;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator==(const basic_string<Char, Traits, Allocator>& lhs,
+                    const Char* rhs)
+    {
+        return lhs.compare(rhs) == 0;
+    }
+
+    /**
+     * 21.4.8.3, operator!=:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator!=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator!=(const Char* lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs != lhs;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator!=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const Char* rhs)
+    {
+        return lhs.compare(rhs) != 0;
+    }
+
+    /**
+     * 21.4.8.4, operator<:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<(const basic_string<Char, Traits, Allocator>& lhs,
+                   const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return lhs.compare(rhs) < 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<(const Char* lhs,
+                   const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs.compare(lhs) > 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<(const basic_string<Char, Traits, Allocator>& lhs,
+                   const Char* rhs)
+    {
+        return lhs.compare(rhs) < 0;
+    }
+
+    /**
+     * 21.4.8.5, operator>:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>(const basic_string<Char, Traits, Allocator>& lhs,
+                   const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return lhs.compare(rhs) > 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>(const Char* lhs,
+                   const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs.compare(lhs) < 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>(const basic_string<Char, Traits, Allocator>& lhs,
+                   const Char* rhs)
+    {
+        return lhs.compare(rhs) > 0;
+    }
+
+    /**
+     * 21.4.8.6, operator<=:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return lhs.compare(rhs) <= 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<=(const Char* lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs.compare(lhs) >= 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator<=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const Char* rhs)
+    {
+        return lhs.compare(rhs) <= 0;
+    }
+
+    /**
+     * 21.4.8.7, operator>=:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
+    {
+        return lhs.compare(rhs) >= 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>=(const Char* lhs,
+                    const basic_string<Char, Traits, Allocator>& rhs)
+    {
+        return rhs.compare(lhs) <= 0;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    bool operator>=(const basic_string<Char, Traits, Allocator>& lhs,
+                    const Char* rhs)
+    {
+        return lhs.compare(rhs) >= 0;
+    }
+
+    /**
+     * 21.4.8.8, swap:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    void swap(basic_string<Char, Traits, Allocator>& lhs,
+              basic_string<Char, Traits, Allocator>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    /**
+     * 21.5, numeric conversions:
+     */
+
+    int stoi(const string& str, size_t* idx = nullptr, int base = 10);
+    long stol(const string& str, size_t* idx = nullptr, int base = 10);
+    unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10);
+    long long stoll(const string& str, size_t* idx = nullptr, int base = 10);
+    unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
+
+    float stof(const string& str, size_t* idx = nullptr);
+    double stod(const string& str, size_t* idx = nullptr);
+    long double stold(const string& str, size_t* idx = nullptr);
+
+    string to_string(int val);
+    string to_string(unsigned val);
+    string to_string(long val);
+    string to_string(unsigned long val);
+    string to_string(long long val);
+    string to_string(unsigned long long val);
+    string to_string(float val);
+    string to_string(double val);
+    string to_string(long double val);
+
+    int stoi(const wstring& str, size_t* idx = nullptr, int base = 10);
+    long stol(const wstring& str, size_t* idx = nullptr, int base = 10);
+    unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10);
+    long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10);
+    unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
+
+    float stof(const wstring& str, size_t* idx = nullptr);
+    double stod(const wstring& str, size_t* idx = nullptr);
+    long double stold(const wstring& str, size_t* idx = nullptr);
+
+    wstring to_wstring(int val);
+    wstring to_wstring(unsigned val);
+    wstring to_wstring(long val);
+    wstring to_wstring(unsigned long val);
+    wstring to_wstring(long long val);
+    wstring to_wstring(unsigned long long val);
+    wstring to_wstring(float val);
+    wstring to_wstring(double val);
+    wstring to_wstring(long double val);
+
+    /**
+     * 21.6, hash support:
+     */
+
+    template<class>
+    struct hash;
+
+    template<>
+    struct hash<string>
+    {
+        size_t operator()(const string& str) const noexcept
+        {
+            size_t res{};
+
+            /**
+             * Note: No need for fancy algorithms here,
+             *       std::hash is used for indexing, not
+             *       cryptography.
+             */
+            for (const auto& c: str)
+                res = res * 5 + (res >> 3) + static_cast<size_t>(c);
+
+            return res;
+        }
+
+        using argument_type = string;
+        using result_type   = size_t;
+    };
+
+    template<>
+    struct hash<wstring>
+    {
+        size_t operator()(const wstring& str) const noexcept
+        {
+            // TODO: implement
+            return size_t{};
+        }
+
+        using argument_type = wstring;
+        using result_type   = size_t;
+    };
+
+    // TODO: add those other 2 string types
+
+    /**
+     * 21.7, suffix for basic_string literals:
+     */
+
+    /**
+     * Note: According to the standard, literal suffixes that do not
+     *       start with an underscore are reserved for future standardization,
+     *       but since we are implementing the standard, we're going to ignore it.
+     *       This should work (according to their documentation) work for clang,
+     *       but that should be tested.
+     */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wliteral-suffix"
+inline namespace literals {
+inline namespace string_literals
+{
+    string operator "" s(const char* str, size_t len);
+    u16string operator "" s(const char16_t* str, size_t len);
+    u32string operator "" s(const char32_t* str, size_t len);
+
+    /* Problem: wchar_t == int in HelenOS, but standard forbids it.
+    wstring operator "" s(const wchar_t* str, size_t len);
+    */
+}}
+#pragma GCC diagnostic pop
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/string/string_io.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string/string_io.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/string/string_io.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_STRING_IO
+#define LIBCPP_BITS_STRING_IO
+
+#include <__bits/string/string.hpp>
+#include <ios>
+
+namespace std
+{
+    /**
+     * 21.4.8.9, inserters and extractors:
+     */
+
+    template<class Char, class Traits, class Allocator>
+    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
+                                            basic_string<Char, Traits, Allocator>& str)
+    {
+        using sentry = typename basic_istream<Char, Traits>::sentry;
+        sentry sen{is, false};
+
+        if (sen)
+        {
+            str.erase();
+
+            auto max_size = is.width();
+            if (max_size <= 0)
+                max_size = static_cast<streamsize>(str.max_size());
+
+            streamsize i{};
+            for(; i < max_size; ++i)
+            {
+                auto ic = is.rdbuf()->sgetc();
+                if (Traits::eq_int_type(ic, Traits::eof()))
+                {
+                    is.setstate(ios_base::eofbit);
+                    break;
+                }
+
+                auto c = Traits::to_char_type(ic);
+                if(isspace(c, is.getloc()))
+                    break;
+
+                str.push_back(c);
+                is.rdbuf()->sbumpc();
+            }
+
+            if (i == 0)
+                is.setstate(ios_base::failbit);
+        }
+        else
+            is.setstate(ios_base::failbit);
+
+        return is;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            const basic_string<Char, Traits, Allocator>& str)
+    {
+        // TODO: determine padding as described in 27.7.3.6.1
+        using sentry = typename basic_ostream<Char, Traits>::sentry;
+        sentry sen{os};
+
+        if (sen)
+        {
+            auto width = os.width();
+            auto size = str.size();
+
+            size_t to_pad{};
+            if (width > 0)
+                to_pad = (static_cast<size_t>(width) - size);
+
+            if (to_pad > 0)
+            {
+                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
+                {
+                    for (std::size_t i = 0; i < to_pad; ++i)
+                        os.put(os.fill());
+                }
+
+                os.rdbuf()->sputn(str.data(), size);
+
+                if ((os.flags() & ios_base::adjustfield) == ios_base::left)
+                {
+                    for (std::size_t i = 0; i < to_pad; ++i)
+                        os.put(os.fill());
+                }
+            }
+            else
+                os.rdbuf()->sputn(str.data(), size);
+
+            os.width(0);
+        }
+
+        return os;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
+                                         basic_string<Char, Traits, Allocator>& str,
+                                         Char delim)
+    {
+        typename basic_istream<Char, Traits>::sentry sen{is, true};
+
+        if (sen)
+        {
+            str.clear();
+            streamsize count{};
+
+            while (true)
+            {
+                auto ic = is.rdbuf()->sbumpc();
+                if (Traits::eq_int_type(ic, Traits::eof()))
+                {
+                    is.setstate(ios_base::eofbit);
+                    break;
+                }
+
+                auto c = Traits::to_char_type(ic);
+                if (Traits::eq(c, delim))
+                    break;
+
+                str.push_back(c);
+                ++count;
+
+                if (count >= static_cast<streamsize>(str.max_size()))
+                {
+                    is.setstate(ios_base::failbit);
+                    break;
+                }
+            }
+
+            if (count == 0)
+                is.setstate(ios_base::failbit);
+        }
+        else
+            is.setstate(ios_base::failbit);
+
+        return is;
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
+                                         basic_string<Char, Traits, Allocator>& str,
+                                         Char delim)
+    {
+        return getline(is, str, delim);
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
+                                         basic_string<Char, Traits, Allocator>& str)
+    {
+        return getline(is, str, is.widen('\n'));
+    }
+
+    template<class Char, class Traits, class Allocator>
+    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
+                                         basic_string<Char, Traits, Allocator>& str)
+    {
+        return getline(is, str, is.widen('\n'));
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/string/stringfwd.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string/stringfwd.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/string/stringfwd.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_STRING_STRINGFWD
+#define LIBCPP_BITS_STRING_STRINGFWD
+
+namespace std
+{
+    template<class Char>
+    struct char_traits;
+
+    template<class T>
+    struct allocator;
+
+    template<
+        class Char,
+        class Traits = char_traits<Char>,
+        class Allocator = allocator<Char>
+    >
+    class basic_string;
+
+    using string  = basic_string<char>;
+    using wstring = basic_string<wchar_t>;
+
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/string_io.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string_io.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,192 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_STRING_IO
-#define LIBCPP_BITS_STRING_IO
-
-#include <ios>
-#include <string>
-
-namespace std
-{
-    /**
-     * 21.4.8.9, inserters and extractors:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            basic_string<Char, Traits, Allocator>& str)
-    {
-        using sentry = typename basic_istream<Char, Traits>::sentry;
-        sentry sen{is, false};
-
-        if (sen)
-        {
-            str.erase();
-
-            auto max_size = is.width();
-            if (max_size <= 0)
-                max_size = static_cast<streamsize>(str.max_size());
-
-            streamsize i{};
-            for(; i < max_size; ++i)
-            {
-                auto ic = is.rdbuf()->sgetc();
-                if (Traits::eq_int_type(ic, Traits::eof()))
-                {
-                    is.setstate(ios_base::eofbit);
-                    break;
-                }
-
-                auto c = Traits::to_char_type(ic);
-                if(isspace(c, is.getloc()))
-                    break;
-
-                str.push_back(c);
-                is.rdbuf()->sbumpc();
-            }
-
-            if (i == 0)
-                is.setstate(ios_base::failbit);
-        }
-        else
-            is.setstate(ios_base::failbit);
-
-        return is;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const basic_string<Char, Traits, Allocator>& str)
-    {
-        // TODO: determine padding as described in 27.7.3.6.1
-        using sentry = typename basic_ostream<Char, Traits>::sentry;
-        sentry sen{os};
-
-        if (sen)
-        {
-            auto width = os.width();
-            auto size = str.size();
-
-            size_t to_pad{};
-            if (width > 0)
-                to_pad = (static_cast<size_t>(width) - size);
-
-            if (to_pad > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (std::size_t i = 0; i < to_pad; ++i)
-                        os.put(os.fill());
-                }
-
-                os.rdbuf()->sputn(str.data(), size);
-
-                if ((os.flags() & ios_base::adjustfield) == ios_base::left)
-                {
-                    for (std::size_t i = 0; i < to_pad; ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.rdbuf()->sputn(str.data(), size);
-
-            os.width(0);
-        }
-
-        return os;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
-                                         basic_string<Char, Traits, Allocator>& str,
-                                         Char delim)
-    {
-        typename basic_istream<Char, Traits>::sentry sen{is, true};
-
-        if (sen)
-        {
-            str.clear();
-            streamsize count{};
-
-            while (true)
-            {
-                auto ic = is.rdbuf()->sbumpc();
-                if (Traits::eq_int_type(ic, Traits::eof()))
-                {
-                    is.setstate(ios_base::eofbit);
-                    break;
-                }
-
-                auto c = Traits::to_char_type(ic);
-                if (Traits::eq(c, delim))
-                    break;
-
-                str.push_back(c);
-                ++count;
-
-                if (count >= static_cast<streamsize>(str.max_size()))
-                {
-                    is.setstate(ios_base::failbit);
-                    break;
-                }
-            }
-
-            if (count == 0)
-                is.setstate(ios_base::failbit);
-        }
-        else
-            is.setstate(ios_base::failbit);
-
-        return is;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
-                                         basic_string<Char, Traits, Allocator>& str,
-                                         Char delim)
-    {
-        return getline(is, str, delim);
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>& is,
-                                         basic_string<Char, Traits, Allocator>& str)
-    {
-        return getline(is, str, is.widen('\n'));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_istream<Char, Traits>& getline(basic_istream<Char, Traits>&& is,
-                                         basic_string<Char, Traits, Allocator>& str)
-    {
-        return getline(is, str, is.widen('\n'));
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/stringfwd.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/stringfwd.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_STRINGFWD
-#define LIBCPP_BITS_STRINGFWD
-
-namespace std
-{
-    template<class Char>
-    struct char_traits;
-
-    template<class T>
-    struct allocator;
-
-    template<
-        class Char,
-        class Traits = char_traits<Char>,
-        class Allocator = allocator<Char>
-    >
-    class basic_string;
-
-    using string  = basic_string<char>;
-    using wstring = basic_string<wchar_t>;
-
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/system_error.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/system_error.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/system_error.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_SYSTEM_ERROR
+#define LIBCPP_BITS_SYSTEM_ERROR
+
+#include <__bits/aux.hpp>
+#include <__bits/string/stringfwd.hpp>
+#include <stdexcept>
+
+namespace std
+{
+    class error_condition;
+    class error_code;
+
+    enum class errc
+    { // TODO: add matching values
+        address_family_not_supported,
+        address_in_use,
+        address_not_available,
+        already_connected,
+        argument_list_too_long,
+        argument_out_of_domain,
+        bad_address,
+        bad_file_descriptor,
+        bad_message,
+        broken_pipe,
+        connection_aborted,
+        connection_already_in_progress,
+        connection_refused,
+        connection_reset,
+        cross_device_link,
+        destination_address_required,
+        device_or_resource_busy,
+        directory_not_empty,
+        executable_format_error,
+        file_exists,
+        file_too_large,
+        filename_too_long,
+        function_not_supported,
+        host_unreachable,
+        identifier_removed,
+        illegal_byte_sequence,
+        inappropriate_io_control_operation,
+        interrupted,
+        invalid_argument,
+        invalid_seek,
+        io_error,
+        is_a_directory,
+        message_size,
+        network_down,
+        network_reset,
+        network_unreachable,
+        no_buffer_space,
+        no_child_process,
+        no_link,
+        no_lock_available,
+        no_message_available,
+        no_message,
+        no_protocol_option,
+        no_space_on_device,
+        no_stream_resources,
+        no_such_device_or_address,
+        no_such_device,
+        no_such_file_or_directory,
+        no_such_process,
+        not_a_directory,
+        not_a_socket,
+        not_a_stream,
+        not_connected,
+        not_enough_memory,
+        not_supported,
+        operation_canceled,
+        operation_in_progress,
+        operation_not_permitted,
+        operation_not_supported,
+        operation_would_block,
+        owner_dead,
+        permission_denied,
+        protocol_error,
+        protocol_not_supported,
+        read_only_file_system,
+        resource_deadlock_would_occur,
+        resource_unavailable_try_again,
+        result_out_of_range,
+        state_not_recoverable,
+        stream_timeout,
+        text_file_busy,
+        timed_out,
+        too_many_files_open_in_system,
+        too_many_files_open,
+        too_many_links,
+        too_many_symbolic_link_levels,
+        value_too_large,
+        wrong_protocol_type
+    };
+
+    template<class>
+    struct is_error_code_enum: false_type
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct is_error_code_enum<errc>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
+
+    template<class>
+    struct is_error_condition_enum: false_type
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct is_error_condition_enum<errc>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value;
+
+    /**
+     * 19.5.1, class error_category:
+     */
+
+    class error_category
+    {
+        public:
+            constexpr error_category() noexcept = default;
+            virtual ~error_category();
+
+            error_category(const error_category&) = delete;
+            error_category& operator=(const error_category&) = delete;
+
+            virtual const char* name() const noexcept = 0;
+            virtual error_condition default_error_condition(int) const noexcept;
+            virtual bool equivalent(int, const error_condition&) const noexcept;
+            virtual bool equivalent(const error_code&, int) const noexcept;
+            virtual string message(int) const = 0;
+
+            bool operator==(const error_category&) const noexcept;
+            bool operator!=(const error_category&) const noexcept;
+            bool operator<(const error_category&) const noexcept;
+    };
+
+    const error_category& generic_category() noexcept;
+    const error_category& system_category() noexcept;
+
+    /**
+     * 19.5.2, class error_code:
+     */
+
+    class error_code
+    {
+        public:
+            /**
+             * 19.5.2.2, constructors:
+             */
+
+            error_code() noexcept;
+            error_code(int, const error_category&) noexcept;
+
+            template<class ErrorCodeEnum>
+            error_code(
+                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
+            ) noexcept
+            {
+                val_ = static_cast<int>(e);
+                cat_ = &generic_category();
+            }
+
+            /**
+             * 19.5.2.3, modifiers:
+             */
+
+            void assign(int, const error_category&) noexcept;
+
+            template<class ErrorCodeEnum>
+            error_code& operator=(
+                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
+            ) noexcept
+            {
+                val_ = static_cast<int>(e);
+                cat_ = &generic_category();
+
+                return *this;
+            }
+
+            void clear() noexcept;
+
+            /**
+             * 19.5.2.4, observers:
+             */
+
+            int value() const noexcept;
+            const error_category& category() const noexcept;
+            error_condition default_error_condition() const noexcept;
+            string message() const;
+
+            explicit operator bool() const noexcept
+            {
+                return val_ != 0;
+            }
+
+        private:
+            int val_;
+            const error_category* cat_;
+    };
+
+    /**
+     * 19.5.2.5, non-member functions:
+     */
+
+    error_code make_error_code(errc e) noexcept;
+    bool operator<(const error_code&, const error_code&) noexcept;
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
+                                            const error_code& ec)
+    {
+        return os << ec.category().name() << ": " << ec.value();
+    }
+
+    /**
+     * 19.5.3, class error_condition:
+     */
+
+    class error_condition
+    {
+        public:
+            /**
+             * 19.5.3.2, constructors:
+             */
+
+            error_condition() noexcept;
+            error_condition(int, const error_category&) noexcept;
+
+            template<class ErrorCodeEnum>
+            error_condition(
+                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
+            ) noexcept
+            {
+                val_ = static_cast<int>(e);
+                cat_ = &generic_category();
+            }
+
+            /**
+             * 19.5.3.3, modifiers:
+             */
+
+            void assign(int, const error_category&) noexcept;
+
+            template<class ErrorCodeEnum>
+            error_condition& operator=(
+                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
+            ) noexcept
+            {
+                val_ = static_cast<int>(e);
+                cat_ = &generic_category();
+
+                return *this;
+            }
+
+            void clear() noexcept;
+
+            /**
+             * 19.5.3.4, observers:
+             */
+
+            int value() const noexcept;
+            const error_category& category() const noexcept;
+            string message() const;
+
+            explicit operator bool() const noexcept
+            {
+                return val_ != 0;
+            }
+
+        private:
+            int val_;
+            const error_category* cat_;
+    };
+
+    /**
+     * 19.5.3.4, non-member functions:
+     */
+
+    error_condition make_error_condition(errc e) noexcept;
+    bool operator<(const error_condition&, const error_condition&) noexcept;
+
+    /**
+     * 19.5.4, comparison operators:
+     */
+
+    bool operator==(const error_code&, const error_code&) noexcept;
+    bool operator==(const error_code&, const error_condition&) noexcept;
+    bool operator==(const error_condition&, const error_code&) noexcept;
+    bool operator==(const error_condition&, const error_condition&) noexcept;
+    bool operator!=(const error_code&, const error_code&) noexcept;
+    bool operator!=(const error_code&, const error_condition&) noexcept;
+    bool operator!=(const error_condition&, const error_code&) noexcept;
+    bool operator!=(const error_condition&, const error_condition&) noexcept;
+
+    /**
+     * 19.5.6, class system_error:
+     */
+
+    class system_error: public runtime_error
+    {
+        public:
+            system_error(error_code, const string&);
+            system_error(error_code, const char*);
+            system_error(error_code);
+            system_error(int, const error_category&, const string&);
+            system_error(int, const error_category&, const char*);
+            system_error(int, const error_category&);
+
+            const error_code& code() const noexcept;
+
+        private:
+            error_code code_;
+    };
+
+    /**
+     * 19.5.5, hash support:
+     */
+
+    template<class>
+    struct hash;
+
+    template<>
+    struct hash<error_code>
+    {
+        size_t operator()(const error_code& ec) const noexcept
+        {
+            return static_cast<size_t>(ec.value());
+        }
+
+        using result_type   = size_t;
+        using argument_type = error_code;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/test/test.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/test/test.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/test/test.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBCPP_TEST_TEST
-#define LIBCPP_TEST_TEST
+#ifndef LIBCPP_BITS_TEST
+#define LIBCPP_BITS_TEST
 
 #include <utility>
Index: uspace/lib/cpp/include/__bits/test/tests.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/test/tests.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/__bits/test/tests.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,9 +27,9 @@
  */
 
-#ifndef LIBCPP_TESTS
-#define LIBCPP_TESTS
-
+#ifndef LIBCPP_BITS_TEST_TESTS
+#define LIBCPP_BITS_TEST_TESTS
+
+#include <__bits/test/test.hpp>
 #include <cstdio>
-#include <__bits/test/test.hpp>
 #include <vector>
 
Index: uspace/lib/cpp/include/__bits/thread.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,233 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITS_THREAD
-#define LIBCPP_BITS_THREAD
-
-namespace std::hel
-{
-    extern "C" {
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-}
-
-#include <chrono>
-
-namespace std::aux
-{
-    struct fibril_tag
-    { /* DUMMY BODY */ };
-
-    struct thread_tag
-    { /* DUMMY BODY */ };
-
-    template<class>
-    struct threading_policy;
-
-    template<>
-    struct threading_policy<fibril_tag>
-    {
-        using mutex_type        = hel::fibril_mutex_t;
-        using thread_type       = hel::fid_t;
-        using condvar_type      = hel::fibril_condvar_t;
-        using time_unit         = hel::suseconds_t;
-        using shared_mutex_type = hel::fibril_rwlock_t;
-
-        struct thread
-        {
-            template<class Callable, class Payload>
-            static thread_type create(Callable clbl, Payload& pld)
-            {
-                return hel::fibril_create(clbl, (void*)&pld);
-            }
-
-            static void start(thread_type thr)
-            {
-                hel::fibril_add_ready(thr);
-            }
-
-            static thread_type this_thread()
-            {
-                return hel::fibril_get_id();
-            }
-
-            static void yield()
-            {
-                hel::fibril_yield();
-            }
-
-            /**
-             * Note: join & detach are performed at the C++
-             *       level at the moment, but eventually should
-             *       be moved here once joinable fibrils are in libc.
-             */
-        };
-
-        struct mutex
-        {
-            static void init(mutex_type& mtx)
-            {
-                hel::fibril_mutex_initialize(&mtx);
-            }
-
-            static void lock(mutex_type& mtx)
-            {
-                hel::fibril_mutex_lock(&mtx);
-            }
-
-            static void unlock(mutex_type& mtx)
-            {
-                hel::fibril_mutex_unlock(&mtx);
-            }
-
-            static bool try_lock(mutex_type& mtx)
-            {
-                return hel::fibril_mutex_trylock(&mtx);
-            }
-
-            static bool try_lock_for(mutex_type& mtx, time_unit timeout)
-            {
-                // TODO: we need fibril_mutex_trylock_for() :/
-                return try_lock(mtx);
-            }
-        };
-
-        struct condvar
-        {
-            static void init(condvar_type& cv)
-            {
-                hel::fibril_condvar_initialize(&cv);
-            }
-
-            static void wait(condvar_type& cv, mutex_type& mtx)
-            {
-                hel::fibril_condvar_wait(&cv, &mtx);
-            }
-
-            static int wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
-            {
-                return hel::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
-            }
-
-            static void signal(condvar_type& cv)
-            {
-                hel::fibril_condvar_signal(&cv);
-            }
-
-            static void broadcast(condvar_type& cv)
-            {
-                hel::fibril_condvar_broadcast(&cv);
-            }
-        };
-
-        struct time
-        {
-            template<class Rep, class Period>
-            static time_unit convert(const std::chrono::duration<Rep, Period>& dur)
-            {
-                return std::chrono::duration_cast<std::chrono::duration<Rep, micro>>(dur).count();
-            }
-
-            static void sleep(time_unit time)
-            {
-                hel::fibril_usleep(time);
-            }
-        };
-
-        struct shared_mutex
-        {
-            static void init(shared_mutex_type& mtx)
-            {
-                hel::fibril_rwlock_initialize(&mtx);
-            }
-
-            static void lock(shared_mutex_type& mtx)
-            {
-                hel::fibril_rwlock_write_lock(&mtx);
-            }
-
-            static void unlock(shared_mutex_type& mtx)
-            {
-                hel::fibril_rwlock_write_unlock(&mtx);
-            }
-
-            static void lock_shared(shared_mutex_type& mtx)
-            {
-                hel::fibril_rwlock_read_lock(&mtx);
-            }
-
-            static void unlock_shared(shared_mutex_type& mtx)
-            {
-                hel::fibril_rwlock_read_unlock(&mtx);
-            }
-
-            static bool try_lock(shared_mutex_type& mtx)
-            {
-                // TODO: rwlocks don't have try locking capabilities
-                lock(mtx);
-
-                return true;
-            }
-
-            static bool try_lock_shared(shared_mutex_type& mtx)
-            {
-                lock(mtx);
-
-                return true;
-            }
-
-            static bool try_lock_for(shared_mutex_type& mtx, time_unit timeout)
-            {
-                return try_lock(mtx);
-            }
-
-            static bool try_lock_shared_for(shared_mutex_type& mtx, time_unit timeout)
-            {
-                return try_lock(mtx);
-            }
-        };
-    };
-
-    template<>
-    struct threading_policy<thread_tag>
-    {
-        // TODO:
-    };
-
-    using default_tag = fibril_tag;
-    using threading = threading_policy<default_tag>;
-
-    using thread_t       = typename threading::thread_type;
-    using mutex_t        = typename threading::mutex_type;
-    using condvar_t      = typename threading::condvar_type;
-    using time_unit_t    = typename threading::time_unit;
-    using shared_mutex_t = typename threading::shared_mutex_type;
-}
-
-#endif
Index: uspace/lib/cpp/include/__bits/thread/condition_variable.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_THREAD_CONDITION_VARIABLE
+#define LIBCPP_BITS_THREAD_CONDITION_VARIABLE
+
+#include <__bits/thread/threading.hpp>
+#include <mutex>
+
+namespace std
+{
+    extern "C" {
+        #include <fibril.h>
+        #include <fibril_synch.h>
+    }
+
+    enum class cv_status
+    {
+        no_timeout,
+        timeout
+    };
+
+    namespace aux
+    {
+        template<class Clock, class Duration>
+        aux::time_unit_t time_until(const chrono::time_point<Clock, Duration>& abs_time)
+        {
+            return aux::threading::time::convert(abs_time - Clock::now());
+        }
+    }
+
+    /**
+     * 30.5.1, class condition_variable:
+     */
+
+    class condition_variable
+    {
+        public:
+            condition_variable();
+            ~condition_variable();
+
+            condition_variable(const condition_variable&) = delete;
+            condition_variable& operator=(const condition_variable&) = delete;
+
+            void notify_one() noexcept;
+            void notify_all() noexcept;
+
+            void wait(unique_lock<mutex>&);
+
+            template<class Predicate>
+            void wait(unique_lock<mutex>& lock, Predicate pred)
+            {
+                /**
+                 * Note: lock is supposed to be locked here,
+                 *       so no need to lock it.
+                 */
+                while (!pred())
+                    wait(lock);
+            }
+
+            template<class Clock, class Duration>
+            cv_status wait_until(unique_lock<mutex>& lock,
+                                 const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                auto ret = aux::threading::condvar::wait_for(
+                    cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
+                );
+
+                if (ret == EOK)
+                    return cv_status::no_timeout;
+                else
+                    return cv_status::timeout;
+            }
+
+            template<class Clock, class Duration, class Predicate>
+            bool wait_until(unique_lock<mutex>& lock,
+                            const chrono::time_point<Clock, Duration>& abs_time,
+                            Predicate pred)
+            {
+                while (!pred())
+                {
+                    if (wait_until(lock, abs_time) == cv_status::timeout)
+                        return pred();
+                }
+
+                return true;
+            }
+
+            template<class Rep, class Period>
+            cv_status wait_for(unique_lock<mutex>& lock,
+                               const chrono::duration<Rep, Period>& rel_time)
+            {
+                return wait_until(
+                    lock, chrono::steady_clock::now() + rel_time
+                );
+            }
+
+            template<class Rep, class Period, class Predicate>
+            bool wait_for(unique_lock<mutex>& lock,
+                          const chrono::duration<Rep, Period>& rel_time,
+                          Predicate pred)
+            {
+                return wait_until(
+                    lock, chrono::steady_clock::now() + rel_time,
+                    move(pred)
+                );
+            }
+
+            using native_handle_type = aux::condvar_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::condvar_t cv_;
+    };
+
+    /**
+     * 30.5.2, class condition_variable_any:
+     */
+
+    class condition_variable_any
+    {
+        public:
+            condition_variable_any();
+            ~condition_variable_any();
+
+            condition_variable_any(const condition_variable_any&) = delete;
+            condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+            void notify_one() noexcept;
+            void notify_all() noexcept;
+
+            template<class Lock>
+            void wait(Lock& lock)
+            {
+                aux::threading::condvar::wait(cv_, *lock.native_handle());
+            }
+
+            template<class Lock, class Predicate>
+            void wait(Lock& lock, Predicate pred)
+            {
+                while (!pred())
+                    wait(lock);
+            }
+
+            template<class Lock, class Clock, class Duration>
+            cv_status wait_until(Lock& lock,
+                                 const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                auto ret = aux::threading::condvar::wait_for(
+                    cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
+                );
+
+                if (ret == EOK)
+                    return cv_status::no_timeout;
+                else
+                    return cv_status::timeout;
+            }
+
+            template<class Lock, class Clock, class Duration, class Predicate>
+            bool wait_until(Lock& lock,
+                            const chrono::time_point<Clock, Duration>& abs_time,
+                            Predicate pred)
+            {
+                while (!pred())
+                {
+                    if (wait_until(lock, abs_time) == cv_status::timeout)
+                        return pred();
+                }
+
+                return true;
+            }
+
+            template<class Lock, class Rep, class Period>
+            cv_status wait_for(Lock& lock,
+                               const chrono::duration<Rep, Period>& rel_time)
+            {
+                return wait_until(
+                    lock, chrono::steady_clock::now() + rel_time
+                );
+            }
+
+            template<class Lock, class Rep, class Period, class Predicate>
+            bool wait_for(Lock& lock,
+                          const chrono::duration<Rep, Period>& rel_time,
+                          Predicate pred)
+            {
+                return wait_until(
+                    lock, chrono::steady_clock::now() + rel_time,
+                    move(pred)
+                );
+            }
+
+            using native_handle_type = aux::condvar_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::condvar_t cv_;
+    };
+
+    void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>&);
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/future.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/future.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_THREAD_FUTURE
+#define LIBCPP_BITS_THREAD_FUTURE
+
+#include <memory>
+#include <system_error>
+#include <type_traits>
+
+namespace std
+{
+    /**
+     * 30.6, futures:
+     */
+
+    enum class future_errc
+    { // The 5001 start is to not collide with system_error's codes.
+        broken_promise = 5001,
+        future_already_retrieved,
+        promise_already_satisfied,
+        no_state
+    };
+
+    enum class launch
+    {
+        async,
+        deferred
+    };
+
+    enum class future_status
+    {
+        ready,
+        timeout,
+        deferred
+    };
+
+    /**
+     * 30.6.2, error handling:
+     */
+
+    template<>
+    struct is_error_code_enum<future_errc>: true_type
+    { /* DUMMY BODY */ };
+
+    error_code make_error_code(future_errc) noexcept;
+    error_condition make_error_condition(future_errc) noexcept;
+
+    const error_category& future_category() noexcept;
+
+    /**
+     * 30.6.3, class future_error:
+     */
+
+    class future_error: public logic_error
+    {
+        public:
+            future_error(error_code ec);
+
+            const error_code& code() const noexcept;
+
+        private:
+            error_code code_;
+    };
+
+    /**
+     * 30.6.4, shared state:
+     */
+
+    template<class R>
+    class promise
+    {
+    };
+
+    template<class R>
+    class promise<R&>
+    {
+    };
+
+    template<>
+    class promise<void>
+    {
+    };
+
+    template<class R>
+    void swap(promise<R>& lhs, promise<R>& rhs) noexcept
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class R, class Alloc>
+    struct uses_allocator<promise<R>, Alloc>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class R>
+    class future
+    {
+    };
+
+    template<class R>
+    class future<R&>
+    {
+    };
+
+    template<>
+    class future<void>
+    {
+    };
+
+    template<class R>
+    class shared_future
+    {
+    };
+
+    template<class R>
+    class shared_future<R&>
+    {
+    };
+
+    template<>
+    class shared_future<void>
+    {
+    };
+
+    template<class>
+    class packaged_task; // undefined
+
+    template<class R, class... Args>
+    class packaged_task<R(Args...)>
+    {
+    };
+
+    template<class R, class... Args>
+    void swap(packaged_task<R(Args...)>& lhs, packaged_task<R(Args...)>& rhs) noexcept
+    {
+        lhs.swap(rhs);
+    };
+
+    template<class R, class Alloc>
+    struct uses_allocator<packaged_task<R>, Alloc>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class F, class... Args>
+    future<result_of_t<decay_t<F>(decay_t<Args>...)>>
+    async(F&& f, Args&&... args)
+    {
+        // TODO: implement
+    }
+
+    template<class F, class... Args>
+    future<result_of_t<decay_t<F>(decay_t<Args>...)>>
+    async(launch, F&& f, Args&&... args)
+    {
+        // TODO: implement
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/mutex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,542 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_THREAD_MUTEX
+#define LIBCPP_BITS_THREAD_MUTEX
+
+#include <__bits/common.hpp>
+#include <__bits/thread/threading.hpp>
+#include <functional>
+#include <thread>
+
+namespace std
+{
+    /**
+     * 20.4.1.2.1, class mutex:
+     */
+
+    class mutex
+    {
+        public:
+            constexpr mutex() noexcept
+                : mtx_{}
+            {
+                aux::threading::mutex::init(mtx_);
+            }
+
+            ~mutex() = default;
+
+            mutex(const mutex&) = delete;
+            mutex& operator=(const mutex&) = delete;
+
+            void lock();
+            bool try_lock();
+            void unlock();
+
+            using native_handle_type = aux::mutex_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::mutex_t mtx_;
+    };
+
+    /**
+     * 30.4.1.2.2, class recursive_mutex:
+     */
+
+    class recursive_mutex
+    {
+        public:
+            constexpr recursive_mutex() noexcept
+                : mtx_{}, lock_level_{}, owner_{}
+            {
+                aux::threading::mutex::init(mtx_);
+            }
+
+            ~recursive_mutex();
+
+            recursive_mutex(const recursive_mutex&) = delete;
+            recursive_mutex& operator=(const recursive_mutex&) = delete;
+
+            void lock();
+            bool try_lock() noexcept;
+            void unlock();
+
+            using native_handle_type = aux::mutex_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::mutex_t mtx_;
+            size_t lock_level_;
+            thread::id owner_;
+    };
+
+    /**
+     * 30.4.1.3.1, class timed_mutex:
+     */
+
+    class timed_mutex
+    {
+        public:
+            timed_mutex() noexcept;
+            ~timed_mutex();
+
+            timed_mutex(const timed_mutex&) = delete;
+            timed_mutex& operator=(const timed_mutex&) = delete;
+
+            void lock();
+            bool try_lock();
+            void unlock();
+
+            template<class Rep, class Period>
+            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                auto time = aux::threading::time::convert(rel_time);
+
+                return aux::threading::mutex::try_lock_for(time);
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                auto dur = (abs_time - Clock::now());
+                auto time = aux::threading::time::convert(dur);
+
+                return aux::threading::mutex::try_lock_for(time);
+            }
+
+            using native_handle_type = aux::mutex_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::mutex_t mtx_;
+    };
+
+    /**
+     * 30.4.1.3.2, class recursive_timed_mutex:
+     */
+
+    class recursive_timed_mutex
+    {
+        public:
+            recursive_timed_mutex() noexcept
+                : mtx_{}, lock_level_{}, owner_{}
+            {
+                aux::threading::mutex::init(mtx_);
+            }
+
+            ~recursive_timed_mutex();
+
+            recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+            recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+            void lock();
+            bool try_lock() noexcept;
+            void unlock();
+
+            template<class Rep, class Period>
+            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                if (owner_ == this_thread::get_id())
+                    return true;
+
+                auto time = aux::threading::time::convert(rel_time);
+                auto ret = aux::threading::mutex::try_lock_for(time);
+
+                if (ret)
+                    ++lock_level_;
+                return ret;
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                if (owner_ == this_thread::get_id())
+                    return true;
+
+                auto dur = (abs_time - Clock::now());
+                auto time = aux::threading::time::convert(dur);
+                auto ret = aux::threading::mutex::try_lock_for(time);
+
+                if (ret)
+                    ++lock_level_;
+                return ret;
+            }
+
+            using native_handle_type = aux::mutex_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::mutex_t mtx_;
+            size_t lock_level_;
+            thread::id owner_;
+    };
+
+    struct defer_lock_t
+    { /* DUMMY BODY */ };
+
+    struct try_to_lock_t
+    { /* DUMMY BODY */ };
+
+    struct adopt_lock_t
+    { /* DUMMY BODY */ };
+
+    constexpr defer_lock_t defer_lock
+    { /* DUMMY BODY */ };
+
+    constexpr try_to_lock_t try_to_lock
+    { /* DUMMY BODY */ };
+
+    constexpr adopt_lock_t adopt_lock
+    { /* DUMMY BODY */ };
+
+    /**
+     * 30.4.2.1, class template lock_guard:
+     */
+
+    template<class Mutex>
+    class lock_guard
+    {
+        public:
+            using mutex_type = Mutex;
+
+            explicit lock_guard(mutex_type& mtx)
+                : mtx_{mtx}
+            {
+                mtx.lock();
+            }
+
+            lock_guard(mutex_type& mtx, adopt_lock_t)
+                : mtx_{mtx}
+            { /* DUMMY BODY */ }
+
+            ~lock_guard()
+            {
+                mtx_.unlock();
+            }
+
+            lock_guard(const lock_guard&) = delete;
+            lock_guard& operator=(const lock_guard&) = delete;
+
+        private:
+            mutex_type& mtx_;
+    };
+
+    template<class Mutex>
+    class unique_lock
+    {
+        public:
+            using mutex_type = Mutex;
+
+            /**
+             * 30.4.2.2.1, construction/copy/destroy:
+             */
+
+            unique_lock() noexcept
+                : mtx_{nullptr}, owns_{false}
+            { /* DUMMY BODY */ }
+
+            explicit unique_lock(mutex_type& mtx)
+                : mtx_{&mtx}, owns_{true}
+            {
+                mtx_->lock();
+            }
+
+            unique_lock(mutex_type& mtx, defer_lock_t) noexcept
+                : mtx_{&mtx}, owns_{false}
+            { /* DUMMY BODY */ }
+
+            unique_lock(mutex_type& mtx, try_to_lock_t)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock();
+            }
+
+            unique_lock(mutex_type& mtx, adopt_lock_t)
+                : mtx_{&mtx}, owns_{true}
+            { /* DUMMY BODY */ }
+
+            template<class Clock, class Duration>
+            unique_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock_until(abs_time);
+            }
+
+            template<class Rep, class Period>
+            unique_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock_for(rel_time);
+            }
+
+            ~unique_lock()
+            {
+                if (owns_)
+                    mtx_->unlock();
+            }
+
+            unique_lock(const unique_lock&) = delete;
+            unique_lock& operator=(const unique_lock&) = delete;
+
+            unique_lock(unique_lock&& other) noexcept
+                : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
+            {
+                other.mtx_ = nullptr;
+                other.owns_ = false;
+            }
+
+            unique_lock& operator=(unique_lock&& other)
+            {
+                if (owns_)
+                    mtx_->unlock();
+
+                mtx_ = move(other.mtx_);
+                owns_ = move(other.owns_);
+
+                other.mtx_ = nullptr;
+                other.owns_ = false;
+            }
+
+            /**
+             * 30.4.2.2.2, locking:
+             */
+
+            void lock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                mtx_->lock();
+                owns_ = true;
+            }
+
+            bool try_lock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock();
+
+                return owns_;
+            }
+
+            template<class Rep, class Period>
+            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock_for(rel_time);
+
+                return owns_;
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock_until(abs_time);
+
+                return owns_;
+            }
+
+            void unlock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if owns_ == false
+                 */
+
+                mtx_->unlock();
+            }
+
+            /**
+             * 30.4.2.2.3, modifiers:
+             */
+
+            void swap(unique_lock& other) noexcept
+            {
+                std::swap(mtx_, other.mtx_);
+                std::swap(owns_, other.owns_);
+            }
+
+            mutex_type* release() noexcept
+            {
+                auto ret = mtx_;
+                mtx_ = nullptr;
+                owns_ = false;
+
+                return ret;
+            }
+
+            /**
+             * 30.4.2.2.4, observers:
+             */
+
+            bool owns_lock() const noexcept
+            {
+                return owns_;
+            }
+
+            explicit operator bool() const noexcept
+            {
+                return owns_;
+            }
+
+            mutex_type* mutex() const noexcept
+            {
+                return mtx_;
+            }
+
+        private:
+            mutex_type* mtx_;
+            bool owns_;
+    };
+
+    template<class Mutex>
+    void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) noexcept
+    {
+        lhs.swap(rhs);
+    }
+
+    namespace aux
+    {
+        template<class L>
+        int try_lock_tail(int idx, L& l)
+        {
+            if (!l.try_lock())
+                return idx;
+            else
+                return -1;
+        }
+
+        template<class L1, class... L2>
+        int try_lock_tail(int idx, L1& l1, L2&... ls)
+        {
+            if (!l1.try_lock())
+                return idx;
+
+            auto ret = try_lock_tail(idx + 1, ls...);
+            if (ret != -1)
+                l1.unlock();
+
+            return ret;
+        }
+    }
+
+    template<class L1, class L2, class... L3>
+    int try_lock(L1& l1, L2& l2, L3&... ls)
+    {
+        return aux::try_lock_tail(0, l1, l2, ls...);
+    }
+
+    namespace aux
+    {
+        template<class L>
+        bool lock_tail(L& l)
+        {
+            return l.try_lock();
+        }
+
+        template<class L1, class... L2>
+        bool lock_tail(L1& l1, L2&... ls)
+        {
+            if (l1.try_lock())
+            {
+                auto ret = lock_tail(ls...);
+                if (ret)
+                    return true;
+
+                l1.unlock();
+            }
+
+            return false;
+        }
+    }
+
+    template<class L1, class L2, class... L3>
+    void lock(L1& l1, L2& l2, L3&... ls)
+    {
+        do
+        {
+            l1.lock();
+
+            if (aux::lock_tail(l2, ls...))
+                return;
+            l1.unlock();
+        } while (true);
+    }
+
+    struct once_flag
+    {
+        constexpr once_flag() noexcept
+            : called_{false}, mtx_{}
+        { /* DUMMY BODY */ }
+
+        once_flag(const once_flag&) = delete;
+        once_flag& operator=(const once_flag&) = delete;
+
+        private:
+            bool called_;
+            mutex mtx_;
+
+            template<class Callable, class... Args>
+            friend void call_once(once_flag&, Callable&&, Args&&...);
+    };
+
+    template<class Callable, class... Args>
+    void call_once(once_flag& flag, Callable&& func, Args&&... args)
+    {
+        flag.mtx_.lock();
+        if (!flag.called_)
+        {
+            // TODO: exception handling
+
+            aux::INVOKE(forward<Callable>(func), forward<Args>(args)...);
+            flag.called_ = true;
+        }
+        flag.mtx_.unlock();
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/shared_mutex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/shared_mutex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/shared_mutex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_THREAD_SHARED_MUTEX
+#define LIBCPP_THREAD_SHARED_MUTEX
+
+#include <__bits/thread/threading.hpp>
+#include <chrono>
+#include <mutex>
+
+namespace std
+{
+    /**
+     * 30.4.1.4.1, class shared_timed_mutex:
+     */
+
+    class shared_timed_mutex
+    {
+        public:
+            shared_timed_mutex() noexcept;
+            ~shared_timed_mutex();
+
+            shared_timed_mutex(const shared_timed_mutex&) = delete;
+            shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+            void lock();
+            bool try_lock();
+            void unlock();
+
+            template<class Rep, class Period>
+            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                auto time = aux::threading::time::convert(rel_time);
+
+                return aux::threading::shared_mutex::try_lock_for(time);
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                auto dur = (abs_time - Clock::now());
+                auto time = aux::threading::time::convert(dur);
+
+                return aux::threading::shared_mutex::try_lock_for(time);
+            }
+
+            void lock_shared();
+            bool try_lock_shared();
+            void unlock_shared();
+
+            template<class Rep, class Period>
+            bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                auto time = aux::threading::time::convert(rel_time);
+
+                return aux::threading::shared_mutex::try_lock_shared_for(time);
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                auto dur = (abs_time - Clock::now());
+                auto time = aux::threading::time::convert(dur);
+
+                return aux::threading::shared_mutex::try_lock_shared_for(time);
+            }
+
+            using native_handle_type = aux::shared_mutex_t*;
+            native_handle_type native_handle();
+
+        private:
+            aux::shared_mutex_t mtx_;
+    };
+
+    /**
+     * 30.4.2.3, class template shared_lock:
+     */
+
+    template<class Mutex>
+    class shared_lock
+    {
+        public:
+            using mutex_type = Mutex;
+
+            /**
+             * 30.4.2.2.1, construction/copy/destroy:
+             */
+
+            shared_lock() noexcept
+                : mtx_{nullptr}, owns_{false}
+            { /* DUMMY BODY */ }
+
+            explicit shared_lock(mutex_type& mtx)
+                : mtx_{&mtx}, owns_{true}
+            {
+                mtx_->lock_shared();
+            }
+
+            shared_lock(mutex_type& mtx, defer_lock_t) noexcept
+                : mtx_{&mtx}, owns_{false}
+            { /* DUMMY BODY */ }
+
+            shared_lock(mutex_type& mtx, try_to_lock_t)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock_shared();
+            }
+
+            shared_lock(mutex_type& mtx, adopt_lock_t)
+                : mtx_{&mtx}, owns_{true}
+            { /* DUMMY BODY */ }
+
+            template<class Clock, class Duration>
+            shared_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock_shared_until(abs_time);
+            }
+
+            template<class Rep, class Period>
+            shared_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
+                : mtx_{&mtx}, owns_{}
+            {
+                owns_ = mtx_->try_lock_shared_for(rel_time);
+            }
+
+            ~shared_lock()
+            {
+                if (owns_)
+                    mtx_->unlock_shared();
+            }
+
+            shared_lock(const shared_lock&) = delete;
+            shared_lock& operator=(const shared_lock&) = delete;
+
+            shared_lock(shared_lock&& other) noexcept
+                : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
+            {
+                other.mtx_ = nullptr;
+                other.owns_ = false;
+            }
+
+            shared_lock& operator=(shared_lock&& other)
+            {
+                if (owns_)
+                    mtx_->unlock_shared();
+
+                mtx_ = move(other.mtx_);
+                owns_ = move(other.owns_);
+
+                other.mtx_ = nullptr;
+                other.owns_ = false;
+            }
+
+            /**
+             * 30.4.2.2.2, locking:
+             */
+
+            void lock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                mtx_->lock_shared();
+                owns_ = true;
+            }
+
+            bool try_lock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock_shared();
+
+                return owns_;
+            }
+
+            template<class Rep, class Period>
+            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock_shared_for(rel_time);
+
+                return owns_;
+            }
+
+            template<class Clock, class Duration>
+            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if mtx_ == nullptr
+                 * throw system_error resource_deadlock_would_occur if owns_ == true
+                 */
+
+                owns_ = mtx_->try_lock_shared_until(abs_time);
+
+                return owns_;
+            }
+
+            void unlock()
+            {
+                /**
+                 * TODO:
+                 * throw system_error operation_not_permitted if owns_ == false
+                 */
+
+                mtx_->unlock_shared();
+            }
+
+            /**
+             * 30.4.2.2.3, modifiers:
+             */
+
+            void swap(shared_lock& other) noexcept
+            {
+                std::swap(mtx_, other.mtx_);
+                std::swap(owns_, other.owns_);
+            }
+
+            mutex_type* release() noexcept
+            {
+                auto ret = mtx_;
+                mtx_ = nullptr;
+                owns_ = false;
+
+                return ret;
+            }
+
+            /**
+             * 30.4.2.2.4, observers:
+             */
+
+            bool owns_lock() const noexcept
+            {
+                return owns_;
+            }
+
+            explicit operator bool() const noexcept
+            {
+                return owns_;
+            }
+
+            mutex_type* mutex() const noexcept
+            {
+                return mtx_;
+            }
+
+        private:
+            mutex_type* mtx_;
+            bool owns_;
+    };
+
+    template<class Mutex>
+    void swap(shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs) noexcept
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/thread.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_THREAD
+#define LIBCPP_BITS_THREAD
+
+#include <__bits/common.hpp>
+#include <__bits/thread/threading.hpp>
+#include <chrono>
+#include <ostream>
+
+namespace std
+{
+    namespace aux
+    {
+        template<class Callable>
+        int thread_main(void*);
+
+        /**
+         * Fibrils in HelenOS are not joinable. They were
+         * in the past, but that functionality was removed from them
+         * so we created a workaround using a conditional variable that
+         * comprises the following two wrapper classes.
+         */
+        class joinable_wrapper
+        {
+            public:
+                joinable_wrapper()
+                    : join_mtx_{}, join_cv_{},
+                      finished_{false}, detached_{false}
+                {
+                    aux::threading::mutex::init(join_mtx_);
+                    aux::threading::condvar::init(join_cv_);
+                }
+
+                void join()
+                {
+                    aux::threading::mutex::lock(join_mtx_);
+                    while (!finished_)
+                        aux::threading::condvar::wait(join_cv_, join_mtx_);
+                    aux::threading::mutex::unlock(join_mtx_);
+                }
+
+                bool finished() const
+                {
+                    return finished_;
+                }
+
+                void detach()
+                {
+                    detached_ = true;
+                }
+
+                bool detached() const
+                {
+                    return detached_;
+                }
+
+            protected:
+                aux::mutex_t join_mtx_;
+                aux::condvar_t join_cv_;
+                bool finished_;
+                bool detached_;
+        };
+
+        template<class Callable>
+        class callable_wrapper: public joinable_wrapper
+        {
+            public:
+                callable_wrapper(Callable&& clbl)
+                    : joinable_wrapper{}, callable_{forward<Callable>(clbl)}
+                { /* DUMMY BODY */ }
+
+                void operator()()
+                {
+                    callable_();
+
+                    aux::threading::mutex::lock(join_mtx_);
+                    finished_ = true;
+                    aux::threading::mutex::unlock(join_mtx_);
+
+                    aux::threading::condvar::broadcast(join_cv_);
+                }
+
+            private:
+                Callable callable_;
+        };
+    }
+
+    /**
+     * 30.3.1, class thread:
+     */
+
+    class thread
+    {
+        public:
+            class id;
+
+            using native_handle_type = aux::thread_t*;
+
+            /**
+             * 30.3.1.2, thread constructors:
+             * 30.3.1.3, thread destructor:
+             * 30.3.1.4, thread assignment:
+             */
+
+            thread() noexcept;
+
+            ~thread();
+
+            // TODO: check the remark in the standard
+            template<class F, class... Args>
+            explicit thread(F&& f, Args&&... args)
+                : id_{}
+            {
+                auto callable = [=](){
+                    return f(forward<Args>(args)...);
+                };
+
+                auto callable_wrapper = new aux::callable_wrapper<decltype(callable)>{move(callable)};
+                joinable_wrapper_ = static_cast<aux::joinable_wrapper*>(callable_wrapper);
+
+                id_ = aux::threading::thread::create(
+                    aux::thread_main<decltype(callable_wrapper)>,
+                    *callable_wrapper
+                );
+
+                aux::threading::thread::start(id_);
+                // TODO: fibrils are weird here, 2 returns with same thread ids
+            }
+
+            thread(const thread&) = delete;
+            thread& operator=(const thread&) = delete;
+
+            thread(thread&& other) noexcept;
+            thread& operator=(thread&& other) noexcept;
+
+            /**
+             * 30.3.1.5, thread members:
+             */
+
+            void swap(thread& other) noexcept;
+
+            bool joinable() const noexcept;
+
+            void join();
+
+            void detach();
+
+            id get_id() const noexcept;
+
+            native_handle_type native_handle();
+
+            static unsigned hardware_concurrency() noexcept;
+
+        private:
+            aux::thread_t id_;
+            aux::joinable_wrapper* joinable_wrapper_{nullptr};
+
+            template<class Callable>
+            friend int aux::thread_main(void*);
+    };
+
+    namespace aux
+    {
+        template<class CallablePtr>
+        int thread_main(void* clbl)
+        {
+            if (!clbl)
+                return 1;
+
+            auto callable = static_cast<CallablePtr>(clbl);
+            (*callable)();
+
+            if (callable->detached())
+                delete callable;
+
+            return 0;
+        }
+    }
+
+    void swap(thread& x, thread& y) noexcept;
+
+    /**
+     * 30.3.2, namespace this_thread:
+     */
+
+    namespace this_thread
+    {
+        thread::id get_id() noexcept;
+
+        void yield() noexcept;
+
+        template<class Clock, class Duration>
+        void sleep_until(const chrono::time_point<Clock, Duration>& abs_time)
+        {
+            auto now = Clock::now();
+
+            auto time = aux::threading::time::convert(abs_time - now);
+            aux::threading::time::sleep(time);
+        }
+
+        template<class Rep, class Period>
+        void sleep_for(const chrono::duration<Rep, Period>& rel_time)
+        {
+            if (rel_time <= chrono::duration<Rep, Period>::zero())
+                return;
+
+            // TODO: timeouts?
+            auto time = aux::threading::time::convert(rel_time);
+            aux::threading::time::sleep(time);
+        }
+    }
+
+    template<class T>
+    struct hash;
+
+    class thread::id
+    {
+        public:
+            constexpr id() noexcept
+                : id_{}
+            { /* DUMMY BODY */ }
+
+        private:
+            aux::thread_t id_;
+
+            id(aux::thread_t id)
+                : id_{id}
+            { /* DUMMY BODY */ }
+
+            friend class thread;
+
+            friend bool operator==(thread::id, thread::id) noexcept;
+            friend bool operator!=(thread::id, thread::id) noexcept;
+            friend bool operator<(thread::id, thread::id) noexcept;
+            friend bool operator<=(thread::id, thread::id) noexcept;
+            friend bool operator>(thread::id, thread::id) noexcept;
+            friend bool operator>=(thread::id, thread::id) noexcept;
+
+            template<class Char, class Traits>
+            friend basic_ostream<Char, Traits>& operator<<(
+                basic_ostream<Char, Traits>&, thread::id);
+
+            friend struct hash<id>;
+
+            friend id this_thread::get_id() noexcept;
+    };
+
+    bool operator==(thread::id lhs, thread::id rhs) noexcept;
+    bool operator!=(thread::id lhs, thread::id rhs) noexcept;
+    bool operator<(thread::id lhs, thread::id rhs) noexcept;
+    bool operator<=(thread::id lhs, thread::id rhs) noexcept;
+    bool operator>(thread::id lhs, thread::id rhs) noexcept;
+    bool operator>=(thread::id lhs, thread::id rhs) noexcept;
+
+    template<class Char, class Traits>
+    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& out, thread::id id)
+    {
+        out << id.id_;
+
+        return out;
+    }
+
+    template<> // TODO: implement
+    struct hash<thread::id>;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/thread/threading.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_THREAD_THREADING
+#define LIBCPP_BITS_THREAD_THREADING
+
+namespace std::hel
+{
+    extern "C" {
+        #include <fibril.h>
+        #include <fibril_synch.h>
+    }
+}
+
+#include <chrono>
+
+namespace std::aux
+{
+    struct fibril_tag
+    { /* DUMMY BODY */ };
+
+    struct thread_tag
+    { /* DUMMY BODY */ };
+
+    template<class>
+    struct threading_policy;
+
+    template<>
+    struct threading_policy<fibril_tag>
+    {
+        using mutex_type        = hel::fibril_mutex_t;
+        using thread_type       = hel::fid_t;
+        using condvar_type      = hel::fibril_condvar_t;
+        using time_unit         = hel::suseconds_t;
+        using shared_mutex_type = hel::fibril_rwlock_t;
+
+        struct thread
+        {
+            template<class Callable, class Payload>
+            static thread_type create(Callable clbl, Payload& pld)
+            {
+                return hel::fibril_create(clbl, (void*)&pld);
+            }
+
+            static void start(thread_type thr)
+            {
+                hel::fibril_add_ready(thr);
+            }
+
+            static thread_type this_thread()
+            {
+                return hel::fibril_get_id();
+            }
+
+            static void yield()
+            {
+                hel::fibril_yield();
+            }
+
+            /**
+             * Note: join & detach are performed at the C++
+             *       level at the moment, but eventually should
+             *       be moved here once joinable fibrils are in libc.
+             */
+        };
+
+        struct mutex
+        {
+            static void init(mutex_type& mtx)
+            {
+                hel::fibril_mutex_initialize(&mtx);
+            }
+
+            static void lock(mutex_type& mtx)
+            {
+                hel::fibril_mutex_lock(&mtx);
+            }
+
+            static void unlock(mutex_type& mtx)
+            {
+                hel::fibril_mutex_unlock(&mtx);
+            }
+
+            static bool try_lock(mutex_type& mtx)
+            {
+                return hel::fibril_mutex_trylock(&mtx);
+            }
+
+            static bool try_lock_for(mutex_type& mtx, time_unit timeout)
+            {
+                // TODO: we need fibril_mutex_trylock_for() :/
+                return try_lock(mtx);
+            }
+        };
+
+        struct condvar
+        {
+            static void init(condvar_type& cv)
+            {
+                hel::fibril_condvar_initialize(&cv);
+            }
+
+            static void wait(condvar_type& cv, mutex_type& mtx)
+            {
+                hel::fibril_condvar_wait(&cv, &mtx);
+            }
+
+            static int wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
+            {
+                return hel::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
+            }
+
+            static void signal(condvar_type& cv)
+            {
+                hel::fibril_condvar_signal(&cv);
+            }
+
+            static void broadcast(condvar_type& cv)
+            {
+                hel::fibril_condvar_broadcast(&cv);
+            }
+        };
+
+        struct time
+        {
+            template<class Rep, class Period>
+            static time_unit convert(const std::chrono::duration<Rep, Period>& dur)
+            {
+                return std::chrono::duration_cast<std::chrono::duration<Rep, micro>>(dur).count();
+            }
+
+            static void sleep(time_unit time)
+            {
+                hel::fibril_usleep(time);
+            }
+        };
+
+        struct shared_mutex
+        {
+            static void init(shared_mutex_type& mtx)
+            {
+                hel::fibril_rwlock_initialize(&mtx);
+            }
+
+            static void lock(shared_mutex_type& mtx)
+            {
+                hel::fibril_rwlock_write_lock(&mtx);
+            }
+
+            static void unlock(shared_mutex_type& mtx)
+            {
+                hel::fibril_rwlock_write_unlock(&mtx);
+            }
+
+            static void lock_shared(shared_mutex_type& mtx)
+            {
+                hel::fibril_rwlock_read_lock(&mtx);
+            }
+
+            static void unlock_shared(shared_mutex_type& mtx)
+            {
+                hel::fibril_rwlock_read_unlock(&mtx);
+            }
+
+            static bool try_lock(shared_mutex_type& mtx)
+            {
+                // TODO: rwlocks don't have try locking capabilities
+                lock(mtx);
+
+                return true;
+            }
+
+            static bool try_lock_shared(shared_mutex_type& mtx)
+            {
+                lock(mtx);
+
+                return true;
+            }
+
+            static bool try_lock_for(shared_mutex_type& mtx, time_unit timeout)
+            {
+                return try_lock(mtx);
+            }
+
+            static bool try_lock_shared_for(shared_mutex_type& mtx, time_unit timeout)
+            {
+                return try_lock(mtx);
+            }
+        };
+    };
+
+    template<>
+    struct threading_policy<thread_tag>
+    {
+        // TODO:
+    };
+
+    using default_tag = fibril_tag;
+    using threading = threading_policy<default_tag>;
+
+    using thread_t       = typename threading::thread_type;
+    using mutex_t        = typename threading::mutex_type;
+    using condvar_t      = typename threading::condvar_type;
+    using time_unit_t    = typename threading::time_unit;
+    using shared_mutex_t = typename threading::shared_mutex_type;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/tuple/tuple.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/tuple/tuple.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/tuple/tuple.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_TUPLE
+#define LIBCPP_BITS_TUPLE
+
+#include <__bits/aux.hpp>
+#include <__bits/tuple/tuple_cat.hpp>
+#include <__bits/tuple/tuple_ops.hpp>
+#include <__bits/type_transformation.hpp>
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+namespace std
+{
+    template<class... Ts>
+    class tuple;
+
+    /**
+     * 20.4.2.4, tuple creation functions:
+     */
+
+    namespace aux
+    {
+        struct ignore_t
+        {
+            template<class T>
+            const ignore_t& operator=(const T&) const
+            {
+                return *this;
+            }
+        };
+    }
+
+    inline constexpr aux::ignore_t ignore;
+
+    template<class... Ts> // TODO: test the reference_wrapper version once we got reference_wrapper
+    constexpr auto make_tuple(Ts&&... ts)
+    {
+        return tuple<aux::transform_tuple_types_t<Ts>...>(forward<Ts>(ts)...);
+    }
+
+    template<class... Ts>
+    constexpr tuple<Ts&&...> forward_as_tuple(Ts&&... ts) noexcept
+    {
+        return tuple<Ts&&...>(forward<Ts>(ts)...);
+    }
+
+    template<class... Ts>
+    constexpr tuple<Ts&...> tie(Ts&... ts) noexcept
+    {
+        return tuple<Ts&...>(ts...);
+    }
+
+    template<class... Tuples>
+    constexpr aux::tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls)
+    { // TODO: currently does not work because of index mismatch
+        return aux::tuple_cat(
+            forward<Tuples>(tpls)...,
+            make_index_sequence<sizeof...(Tuples)>{},
+            aux::generate_indices_t<Tuples...>{}
+        );
+    }
+
+    /**
+     * 20.4.2.5, tuple helper classes:
+     */
+
+    template<class T>
+    class tuple_size; // undefined
+
+    template<class T>
+    class tuple_size<const T>
+        : public integral_constant<size_t, tuple_size<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    class tuple_size<volatile T>
+        : public integral_constant<size_t, tuple_size<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    class tuple_size<const volatile T>
+        : public integral_constant<size_t, tuple_size<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    class tuple_size<tuple<Ts...>>
+        : public integral_constant<size_t, sizeof...(Ts)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr size_t tuple_size_v = tuple_size<T>::value;
+
+    template<size_t I, class T>
+    class tuple_element; // undefined
+
+    template<size_t I, class T>
+    class tuple_element<I, const T>
+    {
+        using type = add_const_t<typename tuple_element<I, T>::type>;
+    };
+
+    template<size_t I, class T>
+    class tuple_element<I, volatile T>
+    {
+        using type = add_volatile_t<typename tuple_element<I, T>::type>;
+    };
+
+    template<size_t I, class T>
+    class tuple_element<I, const volatile T>
+    {
+        using type = add_cv_t<typename tuple_element<I, T>::type>;
+    };
+
+    namespace aux
+    {
+        template<size_t I, class T, class... Ts>
+        struct type_at: type_at<I - 1, Ts...>
+        { /* DUMMY BODY */ };
+
+        template<class T, class... Ts>
+        struct type_at<0, T, Ts...>
+        {
+            using type = T;
+        };
+
+        template<size_t I, class... Ts>
+        using type_at_t = typename type_at<I, Ts...>::type;
+    }
+
+    template<size_t I, class... Ts>
+    class tuple_element<I, tuple<Ts...>>
+    {
+        public:
+            using type = aux::type_at_t<I, Ts...>;
+    };
+
+    template<size_t I, class T>
+    using tuple_element_t = typename tuple_element<I, T>::type;
+
+    namespace aux
+    {
+        template<size_t I, class T>
+        struct tuple_element_wrapper
+        {
+            constexpr tuple_element_wrapper() = default;
+
+            constexpr explicit tuple_element_wrapper(T&& val)
+                : value{forward<T>(val)}
+            { /* DUMMY BODY */ }
+
+            template<
+                class U,
+                class = enable_if_t<
+                    is_convertible_v<U, T> && !is_same_v<U, T>,
+                    void
+                >
+            >
+            constexpr explicit tuple_element_wrapper(U&& val)
+                : value(forward<U>(val))
+            { /* DUMMY BODY */ }
+
+            T value;
+        };
+
+        template<class, class...>
+        class tuple_impl; // undefined
+
+        template<size_t... Is, class... Ts>
+        class tuple_impl<index_sequence<Is...>, Ts...>: public tuple_element_wrapper<Is, Ts>...
+        {
+            public:
+                constexpr tuple_impl()
+                    : tuple_element_wrapper<Is, Ts>{}...
+                { /* DUMMY BODY */ }
+
+                template<class... Us>
+                constexpr explicit tuple_impl(Us&&... us)
+                    : tuple_element_wrapper<Is, Ts>(forward<Us>(us))...
+                { /* DUMMY BODY */ }
+
+                template<class... Us>
+                constexpr tuple_impl(const tuple<Us...>& tpl)
+                    : tuple_impl{tpl, make_index_sequence<sizeof...(Us)>{}}
+                { /* DUMMY BODY */ }
+
+                template<class... Us>
+                constexpr tuple_impl(tuple<Us...>&& tpl)
+                    : tuple_impl{move<tuple<Us...>>(tpl), make_index_sequence<sizeof...(Us)>{}}
+                { /* DUMMY BODY */ }
+
+                template<class... Us, size_t... Iss>
+                constexpr tuple_impl(const tuple<Us...>& tpl, index_sequence<Iss...>)
+                    : tuple_impl{get<Iss>(tpl)...}
+                { /* DUMMY BODY */ }
+
+                template<class... Us, size_t... Iss>
+                constexpr tuple_impl(tuple<Us...>&& tpl, index_sequence<Iss...>)
+                    : tuple_impl{get<Iss>(move(tpl))...}
+                { /* DUMMY BODY */ }
+        };
+
+        template<class T, class... Ts>
+        struct tuple_noexcept_swap
+        {
+            static constexpr bool value = noexcept(std::swap(declval<T&>(), declval<T&>()))
+                && tuple_noexcept_swap<Ts...>::value;
+        };
+
+        template<class T>
+        struct tuple_noexcept_swap<T>
+        {
+            static constexpr bool value = noexcept(std::swap(declval<T&>(), declval<T&>()));
+        };
+
+        template<class T, class... Ts>
+        struct tuple_noexcept_assignment
+        {
+            static constexpr bool value = is_nothrow_move_assignable<T>::value
+                && tuple_noexcept_assignment<Ts...>::value;
+        };
+
+        template<class T>
+        struct tuple_noexcept_assignment<T>
+        {
+            static constexpr bool value = is_nothrow_move_assignable<T>::value;
+        };
+    }
+
+    /**
+     * 20.4.2.6, element access:
+     */
+
+    template<size_t I, class... Ts>
+    constexpr tuple_element_t<I, tuple<Ts...>>& get(tuple<Ts...>& tpl) noexcept
+    {
+        aux::tuple_element_wrapper<I, tuple_element_t<I, tuple<Ts...>>>& wrapper = tpl;
+
+        return wrapper.value;
+    }
+
+    template<size_t I, class... Ts>
+    constexpr tuple_element_t<I, tuple<Ts...>>&& get(tuple<Ts...>&& tpl) noexcept
+    {
+        return forward<typename tuple_element<I, tuple<Ts...>>::type&&>(get<I>(tpl));
+    }
+
+    template<size_t I, class... Ts>
+    constexpr const tuple_element_t<I, tuple<Ts...>>& get(const tuple<Ts...>& tpl) noexcept
+    {
+        const aux::tuple_element_wrapper<I, tuple_element_t<I, tuple<Ts...>>>& wrapper = tpl;
+
+        return wrapper.value;
+    }
+
+    namespace aux
+    {
+        template<size_t I, class U, class T, class... Ts>
+        struct index_of_type: index_of_type<I + 1, U, Ts...>
+        { /* DUMMY BODY */ };
+
+        template<size_t I, class T, class... Ts>
+        struct index_of_type<I, T, T, Ts...>: std::integral_constant<std::size_t, I>
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T, class... Ts>
+    constexpr T& get(tuple<Ts...>& tpl) noexcept
+    {
+        return get<aux::index_of_type<0, T, Ts...>::value>(tpl);
+    }
+
+    template<class T, class... Ts>
+    constexpr T&& get(tuple<Ts...>&& tpl) noexcept
+    {
+        return get<aux::index_of_type<0, T, Ts...>::value>(forward<tuple<Ts...>>(tpl));
+    }
+
+    template<class T, class... Ts>
+    constexpr const T& get(const tuple<Ts...>& tpl) noexcept
+    {
+        return get<aux::index_of_type<0, T, Ts...>::value>(tpl);
+    }
+
+    /**
+     * 20.4.2, class template tuple:
+     */
+
+    template<class... Ts>
+    class tuple: public aux::tuple_impl<make_index_sequence<sizeof...(Ts)>, Ts...>
+    {
+        using base_t = aux::tuple_impl<make_index_sequence<sizeof...(Ts)>, Ts...>;
+
+        public:
+
+            /**
+             * 20.4.2.1, tuple construction:
+             */
+
+            constexpr tuple()
+                : base_t{}
+            { /* DUMMY BODY */ }
+
+            constexpr explicit tuple(
+                const Ts&... ts, enable_if_t<sizeof...(Ts) != 0>* = nullptr)
+                : base_t(ts...)
+            { /* DUMMY BODY */ }
+
+            template<class... Us> // TODO: is_convertible == true for all Us to all Ts
+            constexpr explicit tuple(Us&&... us, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
+                : base_t(forward<Us>(us)...)
+            { /* DUMMY BODY */ }
+
+            tuple(const tuple&) = default;
+            tuple(tuple&&) = default;
+
+            template<class... Us>
+            constexpr tuple(const tuple<Us...>& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
+                : base_t(tpl)
+            { /* DUMMY BODY */ }
+
+            template<class... Us>
+            constexpr tuple(tuple<Us...>&& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
+                : base_t(move(tpl))
+            { /* DUMMY BODY */ }
+
+            // TODO: pair related construction and assignment needs convertibility, not size
+            template<class U1, class U2>
+            constexpr tuple(const pair<U1, U2>& p)
+                : base_t{}
+            {
+                get<0>(*this) = p.first;
+                get<1>(*this) = p.second;
+            }
+
+            template<class U1, class U2>
+            constexpr tuple(pair<U1, U2>&& p)
+                : base_t{}
+            {
+                get<0>(*this) = forward<U1>(p.first);
+                get<1>(*this) = forward<U2>(p.second);
+            }
+
+            // TODO: allocator-extended constructors
+
+            /**
+             * 20.4.2.2, tuple assignment:
+             */
+
+            tuple& operator=(const tuple& other)
+            {
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
+
+                return *this;
+            }
+
+            tuple& operator=(tuple&& other) noexcept(aux::tuple_noexcept_assignment<Ts...>::value)
+            {
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
+
+                return *this;
+            }
+
+            template<class... Us>
+            tuple& operator=(const tuple<Us...>& other)
+            {
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
+
+                return *this;
+            }
+
+            template<class... Us>
+            tuple& operator=(tuple<Us...>&& other)
+            {
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
+
+                return *this;
+            }
+
+            template<class U1, class U2>
+            tuple& operator=(const pair<U1, U2>& p)
+            {
+                get<0>(*this) = p.first;
+                get<1>(*this) = p.second;
+
+                return *this;
+            }
+
+            template<class U1, class U2>
+            tuple& operator=(pair<U1, U2>&& p)
+            {
+                get<0>(*this) = forward<U1>(p.first);
+                get<1>(*this) = forward<U2>(p.second);
+
+                return *this;
+            }
+
+            /**
+             * 20.4.2.3, tuple swap:
+             */
+
+            void swap(tuple& other) noexcept(aux::tuple_noexcept_swap<Ts...>::value)
+            {
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::swap(*this, other);
+            }
+    };
+
+    /**
+     * 20.4.2.7, relational operators:
+     */
+
+    template<class... Ts, class... Us>
+    constexpr bool operator==(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        if constexpr (sizeof...(Ts) == 0)
+            return true;
+        else
+            return aux::tuple_ops<0, sizeof...(Ts) - 1>::eq(lhs, rhs);
+    }
+
+    template<class... Ts, class... Us>
+    constexpr bool operator<(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        if constexpr (sizeof...(Ts) == 0)
+            return false;
+        else
+            return aux::tuple_ops<0, sizeof...(Ts) - 1>::lt(lhs, rhs);
+    }
+
+    template<class... Ts, class... Us>
+    constexpr bool operator!=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class... Ts, class... Us>
+    constexpr bool operator>(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class... Ts, class... Us>
+    constexpr bool operator<=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class... Ts, class... Us>
+    constexpr bool operator>=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    /**
+     * 20.4.2.8, allocator-related traits:
+     */
+
+    template<class... Ts, class Alloc>
+    struct uses_allocator<tuple<Ts...>, Alloc>: true_type
+    { /* DUMMY BODY */ };
+
+    /**
+     * 20.4.2.9, specialized algorithms:
+     */
+
+    template<class... Ts>
+    void swap(tuple<Ts...>& lhs, tuple<Ts...>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/type_traits/type_traits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/type_traits/type_traits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/type_traits/type_traits.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,1222 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_TYPE_TRAITS
+#define LIBCPP_BITS_TYPE_TRAITS
+
+#include <__bits/aux.hpp>
+#include <__bits/type_traits/references.hpp>
+#include <cstdlib>
+#include <cstddef>
+#include <cstdint>
+
+namespace std
+{
+    template<class T>
+    struct add_rvalue_reference;
+
+    template<class T>
+    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
+
+    template<class T>
+    add_rvalue_reference_t<T> declval() noexcept;
+
+    template<class...>
+    using void_t = void;
+
+    template<class>
+    struct remove_cv;
+
+    template<class T>
+    using remove_cv_t = typename remove_cv<T>::type;
+
+    namespace aux
+    {
+        template<class T, class U>
+        struct is_same: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T>
+        struct is_same<T, T>: true_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class... Ts>
+        struct is_one_of;
+
+        template<class T>
+        struct is_one_of<T>: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class... Ts>
+        struct is_one_of<T, T, Ts...>: true_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class U, class... Ts>
+        struct is_one_of<T, U, Ts...>: is_one_of<T, Ts...>
+        { /* DUMMY BODY */ };
+    }
+
+    /**
+     * 20.10.4.1, primary type categories:
+     */
+
+    template<class T>
+    struct is_void: aux::is_same<remove_cv_t<T>, void>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_void_v = is_void<T>::value;
+
+    template<class T>
+    struct is_null_pointer: aux::is_same<remove_cv_t<T>, nullptr_t>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
+
+    template<class T>
+    struct is_integral: aux::is_one_of<remove_cv_t<T>,
+            bool, char, unsigned char, signed char,
+            long, unsigned long, int, unsigned int, short,
+            unsigned short, long long, unsigned long long,
+            char16_t, char32_t, wchar_t>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_floating_point
+        : aux::is_one_of<remove_cv_t<T>, float, double, long double>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
+
+    template<class>
+    struct is_array: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_array<T[]>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_array_v = is_array<T>::value;
+
+    namespace aux
+    {
+        template<class>
+        struct is_pointer: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T>
+        struct is_pointer<T*>: true_type
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T>
+    struct is_pointer: aux::is_pointer<remove_cv_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_pointer_v = is_pointer<T>::value;
+
+    template<class T>
+    struct is_lvalue_reference: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_lvalue_reference<T&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
+
+    template<class T>
+    struct is_rvalue_reference: false_type
+    { /* DUMMY BODY*/ };
+
+    template<class T>
+    struct is_rvalue_reference<T&&>: true_type
+    { /* DUMMY BODY*/ };
+
+    template<class T>
+    inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
+
+    template<class>
+    struct is_member_pointer;
+
+    template<class>
+    struct is_member_function_pointer;
+
+    template<class T>
+    struct is_member_object_pointer
+        : integral_constant<bool, is_member_pointer<T>::value &&
+                            !is_member_function_pointer<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<T>::value;
+
+    template<class>
+    struct is_function;
+
+    namespace aux
+    {
+        template<class T>
+        struct is_member_function_pointer: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class U>
+        struct is_member_function_pointer<T U::*>: is_function<T>
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T>
+    struct is_member_function_pointer: aux::is_member_function_pointer<remove_cv_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<T>::value;
+
+    template<class T>
+    struct is_enum: aux::value_is<bool, __is_enum(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_enum_v = is_enum<T>::value;
+
+    template<class T>
+    struct is_union: aux::value_is<bool, __is_union(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_union_v = is_union<T>::value;
+
+    template<class T>
+    struct is_class: aux::value_is<bool, __is_class(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_class_v = is_class<T>::value;
+
+    /**
+     * Note: is_function taken from possile implementation on cppreference.com
+     */
+    template<class>
+    struct is_function: false_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...)>: true_type
+    { /* DUMMY BODY */ };
+
+    // Note: That hexadot covers variadic functions like printf.
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......)>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile &>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile &&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile & noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) volatile && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args...) const volatile && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) volatile && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class Ret, class... Args>
+    struct is_function<Ret(Args......) const volatile && noexcept>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_function_v = is_function<T>::value;
+
+    /**
+     * 20.10.4.2, composite type categories:
+     */
+
+    template<class T>
+    struct is_reference: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_reference<T&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_reference<T&&>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_reference_v = is_reference<T>::value;
+
+    template<class T>
+    struct is_arithmetic: aux::value_is<
+        bool,
+        is_integral<T>::value || is_floating_point<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
+
+    template<class T>
+    struct is_fundamental;
+
+    template<class T>
+    struct is_object;
+
+    template<class T>
+    struct is_scalar;
+
+    template<class T>
+    struct is_compound;
+
+    namespace aux
+    {
+        template<class T>
+        struct is_member_pointer: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class U>
+        struct is_member_pointer<T U::*>: true_type
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T>
+    struct is_member_pointer: aux::is_member_pointer<remove_cv_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
+
+    /**
+     * 20.10.4.3, type properties:
+     */
+
+    template<class T>
+    struct is_const: false_type
+    { /* DUMMY BODY */};
+
+    template<class T>
+    struct is_const<T const>: true_type
+    { /* DUMMY BODY */};
+
+    template<class T>
+    inline constexpr bool is_const_v = is_const<T>::value;
+
+    template<class T>
+    struct is_volatile: false_type
+    { /* DUMMY BODY */};
+
+    template<class T>
+    struct is_volatile<T volatile>: true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_volatile_v = is_volatile<T>::value;
+
+    /**
+     * 2 forward declarations.
+     */
+
+    template<class T>
+    struct is_trivially_copyable;
+
+    template<class T>
+    struct is_trivially_default_constructible;
+
+    template<class T>
+    struct is_trivial: aux::value_is<
+        bool,
+        is_trivially_copyable<T>::value &&
+        is_trivially_default_constructible<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_trivial_v = is_trivial<T>::value;
+
+    template<class T>
+    struct is_trivially_copyable: aux::value_is<bool, __has_trivial_copy(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
+
+    template<class T>
+    struct is_standard_layout: aux::value_is<bool, __is_standard_layout(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_pod: aux::value_is<bool, __is_pod(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_pod_v = is_pod<T>::value;
+
+    template<class T>
+    struct is_literal_type: aux::value_is<bool, __is_literal_type(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_literal_type_v = is_literal_type<T>::value;
+
+    template<class T>
+    struct is_empty: aux::value_is<bool, __is_empty(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_empty_v = is_empty<T>::value;
+
+    template<class T>
+    struct is_polymorphic: aux::value_is<bool, __is_polymorphic(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_polymorphic_v = is_polymorphic<T>::value;
+
+    template<class T>
+    struct is_abstract: aux::value_is<bool, __is_abstract(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_abstract_v = is_abstract<T>::value;
+
+    template<class T>
+    struct is_final: aux::value_is<bool, __is_final(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_final_v = is_final<T>::value;
+
+    namespace aux
+    {
+        /**
+         * Note: We cannot simply use !is_signed to define
+         *       is_unsigned because non-arithmetic types
+         *       are neither signer nor unsigned.
+         */
+        template<class T, bool = is_arithmetic<T>::value>
+        struct is_signed: value_is<bool, T(-1) < T(0)>
+        { /* DUMMY BODY */ };
+
+        template<class T>
+        struct is_signed<T, false>: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T, bool = is_arithmetic<T>::value>
+        struct is_unsigned: value_is<bool, T(0) < T(-1)>
+        { /* DUMMY BODY */ };
+
+        template<class T>
+        struct is_unsigned<T, false>: false_type
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T>
+    struct is_signed: aux::is_signed<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_signed_v = is_signed<T>::value;
+
+    template<class T>
+    struct is_unsigned: aux::is_unsigned<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
+
+    namespace aux
+    {
+        template<class, class T, class... Args>
+        struct is_constructible: false_type
+        { /* DUMMY BODY */ };
+
+        template<class T, class... Args>
+        struct is_constructible<
+            void_t<decltype(T(declval<Args>()...))>,
+            T, Args...
+        >
+            : true_type
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T, class... Args>
+    struct is_constructible: aux::is_constructible<void_t<>, T, Args...>
+    { /* DUMMY BODY */ };
+
+    template<class T, class... Args>
+    inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value;
+
+    template<class T>
+    struct is_default_constructible
+        : is_constructible<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_copy_constructible
+        : is_constructible<T, add_lvalue_reference<const T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_move_constructible
+        : is_constructible<T, add_rvalue_reference<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U, class = void>
+    struct is_assignable: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    struct is_assignable<T, U, void_t<decltype(declval<T>() = declval<U>())>>
+        : true_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_copy_assignable
+        : is_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_move_assignable
+        : is_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class, class = void>
+    struct is_destructible: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_destructible<T, void_t<decltype(declval<T&>().~T())>>
+        : true_type
+    { /* DUMMY BODY */ };
+
+    template<class T, class... Args>
+    struct is_trivially_constructible: aux::value_is<bool, __has_trivial_constructor(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<T>::value;
+
+    template<class T>
+    struct is_trivially_default_constructible
+        : is_trivially_constructible<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_trivially_copy_constructible: aux::value_is<bool, __has_trivial_copy(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value;
+
+    template<class T>
+    struct is_trivially_move_constructible
+        : is_trivially_constructible<T, add_rvalue_reference_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    struct is_trivially_assignable: aux::value_is<bool, __has_trivial_assign(T) && is_assignable<T, U>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
+
+    template<class T>
+    struct is_trivially_copy_assignable
+        : is_trivially_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_trivially_move_assignable
+        : is_trivially_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_trivially_destructible: aux::value_is<bool, __has_trivial_destructor(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
+
+    template<class T, class... Args>
+    struct is_nothrow_constructible: aux::value_is<bool, __has_nothrow_constructor(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T>::value;
+
+    template<class T>
+    struct is_nothrow_default_constructible
+        : is_nothrow_constructible<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_nothrow_copy_constructible: aux::value_is<bool, __has_nothrow_copy(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value;
+
+    template<class T>
+    struct is_nothrow_move_constructible
+        : is_nothrow_constructible<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    struct is_nothrow_assignable: aux::value_is<bool, __has_nothrow_assign(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
+
+    template<class T>
+    struct is_nothrow_copy_assignable
+        : is_nothrow_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_nothrow_move_assignable
+        : is_nothrow_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
+    { /* DUMMY BODY */ };
+
+    template<class, class = void>
+    struct is_nothrow_destructible: false_type
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct is_nothrow_destructible<T, void_t<decltype(declval<T&>().~T())>>
+        : aux::value_is<bool, noexcept(declval<T&>().~T())>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct has_virtual_destructor: aux::value_is<bool, __has_virtual_destructor(T)>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
+
+    /**
+     * 20.10.5, type property queries:
+     */
+
+    template<class T>
+    struct alignment_of: aux::value_is<std::size_t, alignof(T)>
+    { /* DUMMY BODY */ };
+
+    template<class>
+    struct rank : aux::value_is<size_t, 0u>
+    { /* DUMMY BODY */ };
+
+    template<class T, size_t N>
+    struct rank<T[N]>: aux::value_is<size_t, 1u + rank<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct rank<T[]>: aux::value_is<size_t, 1u + rank<T>::value>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr size_t rank_v = rank<T>::value;
+
+    template<class T, unsigned I = 0U>
+    struct extent: aux::value_is<size_t, 0U>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct extent<T[], 0U>: aux::value_is<size_t, 0U>
+    { /* DUMMY BODY */ };
+
+    template<class T, unsigned I>
+    struct extent<T[], I>: extent<T, I - 1>
+    { /* DUMMY BODY */ };
+
+    template<class T, size_t N>
+    struct extent<T[N], 0U>: aux::value_is<size_t, 0U>
+    { /* DUMMY BODY */ };
+
+    template<class T, unsigned I, size_t N>
+    struct extent<T[N], I>: extent<T, I - 1>
+    { /* DUMMY BODY */ };
+
+    /**
+     * 20.10.6, type relations:
+     */
+
+    template<class T, class U>
+    struct is_same: aux::is_same<T, U>
+    { /* DUMMY BODY */ };
+
+    template<class T, class U>
+    inline constexpr bool is_same_v = is_same<T, U>::value;
+
+    template<class Base, class Derived>
+    struct is_base_of: aux::value_is<bool, __is_base_of(Base, Derived)>
+    { /* DUMMY BODY */ };
+
+    template<class Base, class Derived>
+    inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
+
+    template<class From, class To, class = void>
+    struct is_convertible: false_type
+    { /* DUMMY BODY */ };
+
+    template<class From, class To>
+    struct is_convertible<From, To, void_t<decltype((To)declval<From>())>>
+        : true_type
+    { /* DUMMY BODY */ };
+
+    template<class From, class To>
+    inline constexpr bool is_convertible_v = is_convertible<From, To>::value;
+
+    /**
+     * 20.10.7.1, const-volatile modifications:
+     */
+
+    template<class T>
+    struct remove_const: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_const<T const>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_volatile: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_volatile<T volatile>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_cv: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_cv<T const>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_cv<T volatile>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_cv<T const volatile>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct add_const: aux::type_is<T const>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct add_volatile: aux::type_is<T volatile>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct add_cv: aux::type_is<T const volatile>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using remove_const_t = typename remove_const<T>::type;
+
+    template<class T>
+    using remove_volatile_t = typename remove_volatile<T>::type;
+
+    template<class T>
+    using remove_cv_t = typename remove_cv<T>::type;
+
+    template<class T>
+    using add_const_t = typename add_const<T>::type;
+
+    template<class T>
+    using add_volatile_t = typename add_volatile<T>::type;
+
+    template<class T>
+    using add_cv_t = typename add_cv<T>::type;
+
+    /**
+     * 20.10.7.3, sign modifications:
+     * Note: These are fairly naive implementations that
+     *       are meant to keep our code going (i.e. they work
+     *       for the most common types, but I'm not sure
+     *       if there are any intricacies required by
+     *       the standard).
+     */
+
+    template<class T>
+    struct make_signed: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<char>: aux::type_is<signed char>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<unsigned char>: aux::type_is<signed char>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<unsigned short>: aux::type_is<short>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<unsigned int>: aux::type_is<int>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<unsigned long>: aux::type_is<long>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_signed<unsigned long long>: aux::type_is<long long>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct make_unsigned: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<char>: aux::type_is<unsigned char>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<signed char>: aux::type_is<unsigned char>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<short>: aux::type_is<unsigned short>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<int>: aux::type_is<unsigned int>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<long>: aux::type_is<unsigned long>
+    { /* DUMMY BODY */ };
+
+    template<>
+    struct make_unsigned<long long>: aux::type_is<unsigned long long>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using make_signed_t = typename make_signed<T>::type;
+
+    template<class T>
+    using make_unsigned_t = typename make_signed<T>::type;
+
+    /**
+     * 20.10.7.4, array modifications:
+     */
+
+    template<class T>
+    struct remove_extent: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_extent<T[]>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T, size_t N>
+    struct remove_extent<T[N]>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_all_extents: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_all_extents<T[]>: remove_all_extents<T>
+    { /* DUMMY BODY */ };
+
+    template<class T, size_t N>
+    struct remove_all_extents<T[N]>: remove_all_extents<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using remove_extent_t = typename remove_extent<T>::type;
+
+    template<class T>
+    using remove_all_extents_t = typename remove_all_extents<T>::type;
+
+    /**
+     * 20.10.7.5, pointer modifications:
+     */
+
+    template<class T>
+    struct remove_pointer: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_pointer<T*>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_pointer<T* const>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_pointer<T* volatile>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_pointer<T* const volatile>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    namespace aux
+    {
+        template<class T>
+        struct add_pointer_to_function: type_is<T>
+        { /* DUMMY BODY */ };
+
+        template<class T, class... Args>
+        struct add_pointer_to_function<T(Args...)>
+            : type_is<T(*)(Args...)>
+        { /* DUMMY BODY */ };
+
+        template<class T, bool = false>
+        struct add_pointer_cond: aux::type_is<remove_reference_t<T>*>
+        { /* DUMMY BODY */ };
+
+        template<class T>
+        struct add_pointer_cond<T, true>
+            : aux::add_pointer_to_function<T>
+        { /* DUMMY BODY */ };
+    }
+
+    template<class T>
+    struct add_pointer: aux::add_pointer_cond<T, is_function_v<T>>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using remove_pointer_t = typename remove_pointer<T>::type;
+
+    template<class T>
+    using add_pointer_t = typename add_pointer<T>::type;
+
+    /**
+     * 20.10.7.6, other transformations:
+     */
+
+    namespace aux
+    {
+        template<size_t Len, size_t Align>
+        struct aligned_t
+        {
+            alignas(Align) uint8_t storage[Len];
+        };
+
+        template<class T>
+        constexpr T max_of_cont(T cont)
+        {
+            if (cont.size() == 0U)
+                return T{};
+
+            auto it = cont.begin();
+            auto res = *it;
+
+            while (++it != cont.end())
+            {
+                if (*it > res)
+                    res = *it;
+            }
+
+            return res;
+        }
+    }
+
+    // TODO: consult standard on the default value of align
+    template<std::size_t Len, std::size_t Align = 0>
+    struct aligned_storage: aux::type_is<aux::aligned_t<Len, Align>>
+    { /* DUMMY BODY */ };
+
+    template<std::size_t Len, class... Types>
+    struct aligned_union: aux::type_is<
+        aux::aligned_t<
+            aux::max_of_cont({Len, alignof(Types)...}),
+            aux::max_of_cont({alignof(Types)...})
+        >
+    >
+    { /* DUMMY BODY */ };
+
+	// TODO: this is very basic implementation for chrono, fix!
+    /* template<class T> */
+    /* struct decay: aux::type_is<remove_cv_t<remove_reference_t<T>>> */
+	/* { /1* DUMMY BODY *1/ }; */
+
+    template<bool, class, class>
+    struct conditional;
+
+    template<class T>
+    struct decay: aux::type_is<
+        typename conditional<
+            is_array_v<remove_reference_t<T>>,
+            remove_extent_t<remove_reference_t<T>>*,
+            typename conditional<
+                is_function_v<remove_reference_t<T>>,
+                add_pointer_t<remove_reference_t<T>>,
+                remove_cv_t<remove_reference_t<T>>
+            >::type
+        >::type
+    >
+    { /* DUMMY BODY */ };
+
+	template<class T>
+    using decay_t = typename decay<T>::type;
+
+    template<bool, class T = void>
+    struct enable_if
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct enable_if<true, T>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<bool, class T, class F>
+    struct conditional: aux::type_is<F>
+    { /* DUMMY BODY */ };
+
+    template<class T, class F>
+    struct conditional<true, T, F>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class... T>
+    struct common_type
+    { /* DUMMY BODY */ };
+
+    template<class... T>
+    using common_type_t = typename common_type<T...>::type;
+
+    template<class T>
+    struct common_type<T>: common_type<T, T>
+    { /* DUMMY BODY */ };
+
+    // To avoid circular dependency with <utility>.
+    template<class T>
+    add_rvalue_reference_t<T> declval() noexcept;
+
+    template<class T1, class T2>
+    struct common_type<T1, T2>: aux::type_is<decay_t<decltype(false ? declval<T1>() : declval<T2>())>>
+    { /* DUMMY BODY */ };
+
+    template<class T1, class T2, class... Ts>
+    struct common_type<T1, T2, Ts...>
+        : aux::type_is<common_type_t<common_type_t<T1, T2>, Ts...>>
+    { /* DUMMY BODY */ };
+
+    template<class... T>
+    struct underlying_type;
+
+    template<std::size_t Len, std::size_t Align = 0>
+    using aligned_storage_t = typename aligned_storage<Len, Align>::type;
+
+    template<std::size_t Len, class... Types>
+    using aligned_union_t = typename aligned_union<Len, Types...>::type;
+
+    template<bool b, class T = void>
+    using enable_if_t = typename enable_if<b, T>::type;
+
+    template<bool b, class T, class F>
+    using conditional_t = typename conditional<b, T, F>::type;
+
+    template<class T>
+    using underlying_type_t = typename underlying_type<T>::type;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/typeindex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/typeindex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/typeindex.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_TYPE_INDEX
+#define LIBCPP_BITS_TYPE_INDEX
+
+#include <cstdlib>
+#include <typeinfo>
+
+namespace std
+{
+
+    /**
+     * 20.14.2, type_index:
+     */
+
+    class type_index
+    {
+        public:
+            type_index(const type_info& rhs) noexcept;
+
+            bool operator==(const type_index& rhs) const noexcept;
+
+            bool operator!=(const type_index& rhs) const noexcept;
+
+            bool operator<(const type_index& rhs) const noexcept;
+
+            bool operator<=(const type_index& rhs) const noexcept;
+
+            bool operator>(const type_index& rhs) const noexcept;
+
+            bool operator>=(const type_index& rhs) const noexcept;
+
+            size_t hash_code() const noexcept;
+
+            const char* name() const noexcept;
+
+        private:
+            const type_info* target_;
+    };
+
+    template<class T>
+    struct hash;
+
+    // TODO: implement
+    template<>
+    struct hash<type_index>;
+}
+
+#endif
Index: uspace/lib/cpp/include/__bits/typeinfo.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/typeinfo.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/typeinfo.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_TYPE_INFO
+#define LIBCPP_BITS_TYPE_INFO
+
+#include <cstdlib>
+
+namespace std
+{
+
+class type_info
+{
+    public:
+        virtual ~type_info();
+
+        bool operator==(const type_info&) const noexcept;
+        bool operator!=(const type_info&) const noexcept;
+
+        bool before(const type_info&) const noexcept;
+
+        size_t hash_code() const noexcept;
+
+        const char* name() const noexcept;
+
+        type_info(const type_info&) = delete;
+        type_info& operator=(const type_info&) = delete;
+
+    private:
+        const char* __name;
+};
+
+    // TODO: class bad_cast, bad_typeid
+}
+
+#endif
+
Index: uspace/lib/cpp/include/__bits/utility/utility.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/utility/utility.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
+++ uspace/lib/cpp/include/__bits/utility/utility.hpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2018 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_UTILITY
+#define LIBCPP_BITS_UTILITY
+
+#include <__bits/type_transformation.hpp>
+#include <__bits/utility/forward_move.hpp>
+#include <cstdint>
+#include <type_traits>
+
+namespace std
+{
+    /**
+     * 20.2.1, operators:
+     */
+
+    namespace rel_ops
+    {
+        template<typename T>
+        bool operator!=(const T& lhs, const T& rhs)
+        {
+            return !(lhs == rhs);
+        }
+
+        template<typename T>
+        bool operator>(const T& lhs, const T& rhs)
+        {
+            return (rhs < lhs);
+        }
+
+        template<typename T>
+        bool operator<=(const T& lhs, const T& rhs)
+        {
+            return !(rhs < lhs);
+        }
+
+        template<typename T>
+        bool operator>=(const T& lhs, const T& rhs)
+        {
+            return !(lhs < rhs);
+        }
+    }
+
+    /**
+     * 20.2.2, swap:
+     */
+
+    template<class T>
+    void swap(T& x, T& y)
+        /* noexcept(is_nothrow_move_constructible<T>::value && */
+        /*          is_nothrow_move_assignable<T>::value) */
+    {
+        T tmp{move(x)};
+        x = move(y);
+        y = move(tmp);
+    }
+
+    template<class F1, class F2>
+    F2 swap_ranges(F1, F1, F2);
+
+    template<class T, size_t N>
+    void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)))
+    {
+        swap_ranges(a, a + N, b);
+    }
+
+    /**
+     * 20.2.3, exchange:
+     */
+
+    template<class T, class U = T>
+    T exchange(T& obj, U&& new_val)
+    {
+        T old_val = move(obj);
+        obj = forward<U>(new_val);
+
+        return old_val;
+    }
+
+    /**
+     * 20.5.2, class template integer_sequence:
+     */
+
+    template<class T, T... Is>
+    struct integer_sequence
+    {
+        using value_type = T;
+
+        static constexpr size_t size() noexcept
+        {
+            return sizeof...(Is);
+        }
+
+        using next = integer_sequence<T, Is..., sizeof...(Is)>;
+    };
+
+    template<std::size_t... Is>
+    using index_sequence = integer_sequence<std::size_t, Is...>;
+
+    /**
+     * 20.5.3, alias template make_integer_sequence:
+     */
+
+    namespace aux
+    {
+        template<class T, uintmax_t N>
+        struct make_integer_sequence
+        {
+            /**
+             * Recursive to the bottom case below, appends sizeof...(Is) in
+             * every next "call", building the sequence.
+             */
+            using type = typename make_integer_sequence<T, N - 1>::type::next;
+        };
+
+        template<class T>
+        struct make_integer_sequence<T, std::uintmax_t(0)>
+        {
+            using type = integer_sequence<T>;
+        };
+    }
+
+
+    /**
+     * Problem: We can't specialize the N parameter because it is a value parameter
+     *          depending on a type parameter.
+     * Solution: According to the standard: if N is negative, the program is ill-formed,
+     *           so we just recast it to uintmax_t :)
+     */
+    template<class T, T N>
+    using make_integer_sequence = typename aux::make_integer_sequence<T, std::uintmax_t(N)>::type;
+
+    template<size_t N>
+    using make_index_sequence = make_integer_sequence<std::size_t, N>;
+
+    /**
+     * 20.3, pairs:
+     */
+
+    template<size_t, class>
+    class tuple_element;
+
+    template<size_t I, class T>
+    using tuple_element_t = typename tuple_element<I, T>::type;
+
+    template<class...>
+    class tuple;
+
+    template<size_t I, class... Ts>
+    constexpr tuple_element_t<I, tuple<Ts...>>&& get(tuple<Ts...>&&) noexcept;
+
+    namespace aux
+    {
+        template<class T, class... Args, size_t... Is>
+        T from_tuple(tuple<Args...>&& tpl, index_sequence<Is...>)
+        {
+            return T{get<Is>(move(tpl))...};
+        }
+
+        template<class T, class... Args>
+        T from_tuple(tuple<Args...>&& tpl)
+        {
+            return from_tuple<T>(move(tpl), make_index_sequence<sizeof...(Args)>{});
+        }
+    }
+
+    struct piecewise_construct_t
+    {
+        explicit piecewise_construct_t() = default;
+    };
+
+    inline constexpr piecewise_construct_t piecewise_construct{};
+
+    template<typename T1, typename T2>
+    struct pair
+    {
+        using first_type  = T1;
+        using second_type = T2;
+
+        T1 first;
+        T2 second;
+
+        pair(const pair&) = default;
+        pair(pair&&) = default;
+
+        constexpr pair()
+            : first{}, second{}
+        { /* DUMMY BODY */ }
+
+        constexpr pair(const T1& x, const T2& y)
+            : first{x}, second{y}
+        { /* DUMMY BODY */ }
+
+        template<typename U, typename V>
+        constexpr pair(U&& x, V&& y)
+            : first(x), second(y)
+        { /* DUMMY BODY */ }
+
+        template<typename U, typename V>
+        constexpr pair(const pair<U, V>& other)
+            : first(other.first), second(other.second)
+        { /* DUMMY BODY */ }
+
+        template<typename U, typename V>
+        constexpr pair(pair<U, V>&& other)
+            : first(forward<first_type>(other.first)),
+              second(forward<second_type>(other.second))
+        { /* DUMMY BODY */ }
+
+        template<class... Args1, class... Args2>
+        pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args)
+            : first{aux::from_tuple<first_type>(move(first_args))},
+              second{aux::from_tuple<second_type>(move(second_args))}
+        { /* DUMMY BODY */ }
+
+        pair& operator=(const pair& other)
+        {
+            first = other.first;
+            second = other.second;
+
+            return *this;
+        }
+
+        template<typename U, typename V>
+        pair& operator=(const pair<U, V>& other)
+        {
+            first = other.first;
+            second = other.second;
+
+            return *this;
+        }
+
+        pair& operator=(pair&& other) noexcept
+        {
+            first = forward<first_type>(other.first);
+            second = forward<second_type>(other.second);
+
+            return *this;
+        }
+
+        template<typename U, typename V>
+        pair& operator=(pair<U, V>&& other)
+        {
+            first = forward<first_type>(other.first);
+            second = forward<second_type>(other.second);
+
+            return *this;
+        }
+
+        void swap(pair& other) noexcept(
+            noexcept(std::swap(first, other.first)) &&
+            noexcept(std::swap(second, other.second))
+        )
+        {
+            std::swap(first, other.first);
+            std::swap(second, other.second);
+        }
+    };
+
+    /**
+     * 20.3.3, specialized algorithms:
+     */
+
+    template<class T1, class T2>
+    constexpr bool operator==(const pair<T1, T2>& lhs,
+                              const pair<T1, T2>& rhs)
+    {
+        return lhs.first == rhs.first && lhs.second == rhs.second;
+    }
+
+    template<class T1, class T2>
+    constexpr bool operator<(const pair<T1, T2>& lhs,
+                             const pair<T1, T2>& rhs)
+    {
+        return lhs.first < rhs.first ||
+            (!(rhs.first < lhs.first) && lhs.second < rhs.second);
+    }
+
+    template<class T1, class T2>
+    constexpr bool operator!=(const pair<T1, T2>& lhs,
+                              const pair<T1, T2>& rhs)
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class T1, class T2>
+    constexpr bool operator>(const pair<T1, T2>& lhs,
+                             const pair<T1, T2>& rhs)
+    {
+        return rhs < lhs;
+    }
+
+    template<class T1, class T2>
+    constexpr bool operator>=(const pair<T1, T2>& lhs,
+                              const pair<T1, T2>& rhs)
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class T1, class T2>
+    constexpr bool operator<=(const pair<T1, T2>& lhs,
+                              const pair<T1, T2>& rhs)
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class T1, class T2>
+    constexpr void swap(pair<T1, T2>& lhs, pair<T1, T2>& rhs)
+        noexcept(noexcept(lhs.swap(rhs)))
+    {
+        lhs.swap(rhs);
+    }
+
+    template<class T1, class T2>
+    constexpr auto make_pair(T1&& t1, T2&& t2)
+    {
+        return pair<
+            aux::transform_tuple_types_t<T1>,
+            aux::transform_tuple_types_t<T2>
+        >{
+            forward<T1>(t1), forward<T2>(t2)
+        };
+    }
+
+    /**
+     * 20.3.4, tuple-like access to pair:
+     */
+
+    template<class>
+    struct tuple_size;
+
+    template<class T1, class T2>
+    struct tuple_size<pair<T1, T2>>
+        : integral_constant<size_t, 2>
+    { /* DUMMY BODY */ };
+
+    template<size_t, class>
+    struct tuple_element;
+
+    template<class T1, class T2>
+    struct tuple_element<0, pair<T1, T2>>
+        : aux::type_is<T1>
+    { /* DUMMY BODY */ };
+
+    template<class T1, class T2>
+    struct tuple_element<1, pair<T1, T2>>
+        : aux::type_is<T2>
+    { /* DUMMY BODY */ };
+
+    template<size_t I, class T>
+    using tuple_element_t = typename tuple_element<I, T>::type;
+
+    template<size_t I, class T1, class T2>
+    constexpr tuple_element_t<I, pair<T1, T2>>&
+    get(pair<T1, T2>& p) noexcept
+    {
+        if constexpr (I == 0)
+            return p.first;
+        else
+            return p.second;
+    }
+
+    template<size_t I, class T1, class T2>
+    constexpr const tuple_element_t<I, pair<T1, T2>>&
+    get(const pair<T1, T2>& p) noexcept
+    {
+        if constexpr (I == 0)
+            return p.first;
+        else
+            return p.second;
+    }
+
+    template<size_t I, class T1, class T2>
+    constexpr tuple_element_t<I, pair<T1, T2>>&&
+    get(pair<T1, T2>&& p) noexcept
+    {
+        if constexpr (I == 0)
+            return forward<T1>(p.first);
+        else
+            return forward<T2>(p.second);
+    }
+
+    template<class T, class U>
+    constexpr T& get(pair<T, U>& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<0>(p);
+    }
+
+    template<class T, class U>
+    constexpr const T& get(const pair<T, U>& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<0>(p);
+    }
+
+    template<class T, class U>
+    constexpr T&& get(pair<T, U>&& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<0>(move(p));
+    }
+
+    template<class T, class U>
+    constexpr T& get(pair<U, T>& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<1>(p);
+    }
+
+    template<class T, class U>
+    constexpr const T& get(const pair<U, T>& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<1>(p);
+    }
+
+    template<class T, class U>
+    constexpr T&& get(pair<U, T>&& p) noexcept
+    {
+        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
+
+        return get<1>(move(p));
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/algorithm
===================================================================
--- uspace/lib/cpp/include/algorithm	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/algorithm	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/algorithm.hpp>
+#include <__bits/algorithm.hpp>
Index: uspace/lib/cpp/include/array
===================================================================
--- uspace/lib/cpp/include/array	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/array	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/array.hpp>
+#include <__bits/adt/array.hpp>
Index: uspace/lib/cpp/include/atomic
===================================================================
--- uspace/lib/cpp/include/atomic	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/atomic	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/atomic.hpp>
+#include <__bits/atomic.hpp>
Index: uspace/lib/cpp/include/bitset
===================================================================
--- uspace/lib/cpp/include/bitset	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/bitset	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/bitset.hpp>
+#include <__bits/adt/bitset.hpp>
Index: uspace/lib/cpp/include/chrono
===================================================================
--- uspace/lib/cpp/include/chrono	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/chrono	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/chrono.hpp>
+#include <__bits/chrono.hpp>
Index: uspace/lib/cpp/include/cinttypes
===================================================================
--- uspace/lib/cpp/include/cinttypes	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/cinttypes	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -3,5 +3,5 @@
  * All rights reserved.
  *
- * Redistribution and using in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -12,5 +12,5 @@
  *   notice, this list of conditions and the following disclaimer in the
  *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be usingd to endorse or promote products
+ * - The name of the author may not be used to endorse or promote products
  *   derived from this software without specific prior written permission.
  *
Index: uspace/lib/cpp/include/complex
===================================================================
--- uspace/lib/cpp/include/complex	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/complex	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/complex.hpp>
+#include <__bits/complex.hpp>
Index: uspace/lib/cpp/include/condition_variable
===================================================================
--- uspace/lib/cpp/include/condition_variable	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/condition_variable	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/condition_variable.hpp>
+#include <__bits/thread/condition_variable.hpp>
Index: uspace/lib/cpp/include/deque
===================================================================
--- uspace/lib/cpp/include/deque	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/deque	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/deque.hpp>
+#include <__bits/adt/deque.hpp>
Index: uspace/lib/cpp/include/exception
===================================================================
--- uspace/lib/cpp/include/exception	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/exception	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/exception.hpp>
+#include <__bits/exception.hpp>
Index: uspace/lib/cpp/include/forward_list
===================================================================
--- uspace/lib/cpp/include/forward_list	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/forward_list	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/forward_list.hpp>
+#include <__bits/adt/forward_list.hpp>
Index: uspace/lib/cpp/include/fstream
===================================================================
--- uspace/lib/cpp/include/fstream	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/fstream	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/fstream.hpp>
+#include <__bits/io/fstream.hpp>
Index: uspace/lib/cpp/include/functional
===================================================================
--- uspace/lib/cpp/include/functional	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/functional	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,8 +27,8 @@
  */
 
-#include <impl/functional.hpp>
 #include <__bits/functional/arithmetic_operations.hpp>
 #include <__bits/functional/bind.hpp>
 #include <__bits/functional/function.hpp>
+#include <__bits/functional/functional.hpp>
 #include <__bits/functional/invoke.hpp>
 #include <__bits/functional/hash.hpp>
Index: uspace/lib/cpp/include/future
===================================================================
--- uspace/lib/cpp/include/future	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/future	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/future.hpp>
+#include <__bits/thread/future.hpp>
Index: uspace/lib/cpp/include/impl/algorithm.hpp
===================================================================
--- uspace/lib/cpp/include/impl/algorithm.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1154 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_ALGORITHM
-#define LIBCPP_ALGORITHM
-
-#include <iterator>
-#include <utility>
-
-namespace std
-{
-    template<class T>
-    struct less;
-
-    /**
-     * 25.2, non-modyfing sequence operations:
-     */
-
-    /**
-     * 25.2.1, all_of:
-     */
-
-    template<class InputIterator, class Predicate>
-    bool all_of(InputIterator first, InputIterator last, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (!pred(*first++))
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 25.2.2, any_of:
-     */
-
-    template<class InputIterator, class Predicate>
-    bool any_of(InputIterator first, InputIterator last, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (pred(*first++))
-                return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * 25.2.3, none_of:
-     */
-
-    template<class InputIterator, class Predicate>
-    bool none_of(InputIterator first, InputIterator last, Predicate pred)
-    {
-        return !any_of(first, last, pred);
-    }
-
-    /**
-     * 25.2.4, for_each:
-     */
-
-    template<class InputIterator, class Function>
-    Function for_each(InputIterator first, InputIterator last, Function f)
-    {
-        while (first != last)
-            f(*first++);
-
-        return move(f);
-    }
-
-    /**
-     * 25.2.5, find:
-     */
-
-    template<class InputIterator, class T>
-    InputIterator find(InputIterator first, InputIterator last, const T& value)
-    {
-        while (first != last)
-        {
-            if (*first == value)
-                return first;
-            ++first;
-        }
-
-        return last;
-    }
-
-    template<class InputIterator, class Predicate>
-    InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (pred(*first))
-                return first;
-            ++first;
-        }
-
-        return last;
-    }
-
-    template<class InputIterator, class Predicate>
-    InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (!pred(*first))
-                return first;
-            ++first;
-        }
-
-        return last;
-    }
-
-    /**
-     * 25.2.6, find_end:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.2.7, find_first:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.2.8, adjacent_find:
-     */
-
-    template<class ForwardIterator>
-    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)
-    {
-        while (first != last)
-        {
-            if (*first == *(first + 1))
-                return first;
-            ++first;
-        }
-
-        return last;
-    }
-
-    template<class ForwardIterator, class Predicate>
-    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (pred(*first, *(first + 1)))
-                return first;
-            ++first;
-        }
-
-        return last;
-    }
-
-    /**
-     * 25.2.9, count:
-     */
-
-    template<class InputIterator, class T>
-    typename iterator_traits<InputIterator>::difference_type
-    count(InputIterator first, InputIterator last, const T& value)
-    {
-        typename iterator_traits<InputIterator>::difference_type cnt{};
-
-        while (first != last)
-        {
-            if (*first++ == value)
-                ++cnt;
-        }
-
-        return cnt;
-    }
-
-    template<class InputIterator, class Predicate>
-    typename iterator_traits<InputIterator>::difference_type
-    count_if(InputIterator first, InputIterator last, Predicate pred)
-    {
-        typename iterator_traits<InputIterator>::difference_type cnt{};
-
-        while (first != last)
-        {
-            if (pred(*first++))
-                ++cnt;
-        }
-
-        return cnt;
-    }
-
-    /**
-     * 25.2.10, mismatch:
-     */
-
-    template<class InputIterator1, class InputIterator2>
-    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
-                                                  InputIterator2 first2)
-    {
-        while (first1 != last1 && *first1 == *first2)
-        {
-            ++first1;
-            ++first2;
-        }
-
-        return make_pair(first1, first2);
-    }
-
-    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
-    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
-                                                  InputIterator2 first2, BinaryPredicate pred)
-    {
-        while (first1 != last1 && pred(*first1, *first2))
-        {
-            ++first1;
-            ++first2;
-        }
-
-        return make_pair(first1, first2);
-    }
-
-    template<class InputIterator1, class InputIterator2>
-    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
-                                                  InputIterator2 first2, InputIterator2 last2)
-    {
-        while (first1 != last1 && first2 != last2 && *first1 == *first2)
-        {
-            ++first1;
-            ++first2;
-        }
-
-        return make_pair(first1, first2);
-    }
-
-    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
-    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1,
-                                                  InputIterator2 first2, InputIterator2 last2,
-                                                  BinaryPredicate pred)
-    {
-        while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
-        {
-            ++first1;
-            ++first2;
-        }
-
-        return make_pair(first1, first2);
-    }
-
-    /**
-     * 25.2.11, equal:
-     */
-
-    template<class InputIterator1, class InputIterator2>
-    bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
-    {
-        while (first1 != last1)
-        {
-            if (*first1++ != *first2++)
-                return false;
-        }
-
-        return true;
-    }
-
-    template<class InputIterator1, class InputIterator2>
-    bool equal(InputIterator1 first1, InputIterator1 last1,
-               InputIterator2 first2, InputIterator2 last2)
-    {
-        while (first1 != last1 && first2 != last2)
-        {
-            if (*first1++ != *first2++)
-                return false;
-        }
-
-        return true;
-    }
-
-    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
-    bool equal(InputIterator1 first1, InputIterator1 last1,
-               InputIterator2 first2, BinaryPredicate pred)
-    {
-        while (first1 != last1)
-        {
-            if (!pred(*first1++, *first2++))
-                return false;
-        }
-
-        return true;
-    }
-
-    template<class InputIterator1, class InputIterator2, class BinaryPredicate>
-    bool equal(InputIterator1 first1, InputIterator1 last1,
-               InputIterator2 first2, InputIterator2 last2,
-               BinaryPredicate pred)
-    {
-        while (first1 != last1 && first2 != last2)
-        {
-            if (!pred(*first1++, *first2++))
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * 25.2.12, is_permutation:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.2.13, search:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.3, mutating sequence operations:
-     */
-
-    /**
-     * 25.3.1, copy:
-     */
-
-    template<class InputIterator, class OutputIterator>
-    OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
-    {
-        while (first != last)
-            *result++ = *first++;
-
-        return result;
-    }
-
-    template<class InputIterator, class Size, class OutputIterator>
-    OutputIterator copy_n(InputIterator first, Size count, OutputIterator result)
-    {
-        for (Size i = 0; i < count; ++i, ++first, ++result)
-            *result = *first;
-
-        return result;
-    }
-
-    template<class InputIterator, class OutputIterator, class Predicate>
-    OutputIterator copy_if(InputIterator first, InputIterator last,
-                           OutputIterator result, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (pred(*first))
-                *result++ = *first;
-            ++first;
-        }
-
-        return result;
-    }
-
-    template<class BidirectionalIterator1, class BidirectionalIterator2>
-    BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
-                                         BidirectionalIterator2 result)
-    {
-        // Note: We're copying [first, last) so we need to skip the initial value of last.
-        while (last-- != first)
-            *result-- = *last;
-
-        return result;
-    }
-
-    /**
-     * 25.3.2, move:
-     */
-
-    template<class InputIterator, class OutputIterator>
-    OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
-    {
-        while (first != last)
-            *result++ = move(*first++);
-
-        return result;
-    }
-
-    template<class BidirectionalIterator1, class BidirectionalIterator2>
-    BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
-                                         BidirectionalIterator2 result)
-    {
-        // Note: We're copying [first, last) so we need to skip the initial value of last.
-        while (last-- != first)
-            *result-- = move(*last);
-    }
-
-    /**
-     * 25.3.3, swap:
-     */
-
-    template<class ForwardIterator1, class ForwardIterator2>
-    ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
-                                 ForwardIterator2 first2)
-    {
-        while (first1 != last1)
-            swap(*first1++, *first2++);
-
-        return first2;
-    }
-
-    template<class ForwardIterator1, class ForwardIterator2>
-    void iter_swap(ForwardIterator1 iter1, ForwardIterator2 iter2)
-    {
-        swap(*iter1, *iter2);
-    }
-
-    /**
-     * 25.3.4, transform:
-     */
-
-    template<class InputIterator, class OutputIterator, class UnaryOperation>
-    OutputIterator transform(InputIterator first, InputIterator last,
-                             OutputIterator result, UnaryOperation op)
-    {
-        while (first != last)
-            *result++ = op(*first++);
-
-        return result;
-    }
-
-    template<class InputIterator1, class InputIterator2,
-             class OutputIterator, class BinaryOperation>
-    OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
-                             InputIterator2 first2, OutputIterator result,
-                             BinaryOperation op)
-    {
-        while (first1 != last1)
-            *result++ = op(*first1++, *first2++);
-
-        return result;
-    }
-
-    /**
-     * 25.3.5, replace:
-     */
-
-    template<class ForwardIterator, class T>
-    void replace(ForwardIterator first, ForwardIterator last,
-                 const T& old_value, const T& new_value)
-    {
-        while (first != last)
-        {
-            if (*first == old_value)
-                *first = new_value;
-            ++first;
-        }
-    }
-
-    template<class ForwardIterator, class Predicate, class T>
-    void replace_if(ForwardIterator first, ForwardIterator last,
-                    Predicate pred, const T& new_value)
-    {
-        while (first != last)
-        {
-            if (pred(*first))
-                *first = new_value;
-            ++first;
-        }
-    }
-
-    template<class InputIterator, class OutputIterator, class T>
-    OutputIterator replace_copy(InputIterator first, InputIterator last,
-                                OutputIterator result, const T& old_value,
-                                const T& new_value)
-    {
-        while (first != last)
-        {
-            if (*first == old_value)
-                *result = new_value;
-            else
-                *result = *first;
-
-            ++first;
-            ++result;
-        }
-    }
-
-    template<class InputIterator, class OutputIterator, class Predicate, class T>
-    OutputIterator replace_copy_if(InputIterator first, InputIterator last,
-                                OutputIterator result, Predicate pred,
-                                const T& new_value)
-    {
-        while (first != last)
-        {
-            if (pred(*first))
-                *result = new_value;
-            else
-                *result = *first;
-
-            ++first;
-            ++result;
-        }
-    }
-
-    /**
-     * 25.3.6, fill:
-     */
-
-    template<class ForwardIterator, class T>
-    void fill(ForwardIterator first, ForwardIterator last, const T& value)
-    {
-        while (first != last)
-            *first++ = value;
-    }
-
-    template<class InputIterator, class Size, class T>
-    void fill_n(InputIterator first, Size count, const T& value)
-    {
-        for (Size i = 0; i < count; ++i)
-            *first++ = value;
-    }
-
-    /**
-     * 25.3.7, generate:
-     */
-
-    template<class ForwardIterator, class Generator>
-    void generate(ForwardIterator first, ForwardIterator last,
-                  Generator gen)
-    {
-        while (first != last)
-            *first++ = gen();
-    }
-
-    template<class OutputIterator, class Size, class Generator>
-    void generate(OutputIterator first, Size count, Generator gen)
-    {
-        for (Size i = 0; i < count; ++i)
-            *first++ = gen();
-    }
-
-    /**
-     * 25.3.8, remove:
-     */
-
-    template<class ForwardIterator, class T>
-    ForwardIterator remove(ForwardIterator first, ForwardIterator last,
-                           const T& value)
-    {
-        auto it = first;
-        while (it != last)
-        {
-            if (*it != value)
-                *first++ = move(*it);
-        }
-
-        return first;
-    }
-
-    template<class ForwardIterator, class Predicate>
-    ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
-                              Predicate pred)
-    {
-        auto it = first;
-        while (it != last)
-        {
-            if (!pred(*it))
-                *first++ = move(*it);
-        }
-
-        return first;
-    }
-
-    template<class InputIterator, class OutputIterator, class T>
-    OutputIterator remove_copy(InputIterator first, InputIterator last,
-                               OutputIterator result, const T& value)
-    {
-        while (first != last)
-        {
-            if (*first != value)
-                *result++ = *first;
-            ++first;
-        }
-
-        return result;
-    }
-
-    template<class InputIterator, class OutputIterator, class Predicate>
-    OutputIterator remove_copy_if(InputIterator first, InputIterator last,
-                                  OutputIterator result, Predicate pred)
-    {
-        while (first != last)
-        {
-            if (!pred(*first))
-                *result++ = *first;
-            ++first;
-        }
-
-        return result;
-    }
-
-    /**
-     * 25.3.9, unique:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.3.10, reverse:
-     */
-
-    template<class BidirectionalIterator>
-    void reverse(BidirectionalIterator first, BidirectionalIterator last)
-    {
-        if (first == last)
-            return;
-        auto mid_count = (last - first) / 2;
-
-        --last;
-        for (decltype(mid_count) i = 0; i < mid_count; ++i)
-            iter_swap(first++, last--);
-    }
-
-    template<class BidirectionalIterator, class OutputIterator>
-    OutputIterator reverse_copy(BidirectionalIterator first,
-                                BidirectionalIterator last,
-                                OutputIterator result)
-    {
-        while (--last != first)
-            *result++ = *last;
-    }
-
-    /**
-     * 25.3.11, rotate:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.3.12, shuffle:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.3.13, partitions:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4, sorting and related operations:
-     */
-
-    /**
-     * 25.4.1, sorting:
-     */
-
-    /**
-     * 25.4.1.1, sort:
-     */
-
-    template<class RandomAccessIterator, class Compare>
-    void make_heap(RandomAccessIterator, RandomAccessIterator,
-                   Compare);
-
-    template<class RandomAccessIterator, class Compare>
-    void sort_heap(RandomAccessIterator, RandomAccessIterator,
-                   Compare);
-
-    template<class RandomAccessIterator>
-    void sort(RandomAccessIterator first, RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        sort(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    void sort(RandomAccessIterator first, RandomAccessIterator last,
-              Compare comp)
-    {
-        /**
-         * Note: This isn't the most effective approach,
-         *       but since we already have these two functions
-         *       and they satisfy asymptotic limitations
-         *       imposed by the standard, we're using them at
-         *       the moment. Might be good to change it to qsort
-         *       or merge sort later.
-         */
-
-        make_heap(first, last, comp);
-        sort_heap(first, last, comp);
-    }
-
-    /**
-     * 25.4.1.2, stable_sort:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.1.3, partial_sort:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.1.4, partial_sort_copy:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.1.5, is_sorted:
-     */
-
-    template<class ForwardIterator>
-    bool is_sorted(ForwardIterator first, ForwardIterator last)
-    {
-        return is_sorted_until(first, last) == last;
-    }
-
-    template<class ForwardIterator, class Comp>
-    bool is_sorted(ForwardIterator first, ForwardIterator last,
-                   Comp comp)
-    {
-        return is_sorted_until(first, last, comp) == last;
-    }
-
-    template<class ForwardIterator>
-    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last)
-    {
-        if (distance(first, last) < 2)
-            return last;
-
-        while (first != last)
-        {
-            if (*first > *(++first))
-                return first;
-        }
-
-        return last;
-    }
-
-    template<class ForwardIterator, class Comp>
-    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last,
-                                    Comp comp)
-    {
-        if (distance(first, last) < 2)
-            return last;
-
-        while (first != last)
-        {
-            if (!comp(*first, *(++first)))
-                return first;
-        }
-
-        return last;
-    }
-
-    /**
-     * 25.4.2, nth_element:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.3, binary search:
-     */
-
-    /**
-     * 25.4.3.1, lower_bound
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.3.2, upper_bound
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.3.3, equal_range:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.3.4, binary_search:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.4, merge:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.5, set operations on sorted structures:
-     */
-
-    /**
-     * 25.4.5.1, includes:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.5.2, set_union:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.5.3, set_intersection:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.5.4, set_difference:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.5.5, set_symmetric_difference:
-     */
-
-    // TODO: implement
-
-    /**
-     * 25.4.6, heap operations:
-     */
-
-    namespace aux
-    {
-        template<class T>
-        T heap_parent(T idx)
-        {
-            return (idx - 1) / 2;
-        }
-
-        template<class T>
-        T heap_left_child(T idx)
-        {
-            return 2 * idx + 1;
-        }
-
-        template<class T>
-        T heap_right_child(T idx)
-        {
-            return 2 * idx + 2;
-        }
-
-        template<class RandomAccessIterator, class Size, class Compare>
-        void correct_children(RandomAccessIterator first,
-                              Size idx, Size count, Compare comp)
-        {
-            using aux::heap_left_child;
-            using aux::heap_right_child;
-
-            auto left = heap_left_child(idx);
-            auto right = heap_right_child(idx);
-
-            bool left_incorrect{comp(first[idx], first[left])};
-            bool right_incorrect{comp(first[idx], first[right])};
-            while ((left < count && left_incorrect) ||
-                   (right < count && right_incorrect))
-            {
-                if (right >= count || (left_incorrect && comp(first[right], first[left])))
-                {
-                    swap(first[idx], first[left]);
-
-                    idx = left;
-                }
-                else if (right < count && right_incorrect)
-                {
-                    swap(first[idx], first[right]);
-
-                    idx = right;
-                } // Else should not happen because of the while condition.
-
-                left = heap_left_child(idx);
-                right = heap_right_child(idx);
-
-                left_incorrect = comp(first[idx], first[left]);
-                right_incorrect = comp(first[idx], first[right]);
-            }
-        }
-    }
-
-    /**
-     * 25.4.6.1, push_heap:
-     */
-
-    template<class RandomAccessIterator>
-    void push_heap(RandomAccessIterator first,
-                   RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        push_heap(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    void push_heap(RandomAccessIterator first,
-                   RandomAccessIterator last,
-                   Compare comp)
-    {
-        using aux::heap_parent;
-
-        auto count = distance(first, last);
-        if (count <= 1)
-            return;
-
-        auto idx = count - 1;
-        auto parent = heap_parent(idx);
-        while (idx > 0 && comp(first[parent], first[idx]))
-        {
-            swap(first[idx], first[parent]);
-
-            idx = parent;
-            parent = heap_parent(idx);
-        }
-    }
-
-    /**
-     * 25.4.6.2, pop_heap:
-     */
-
-    template<class RandomAccessIterator>
-    void pop_heap(RandomAccessIterator first,
-                  RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        pop_heap(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    void pop_heap(RandomAccessIterator first,
-                  RandomAccessIterator last,
-                  Compare comp)
-    {
-        auto count = distance(first, last);
-        if (count <= 1)
-            return;
-
-        swap(first[0], first[count - 1]);
-        aux::correct_children(first, decltype(count){}, count - 2, comp);
-    }
-
-    /**
-     * 25.4.6.3, make_heap:
-     */
-
-    template<class RandomAccessIterator>
-    void make_heap(RandomAccessIterator first,
-                   RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        make_heap(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    void make_heap(RandomAccessIterator first,
-                   RandomAccessIterator last,
-                   Compare comp)
-    {
-        auto count = distance(first, last);
-        if (count <= 1)
-            return;
-
-        for (auto i = count; i > 0; --i)
-        {
-            auto idx = i - 1;
-
-            aux::correct_children(first, idx, count, comp);
-        }
-    }
-
-    /**
-     * 25.4.6.4, sort_heap:
-     */
-
-    template<class RandomAccessIterator>
-    void sort_heap(RandomAccessIterator first,
-                   RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        sort_heap(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    void sort_heap(RandomAccessIterator first,
-                   RandomAccessIterator last,
-                   Compare comp)
-    {
-        while (first != last)
-            pop_heap(first, last--, comp);
-    }
-
-    /**
-     * 25.4.6.5, is_heap:
-     */
-
-    template<class RandomAccessIterator>
-    auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last)
-    {
-        using value_type = typename iterator_traits<RandomAccessIterator>::value_type;
-
-        return is_heap_until(first, last, less<value_type>{});
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last,
-                       Compare comp)
-    {
-        using aux::heap_left_child;
-        using aux::heap_right_child;
-
-        auto count = distance(first, last);
-        if (count < 2)
-            return last;
-
-        auto res = first;
-        for (decltype(count) idx = 0; idx < count; ++idx)
-        {
-            auto left = heap_left_child(idx);
-            auto right = heap_right_child(idx);
-
-            if (left < count && comp(first[idx], first[left]))
-                return res;
-            if (right < count && comp(first[idx], first[right]))
-                return res;
-
-            ++res;
-        }
-
-        return res;
-    }
-
-    template<class RandomAccessIterator>
-    bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
-    {
-        return is_heap_until(first, last) == last;
-    }
-
-    template<class RandomAccessIterator, class Compare>
-    bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
-                 Compare comp)
-    {
-        return is_heap_until(first, last, comp) == last;
-    }
-
-    /**
-     * 25.4.7, minimum and maximum:
-     * // TODO: implement container versions when we have
-     *          numeric limits and min/max element
-     * // TODO: versions with comparators
-     * // TODO: minmax
-     */
-
-    template<class T>
-    constexpr const T& min(const T& lhs, const T& rhs)
-    {
-        return (lhs < rhs) ? lhs : rhs;
-    }
-
-    template<class T>
-    constexpr const T& max(const T& lhs, const T& rhs)
-    {
-        return (lhs > rhs) ? lhs : rhs;
-    }
-
-    /**
-     * 25.4.8, lexicographical comparison:
-     */
-
-    template<class InputIterator1, class InputIterator2>
-    bool lexicographical_compare(InputIterator1 first1,
-                                 InputIterator1 last1,
-                                 InputIterator2 first2,
-                                 InputIterator2 last2)
-    {
-        /**
-         * *first1 and *first2 can have different types
-         * so we use a transparent comparator.
-         */
-        return lexicographical_compare(
-            first1, last1, first2, last2,
-            less<void>{}
-        );
-    }
-
-    template<class InputIterator1, class InputIterator2, class Compare>
-    bool lexicographical_compare(InputIterator1 first1,
-                                 InputIterator1 last1,
-                                 InputIterator2 first2,
-                                 InputIterator2 last2,
-                                 Compare comp)
-    {
-        while ((first1 != last1) && (first2 != last2))
-        {
-            if (comp(*first1, *first2))
-                return true;
-            if (comp(*first2, *first1))
-                return false;
-
-            ++first1;
-            ++first2;
-        }
-
-        /**
-         * Up until now they are same, so we have to check
-         * if we reached the end on one.
-         */
-        return (first1 == last1) && (first2 != last2);
-    }
-
-    /**
-     * 25.4.9, permutation generators:
-     */
-
-    // TODO: implement
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/array.hpp
===================================================================
--- uspace/lib/cpp/include/impl/array.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,223 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_ARRAY
-#define LIBCPP_ARRAY
-
-#include <iterator>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 23.3.2, class template array:
-     */
-
-    template<class T, size_t N>
-    struct array
-    {
-        using value_type             = T;
-        using reference              = T&;
-        using const_reference        = const T&;
-        using size_type              = size_t;
-        using difference_type        = ptrdiff_t;
-        using pointer                = T*;
-        using const_pointer          = const T*;
-        using iterator               = pointer;
-        using const_iterator         = const_pointer;
-        using reverse_iterator       = std::reverse_iterator<iterator>;
-        using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-        /**
-         * Note: In the case of N == 0 the standard mandates that
-         *       begin() == end() which is achieved by setting the size
-         *       to 1. Return value of data() is unspecified and front()
-         *       and back() cause undefined behavior.
-         */
-        value_type elems[N ? N : 1];
-
-        void fill(const T& x)
-        {
-            fill_n(begin(), N, x);
-        }
-
-        void swap(array& other)
-                // TODO: Does not find declval atm :/
-                /* noexcept(noexcept(swap(declval<T&>(), declval<T&>()))) */
-        {
-            swap_ranges(begin(), end(), other.begin());
-        }
-
-        iterator begin() noexcept
-        {
-            return &elems[0];
-        }
-
-        iterator end() noexcept
-        {
-            return &elems[0] + N;
-        }
-
-        reverse_iterator rbegin() noexcept
-        {
-            return make_reverse_iterator(end());
-        }
-
-        reverse_iterator rend() noexcept
-        {
-            return make_reverse_iterator(begin());
-        }
-
-        const_iterator cbegin() const noexcept
-        {
-            return &elems[0];
-        }
-
-        const_iterator cend() const noexcept
-        {
-            return &elems[0] + N;
-        }
-
-        const_reverse_iterator crbegin() const noexcept
-        {
-            return make_reverse_iterator(end());
-        }
-
-        const_reverse_iterator crend() const noexcept
-        {
-            return make_reverse_iterator(begin());
-        }
-
-        reference operator[](size_type idx)
-        {
-            return elems[idx];
-        }
-
-        constexpr const_reference operator[](size_type idx) const
-        {
-            return elems[idx];
-        }
-
-        reference at(size_type idx)
-        {
-            // TODO: Bounds checking.
-            return elems[idx];
-        }
-
-        constexpr const_reference at(size_type idx) const
-        {
-            // TODO: Bounds checking.
-            return elems[idx];
-        }
-
-        reference front()
-        {
-            return elems[0];
-        }
-
-        constexpr const_reference front() const
-        {
-            return elems[0];
-        }
-
-        reference back()
-        {
-            return elems[N - 1];
-        }
-
-        constexpr const_reference back() const
-        {
-            return elems[N - 1];
-        }
-
-        pointer data() noexcept
-        {
-            return &elems[0];
-        }
-
-        const_pointer data() const noexcept
-        {
-            return &elems[0];
-        }
-
-        size_type size() const noexcept
-        {
-            return N;
-        }
-    };
-
-    template<class T, size_t N>
-    void swap(array<T, N>& lhs, array<T, N>& rhs) noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 23.3.2.9, tuple interface for class template array:
-     */
-
-    template<class>
-    struct tuple_size;
-
-    template<class T, size_t N>
-    struct tuple_size<array<T, N>>
-        : integral_constant<size_t, N>
-    { /* DUMMY BODY */ };
-
-    template<size_t, class>
-    struct tuple_element;
-
-    template<size_t I, class T, size_t N>
-    struct tuple_element<I, array<T, N>>
-        : aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<size_t I, class T, size_t N>
-    constexpr T& get(array<T, N>& arr) noexcept
-    {
-        static_assert(I < N, "index out of bounds");
-
-        return arr[I];
-    }
-
-    template<size_t I, class T, size_t N>
-    constexpr T&& get(array<T, N>&& arr) noexcept
-    {
-        return move(get<I>(arr));
-    }
-
-    template<size_t I, class T, size_t N>
-    constexpr const T& get(const array<T, N>& arr) noexcept
-    {
-        static_assert(I < N, "index out of bounds");
-
-        return arr[I];
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/atomic.hpp
===================================================================
--- uspace/lib/cpp/include/impl/atomic.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_ATOMIC
-#define LIBCPP_ATOMIC
-
-#error "<atomic> is not implemented"
-
-#endif
Index: uspace/lib/cpp/include/impl/bitset.hpp
===================================================================
--- uspace/lib/cpp/include/impl/bitset.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,510 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_BITSET
-#define LIBCPP_BITSET
-
-#include <iosfwd>
-#include <string>
-
-namespace std
-{
-    /**
-     * 20.6, class template bitset:
-     */
-
-    template<size_t N>
-    class bitset
-    {
-        public:
-            class reference
-            {
-                friend class bitset;
-
-                public:
-                    ~reference() noexcept = default;
-
-                    reference& operator=(bool val) noexcept
-                    {
-                        if (val)
-                            data_ |= mask_;
-                        else
-                            data_ &= ~mask_;
-                    }
-
-                    reference& operator=(const reference& other) noexcept
-                    {
-                        if (other)
-                            data_ |= mask_;
-                        else
-                            data_ &= ~mask_;
-                    }
-
-                    bool operator~() const noexcept
-                    {
-                        return data_ & mask_;
-                    }
-
-                    operator bool() const noexcept
-                    {
-                        return data_ & mask_;
-                    }
-
-                    reference& flip() noexcept
-                    {
-                        data_ ^= mask_;
-
-                        return *this;
-                    }
-
-                private:
-                    reference() noexcept = delete;
-
-                    using data_type = typename bitset::data_type;
-
-                    data_type& data_;
-                    data_type mask_;
-
-                    reference(data_type& data, size_t idx)
-                        : data_{data}, mask_{bitset::one_ << idx}
-                    { /* DUMMY BODY */ }
-            };
-
-            /**
-             * 20.6.1, constructors:
-             */
-
-            constexpr bitset() noexcept
-            {
-                init_(zero_);
-            }
-
-            constexpr bitset(unsigned long long val) noexcept
-            {
-                init_(val);
-            }
-
-            template<class Char, class Traits, class Allocator>
-            explicit bitset(
-                const basic_string<Char, Traits, Allocator>& str,
-                typename basic_string<Char, Traits, Allocator>::size_type pos = 0,
-                typename basic_string<Char, Traits, Allocator>::size_type n =
-                    basic_string<Char, Traits, Allocator>::npos,
-                Char zero = Char('0'), Char one = Char('1')
-            )
-            {
-                // TODO: throw out_of_range if pos > str.size()
-
-                init_(zero_);
-                auto len = n < (str.size() - pos) ? n : (str.size() - pos);
-                len = len < N ? len : N;
-
-                for (size_t i = 0, j = pos + len - 1; i < len; ++i, --j)
-                {
-                    if (Traits::eq(str[j], zero))
-                        set(i, false);
-                    else if (Traits::eq(str[j], one))
-                        set(i, true);
-                    // TODO: else throw invalid_argument
-                }
-            }
-
-            template<class Char>
-            explicit bitset(
-                const Char* str,
-                typename basic_string<Char>::size_type n = basic_string<Char>::npos,
-                Char zero = Char('0'), Char one = Char('1')
-            )
-                : bitset{
-                    n == basic_string<Char>::npos ? basic_string<Char>{str} : basic_string<Char>{str, n},
-                    0, n, zero, one
-                  }
-            { /* DUMMY BODY */ }
-
-            /**
-             * 20.6.2, bitset operations:
-             */
-
-            bitset<N>& operator&=(const bitset<N>& rhs) noexcept
-            {
-                for (size_t i = 0; i < data_size_; ++i)
-                    data_[i] &= rhs.data_[i];
-
-                return *this;
-            }
-
-            bitset<N>& operator|=(const bitset<N>& rhs) noexcept
-            {
-                for (size_t i = 0; i < data_size_; ++i)
-                    data_[i] |= rhs.data_[i];
-
-                return *this;
-            }
-
-            bitset<N>& operator^=(const bitset<N>& rhs) noexcept
-            {
-                for (size_t i = 0; i < data_size_; ++i)
-                    data_[i] ^= rhs.data_[i];
-
-                return *this;
-            }
-
-            bitset<N>& operator<<=(size_t pos) noexcept
-            {
-                for (size_t i = N; i > 1; --i)
-                {
-                    if (i < pos)
-                        set(i - 1, false);
-                    else
-                        set(i - 1, test(i - 1 - pos));
-                }
-
-                return *this;
-            }
-
-            bitset<N>& operator>>=(size_t pos) noexcept
-            {
-                for (size_t i = 0; i < N; ++i)
-                {
-                    if (pos >= N - i)
-                        set(i, false);
-                    else
-                        set(i, test(i + pos));
-                }
-
-                return *this;
-            }
-
-            bitset<N>& set() noexcept
-            {
-                for (size_t i = 0; i < N; ++i)
-                    set(i);
-
-                return *this;
-            }
-
-            bitset<N>& set(size_t pos, bool val = true)
-            {
-                // TODO: throw out_of_range if pos > N
-                set_bit_(get_data_idx_(pos), get_bit_idx_(pos), val);
-
-                return *this;
-            }
-
-            bitset<N>& reset() noexcept
-            {
-                for (size_t i = 0; i < N; ++i)
-                    reset(i);
-
-                return *this;
-            }
-
-            bitset<N>& reset(size_t pos)
-            {
-                set_bit_(get_data_idx_(pos), get_bit_idx_(pos), false);
-
-                return *this;
-            }
-
-            bitset<N> operator~() const noexcept
-            {
-                bitset<N> res{*this};
-
-                return res.flip();
-            }
-
-            bitset<N>& flip() noexcept
-            {
-                for (size_t i = 0; i < N; ++i)
-                    flip(i);
-
-                return *this;
-            }
-
-            bitset<N>& flip(size_t pos)
-            {
-                return set(pos, !test(pos));
-            }
-
-            constexpr bool operator[](size_t pos) const
-            {
-                /**
-                 * Note: The standard doesn't mention any exception
-                 *       here being thrown at any time, so we shouldn't
-                 *       use test().
-                 */
-                return get_bit_(data_[get_data_idx_(pos)], get_bit_idx_(pos));
-            }
-
-            reference operator[](size_t pos)
-            {
-                return reference{data_[get_data_idx_(pos)], get_bit_idx_(pos)};
-            }
-
-            unsigned long to_ulong() const
-            {
-                // TODO: throw overflow_error if N > bits in ulong
-                return static_cast<unsigned long>(data_[0] & (~0UL));
-            }
-
-            unsigned long long to_ullong() const
-            {
-                // TODO: throw overflow_error if N > bits_in_data_type_
-                return data_[0];
-            }
-
-            template<
-                class Char = char,
-                class Traits = char_traits<Char>,
-                class Allocator = allocator<Char>
-            >
-            basic_string<Char, Traits, Allocator> to_string(Char zero = Char('0'),
-                                                            Char one = Char('1')) const
-            {
-                basic_string<Char, Traits, Allocator> res{};
-                res.reserve(N);
-                for (size_t i = N; i > 0; --i)
-                {
-                    if (test(i - 1))
-                        res.push_back(one);
-                    else
-                        res.push_back(zero);
-                }
-
-                return res;
-            }
-
-            size_t count() const noexcept
-            {
-                size_t res{};
-                for (size_t i = 0; i < N; ++i)
-                {
-                    if (test(i))
-                        ++res;
-                }
-
-                return res;
-            }
-
-            constexpr size_t size() const noexcept
-            {
-                return N;
-            }
-
-            bool operator==(const bitset<N>& rhs) const noexcept
-            {
-                for (size_t i = 0; i < data_size_; ++i)
-                {
-                    if (data_[i] != rhs.data_[i])
-                        return false;
-                }
-
-                return true;
-            }
-
-            bool operator!=(const bitset<N>& rhs) const noexcept
-            {
-                return !(*this == rhs);
-            }
-
-            bool test(size_t pos) const
-            {
-                // TODO: throw out of range if pos > N
-                return get_bit_(data_[get_data_idx_(pos)], get_bit_idx_(pos));
-            }
-
-            bool all() const noexcept
-            {
-                return count() == size();
-            }
-
-            bool any() const noexcept
-            {
-                return count() != 0;
-            }
-
-            bool none() const noexcept
-            {
-                return count() == 0;
-            }
-
-            bitset<N> operator<<(size_t pos) const noexcept
-            {
-                return bitset<N>{*this} <<= pos;
-            }
-
-            bitset<N> operator>>(size_t pos) const noexcept
-            {
-                return bitset<N>{*this} >>= pos;
-            }
-
-        private:
-            /**
-             * While this might be a bit more wasteful
-             * than using unsigned or unsigned long,
-             * it will make parts of out code easier
-             * to read.
-             */
-            using data_type = unsigned long long;
-
-            static constexpr size_t bits_in_data_type_ = sizeof(data_type) * 8;
-            static constexpr size_t data_size_ = N / bits_in_data_type_ + 1;
-
-            /**
-             * These are useful for masks, if we use literals
-             * then forgetting to add ULL or changing the data
-             * type could result in wrong indices being computed.
-             */
-            static constexpr data_type zero_ = data_type{0};
-            static constexpr data_type one_ = data_type{1};
-
-            data_type data_[data_size_];
-
-            void init_(data_type val)
-            {
-                data_type mask{~zero_};
-                if (N < bits_in_data_type_)
-                    mask >>= N;
-                data_[0] = val & mask;
-
-                for (size_t i = 1; i < data_size_; ++i)
-                    data_[i] = data_type{};
-            }
-
-            size_t get_data_idx_(size_t pos) const
-            {
-                return pos / bits_in_data_type_;
-            }
-
-            size_t get_bit_idx_(size_t pos) const
-            {
-                return pos % bits_in_data_type_;
-            }
-
-            bool get_bit_(data_type data, size_t bit_idx) const
-            {
-                return data & (one_ << bit_idx);
-            }
-
-            void set_bit_(size_t data_idx, size_t bit_idx, bool val)
-            {
-                if (val)
-                    data_[data_idx] |= (one_ << bit_idx);
-                else
-                    data_[data_idx] &= ~(one_ << bit_idx);
-            }
-    };
-
-    /**
-     * 20.6.3 hash support:
-     */
-
-    template<class T>
-    struct hash;
-
-    template<size_t N>
-    struct hash<bitset<N>>
-    {
-        size_t operator()(const bitset<N>& set) const noexcept
-        {
-            return hash<unsigned long long>{}(set.to_ullong());
-        }
-
-        using argument_type = bitset<N>;
-        using result_type   = size_t;
-    };
-
-    /**
-     * 20.6.4, bitset operators:
-     */
-
-    template<size_t N>
-    bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
-    {
-        return bitset<N>{lhs} &= rhs;
-    }
-
-    template<size_t N>
-    bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
-    {
-        return bitset<N>{lhs} |= rhs;
-    }
-
-    template<size_t N>
-    bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept
-    {
-        return bitset<N>{lhs} ^= rhs;
-    }
-
-    template<class Char, class Traits, size_t N>
-    basic_istream<Char, Traits>&
-    operator>>(basic_istream<Char, Traits>& is, bitset<N>& set)
-    {
-        size_t i{};
-        Char c{};
-        Char zero{is.widen('0')};
-        Char one{is.widen('1')};
-
-        basic_string<Char, Traits> str{};
-        while (i < N)
-        {
-            if (is.eof())
-                break;
-
-            is.get(c);
-
-            if (!Traits::eq(c, one) && !Traits::eq(c, zero))
-            {
-                is.putback(c);
-                break;
-            }
-
-            str.push_back(c);
-            ++i;
-        }
-
-        if (i == 0)
-            is.setstate(ios_base::failbit);
-
-        set = bitset<N>{str};
-
-        return is;
-    }
-
-    template<class Char, class Traits, size_t N>
-    basic_ostream<Char, Traits>&
-    operator<<(basic_ostream<Char, Traits>& os, const bitset<N>& set)
-    {
-        return os << set.template to_string<Char, Traits, allocator<Char>>(
-            use_facet<ctype<Char>>(os.getloc()).widen('0'),
-            use_facet<ctype<Char>>(os.getloc()).widen('1')
-        );
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/chrono.hpp
===================================================================
--- uspace/lib/cpp/include/impl/chrono.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,759 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_CHRONO
-#define LIBCPP_CHRONO
-
-#include <ctime>
-#include <limits>
-#include <ratio>
-#include <type_traits>
-
-namespace std::chrono
-{
-    /**
-     * 20.12.5, class template duration:
-     */
-
-    // Forward declarations.
-    template<class Rep, class Period = ratio<1>>
-    class duration;
-
-    template<class ToDuration, class Rep, class Period>
-    constexpr ToDuration duration_cast(const duration<Rep, Period>& dur);
-
-    template<class Rep>
-    struct duration_values;
-
-    template<class Rep, class Period>
-    class duration
-    {
-        public:
-            using rep    = Rep;
-            using period = Period;
-
-            /**
-             * 20.12.5.1, construct/copy/destroy:
-             */
-
-            constexpr duration() = default;
-
-            // TODO: check remarks to these two constructors, need is_convertible
-            template<class Rep2>
-            constexpr explicit duration(const Rep2& r)
-                : rep_{r}
-            { /* DUMMY BODY */ }
-
-            template<class Rep2, class Period2>
-            constexpr duration(const duration<Rep2, Period2>& other)
-                : rep_{duration_cast<duration>(other).count()}
-            { /* DUMMY BODY */ }
-
-            ~duration() = default;
-
-            duration(const duration&) = default;
-
-            duration& operator=(const duration&) = default;
-
-            /**
-             * 20.12.5.2, observer:
-             */
-
-            constexpr rep count() const
-            {
-                return rep_;
-            }
-
-            /**
-             * 20.12.5.3, arithmetic:
-             */
-
-            constexpr duration operator+() const
-            {
-                return *this;
-            }
-
-            constexpr duration operator-() const
-            {
-                return duration{-rep_};
-            }
-
-            duration& operator++()
-            {
-                ++rep_;
-
-                return *this;
-            }
-
-            duration operator++(int)
-            {
-                return duration{rep_++};
-            }
-
-            duration& operator--()
-            {
-                --rep_;
-
-                *this;
-            }
-
-            duration operator--(int)
-            {
-                return duration{rep_--};
-            }
-
-            duration& operator+=(const duration& rhs)
-            {
-                rep_ += rhs.count();
-
-                return *this;
-            }
-
-            duration& operator-=(const duration& rhs)
-            {
-                rep_ -= rhs.count();
-
-                return *this;
-            }
-
-            duration& operator*=(const rep& rhs)
-            {
-                rep_ *= rhs;
-
-                return *this;
-            }
-
-            duration& operator/=(const rep& rhs)
-            {
-                rep_ /= rhs;
-
-                return *this;
-            }
-
-            duration& operator%=(const rep& rhs)
-            {
-                rep_ %= rhs;
-
-                return *this;
-            }
-
-            duration& operator%=(const duration& rhs)
-            {
-                rep_ %= rhs.count();
-
-                return *this;
-            }
-
-            /**
-             * 20.12.5.4, special values:
-             */
-
-            static constexpr duration zero()
-            {
-                return duration{duration_values<rep>::zero()};
-            }
-
-            static constexpr duration min()
-            {
-                return duration{duration_values<rep>::min()};
-            }
-
-            static constexpr duration max()
-            {
-                return duration{duration_values<rep>::max()};
-            }
-
-        private:
-            rep rep_;
-    };
-
-    /**
-     * 20.12.6, class template time_point:
-     */
-
-    template<class Clock, class Duration = typename Clock::duration>
-    class time_point
-    {
-        public:
-            using clock    = Clock;
-            using duration = Duration;
-            using rep      = typename duration::rep;
-            using period   = typename duration::period;
-
-            /**
-             * 20.12.6.1, construct:
-             */
-
-            constexpr time_point()
-                : duration_{duration::zero()}
-            { /* DUMMY BODY */ }
-
-            constexpr explicit time_point(const duration& d)
-                : duration_{d}
-            { /* DUMMY BODY */ }
-
-            // TODO: see remark to this constuctor
-            template<class Duration2>
-            constexpr time_point(const time_point<clock, Duration2>& other)
-                : duration_{static_cast<duration>(other.time_since_epoch())}
-            { /* DUMMY BODY */ }
-
-            /**
-             * 20.12.6.2, observer:
-             */
-
-            constexpr duration time_since_epoch() const
-            {
-                return duration_;
-            }
-
-            /**
-             * 20.12.6.3, arithmetic:
-             */
-
-            time_point& operator+=(const duration& rhs)
-            {
-                duration_ += rhs;
-
-                return *this;
-            }
-
-            time_point& operator-=(const duration& rhs)
-            {
-                duration_ -= rhs;
-
-                return *this;
-            }
-
-            /**
-             * 20.12.6.4, special values:
-             */
-
-            static constexpr time_point min()
-            {
-                return time_point{duration::min()};
-            }
-
-            static constexpr time_point max()
-            {
-                return time_point{duration::max()};
-            }
-
-        private:
-            duration duration_;
-    };
-}
-
-namespace std
-{
-    /**
-     * 20.12.4.3, common_type specializations:
-     */
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>
-    {
-        using type = chrono::duration<
-            common_type_t<Rep1, Rep2>,
-            ratio<aux::gcd_v<Period1::num, Period2::num>, aux::lcm_v<Period1::den, Period2::den>>
-        >;
-    };
-
-    template<class Clock, class Duration1, class Duration2>
-    struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>
-    {
-        using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
-    };
-}
-
-namespace std::chrono
-{
-    /**
-     * 20.12.4, customization traits:
-     */
-
-    template<class Rep>
-    struct treat_as_floating_point: is_floating_point<Rep>
-    { /* DUMMY BODY */ };
-
-    template<class Rep>
-    struct duration_values
-    {
-        static constexpr Rep zero()
-        {
-            // Note: Using Rep(0) instead of Rep{} is intentional, do not change.
-            return Rep(0);
-        }
-
-        static constexpr Rep min()
-        {
-            return numeric_limits<Rep>::lowest();
-        }
-
-        static constexpr Rep max()
-        {
-            return numeric_limits<Rep>::max();
-        }
-    };
-
-    /**
-     * 20.12.5.5, duration arithmetic:
-     */
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
-    operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
-        return CD(CD(lhs.count()) + CD(rhs.count()));
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
-    operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
-        return CD(CD(lhs).count() - CD(rhs).count());
-    }
-
-    // TODO: This shall not participate in overloading if Rep2 is not implicitly
-    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
-    //       common_type_t<A, B>.
-    template<class Rep1, class Period, class Rep2>
-    constexpr duration<common_type_t<Rep1, Rep2>, Period>
-    operator*(const duration<Rep1, Period>& dur, const Rep2& rep)
-    {
-        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
-        return CD(CD(dur).count() * rep);
-    }
-
-    // TODO: This shall not participate in overloading if Rep2 is not implicitly
-    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
-    //       common_type_t<A, B>.
-    template<class Rep1, class Period, class Rep2>
-    constexpr duration<common_type_t<Rep1, Rep2>, Period>
-    operator*(const Rep2& rep, const duration<Rep1, Period>& dur)
-    {
-        return dur * rep;
-    }
-
-    // TODO: This shall not participate in overloading if Rep2 is not implicitly
-    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
-    //       common_type_t<A, B>.
-    template<class Rep1, class Period, class Rep2>
-    constexpr duration<common_type_t<Rep1, Rep2>, Period>
-    operator/(const duration<Rep1, Period>& dur, const Rep2& rep)
-    {
-        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
-        return CD(CD(dur).count() / rep);
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr common_type_t<Rep1, Rep2>
-    operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        using CD = common_type_t<Rep1, Rep2>;
-        return CD(lhs).count() / CD(rhs).count();
-    }
-
-    // TODO: This shall not participate in overloading if Rep2 is not implicitly
-    //       convertible to CR(Rep1, Rep2) -> CR(A, B) defined in standard as
-    //       common_type_t<A, B>.
-    template<class Rep1, class Period, class Rep2>
-    constexpr duration<common_type_t<Rep1, Rep2>, Period>
-    operator%(const duration<Rep1, Period>& dur, const Rep2& rep)
-    {
-        using CD = duration<common_type_t<Rep1, Rep2>, Period>;
-        return CD(CD(dur).count() / rep);
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
-    operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        using CD = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
-        return CD(CD(lhs).count() % CD(rhs).count());
-    }
-
-    /**
-     * 20.12.5.6, duration comparisons:
-     */
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator==(const duration<Rep1, Period1>& lhs,
-                              const duration<Rep2, Period2>& rhs)
-    {
-        using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
-        return CT(lhs).count() == CT(rhs).count();
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
-                              const duration<Rep2, Period2>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator<(const duration<Rep1, Period1>& lhs,
-                             const duration<Rep2, Period2>& rhs)
-    {
-        using CT = common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>;
-        return CT(lhs).count() < CT(rhs).count();
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
-                              const duration<Rep2, Period2>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator>(const duration<Rep1, Period1>& lhs,
-                             const duration<Rep2, Period2>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Rep1, class Period1, class Rep2, class Period2>
-    constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
-                              const duration<Rep2, Period2>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    /**
-     * 20.12.5.7, duration cast:
-     */
-
-    // TODO: This function should not participate in overloading
-    //       unless ToDuration is an instantiation of duration.
-    template<class ToDuration, class Rep, class Period>
-    constexpr ToDuration duration_cast(const duration<Rep, Period>& dur)
-    {
-        using CF = ratio_divide<Period, typename ToDuration::period>;
-        using CR = typename common_type<typename ToDuration::rep, Rep, intmax_t>::type;
-
-        using to_rep = typename ToDuration::rep;
-
-        if constexpr (CF::num == 1 && CF::den == 1)
-            return ToDuration(static_cast<to_rep>(dur.count()));
-        else if constexpr (CF::num != 1 && CF::den == 1)
-        {
-            return ToDuration(
-                static_cast<to_rep>(
-                    static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
-                )
-            );
-        }
-        else if constexpr (CF::num == 1 && CF::den != 1)
-        {
-            return ToDuration(
-                static_cast<to_rep>(
-                    static_cast<CR>(dur.count()) / static_cast<CR>(CF::den)
-                )
-            );
-        }
-        else
-        {
-            return ToDuration(
-                static_cast<to_rep>(
-                    static_cast<CR>(dur.count()) * static_cast<CR>(CF::num)
-                    / static_cast<CR>(CF::den)
-                )
-            );
-        }
-    }
-
-    // convenience typedefs
-    using nanoseconds  = duration<int64_t, nano>;
-    using microseconds = duration<int64_t, micro>;
-    using milliseconds = duration<int64_t, milli>;
-    using seconds      = duration<int64_t>;
-    using minutes      = duration<int32_t, ratio<60>>;
-    using hours        = duration<int32_t, ratio<3600>>;
-
-    /**
-     * 20.12.6.5, time_point arithmetic:
-     */
-
-    template<class Clock, class Duration1, class Rep2, class Period2>
-    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
-    operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        using CT = time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>;
-        return CT(lhs.time_since_epoch() + rhs);
-    }
-
-    template<class Rep1, class Period1, class Clock, class Duration2>
-    constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
-    operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs)
-    {
-        return rhs + lhs;
-    }
-
-    template<class Clock, class Duration1, class Rep2, class Period2>
-    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
-    operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
-    {
-        return lhs + (-rhs);
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr common_type_t<Duration1, Duration2>
-    operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
-    {
-        return lhs.time_since_epoch() - rhs.time_since_epoch();
-    }
-
-    /**
-     * 20.12.6.6, time_point comparisons:
-     */
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
-                              const time_point<Clock, Duration2>& rhs)
-    {
-        return lhs.time_since_epoch() == rhs.time_since_epoch();
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
-                              const time_point<Clock, Duration2>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator<(const time_point<Clock, Duration1>& lhs,
-                             const time_point<Clock, Duration2>& rhs)
-    {
-        return lhs.time_since_epoch() < rhs.time_since_epoch();
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
-                              const time_point<Clock, Duration2>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator>(const time_point<Clock, Duration1>& lhs,
-                             const time_point<Clock, Duration2>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Clock, class Duration1, class Duration2>
-    constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
-                              const time_point<Clock, Duration2>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    /**
-     * 20.12.6.7, time_point cast:
-     */
-
-    // TODO: This function should not participate in overloading
-    //       unless ToDuration is an instantiation of duration.
-    template<class ToDuration, class Clock, class Duration>
-    constexpr time_point<Clock, ToDuration>
-    time_point_cast(const time_point<Clock, Duration>& tp)
-    {
-        return time_point<Clock, ToDuration>(
-            duration_cast<ToDuration>(tp.time_since_epoch())
-        );
-    }
-
-    /**
-     * 20.12.7, clocks:
-     */
-
-    class system_clock
-    {
-        public:
-            using rep        = int64_t;
-            using period     = micro;
-            using duration   = chrono::duration<rep, period>;
-            using time_point = chrono::time_point<system_clock>;
-
-            // TODO: is it steady?
-            static constexpr bool is_steady = true;
-
-            static time_point now()
-            {
-                hel::timeval tv{};
-                hel::gettimeofday(&tv, nullptr);
-
-                rep time = tv.tv_usec;
-                time += (tv.tv_sec * 1'000'000ul);
-
-                return time_point{duration{time - epoch_usecs}};
-            }
-
-            static time_t to_time_t(const time_point& tp)
-            {
-                /* auto dur = tp.time_since_epoch(); */
-                /* auto time_t_dur = duration_cast<chrono::duration<time_t, seconds>>(dur); */
-
-                /* return time_t{time_t_dur.count()}; */
-                return time_t{};
-            }
-
-            static time_point from_time_t(time_t tt)
-            {
-                /* auto time_t_dur = chrono::duration<time_t, seconds>{tt}; */
-                /* auto dur = duration_cast<duration>(time_t_dur); */
-
-                /* return time_point{duration_cast<duration>(chrono::duration<time_t, seconds>{tt})}; */
-                return time_point{};
-            }
-
-        private:
-            static constexpr rep epoch_usecs{11644473600ul * 1'000'000ul};
-    };
-
-    class steady_clock
-    {
-        public:
-            using rep        = int64_t;
-            using period     = micro;
-            using duration   = chrono::duration<rep, period>;
-            using time_point = chrono::time_point<steady_clock>;
-
-            static constexpr bool is_steady = true;
-
-            static time_point now()
-            {
-                hel::timeval tv{};
-                hel::getuptime(&tv);
-
-                rep time = tv.tv_usec;
-                time += (tv.tv_sec * 1'000'000ul);
-
-                return time_point{duration{time}};
-            }
-    };
-
-    using high_resolution_clock = system_clock;
-}
-
-namespace std
-{
-    inline namespace literals
-    {
-        inline namespace chrono_literals
-        {
-            /**
-             * 20.125.8, suffixes for duration literals:
-             */
-
-            /**
-             * Note: According to the standard, literal suffixes that do not
-             *       start with an underscore are reserved for future standardization,
-             *       but since we are implementing the standard, we're going to ignore it.
-             *       This should work (according to their documentation) work for clang,
-             *       but that should be tested.
-             */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wliteral-suffix"
-
-            constexpr chrono::hours operator ""h(unsigned long long hrs)
-            {
-                return chrono::hours{static_cast<chrono::hours::rep>(hrs)};
-            }
-
-            constexpr chrono::duration<long double, ratio<3600>> operator ""h(long double hrs)
-            {
-                return chrono::duration<long double, ratio<3600>>{hrs};
-            }
-
-            constexpr chrono::minutes operator ""m(unsigned long long mins)
-            {
-                return chrono::minutes{static_cast<chrono::minutes::rep>(mins)};
-            }
-
-            constexpr chrono::duration<long double, ratio<60>> operator ""m(long double mins)
-            {
-                return chrono::duration<long double, ratio<60>>{mins};
-            }
-
-            constexpr chrono::seconds operator ""s(unsigned long long secs)
-            {
-                return chrono::seconds{static_cast<chrono::seconds::rep>(secs)};
-            }
-
-            constexpr chrono::duration<long double, ratio<1>> operator ""s(long double secs)
-            {
-                return chrono::duration<long double, ratio<1>>{secs};
-            }
-
-            constexpr chrono::milliseconds operator ""ms(unsigned long long msecs)
-            {
-                return chrono::milliseconds{static_cast<chrono::milliseconds::rep>(msecs)};
-            }
-
-            constexpr chrono::duration<long double, milli> operator ""ms(long double msecs)
-            {
-                return chrono::duration<long double, milli>{msecs};
-            }
-
-            constexpr chrono::microseconds operator ""us(unsigned long long usecs)
-            {
-                return chrono::microseconds{static_cast<chrono::microseconds::rep>(usecs)};
-            }
-
-            constexpr chrono::duration<long double, micro> operator ""us(long double usecs)
-            {
-                return chrono::duration<long double, micro>{usecs};
-            }
-
-            constexpr chrono::nanoseconds operator ""ns(unsigned long long nsecs)
-            {
-                return chrono::nanoseconds{static_cast<chrono::nanoseconds::rep>(nsecs)};
-            }
-
-            constexpr chrono::duration<long double, nano> operator ""ns(long double nsecs)
-            {
-                return chrono::duration<long double, nano>{nsecs};
-            }
-
-#pragma GCC diagnostic pop
-        }
-    }
-
-    namespace chrono
-    {
-        using namespace literals::chrono_literals;
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/complex.hpp
===================================================================
--- uspace/lib/cpp/include/impl/complex.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,977 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_COMPLEX
-#define LIBCPP_COMPLEX
-
-#include <iosfwd>
-#include <sstream>
-
-namespace std
-{
-    template<class T>
-    class complex
-    {
-        public:
-            using value_type = T;
-
-            constexpr complex(const value_type& re = value_type{},
-                              const value_type& im = value_type{})
-                : real_{re}, imag_{im}
-            { /* DUMMY BODY */ }
-
-            constexpr complex(const complex& other)
-                : real_{other.real_}, imag_{other.imag_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            constexpr complex(const complex<U>& other)
-                : real_(other.real()), imag_(other.imag())
-            { /* DUMMY BODY */ }
-
-            constexpr value_type real() const
-            {
-                return real_;
-            }
-
-            void real(value_type val)
-            {
-                real_ = val;
-            }
-
-            constexpr value_type imag() const
-            {
-                return imag_;
-            }
-
-            void imag(value_type val)
-            {
-                imag_ = val;
-            }
-
-            complex& operator=(const value_type& val)
-            {
-                real_ = val;
-                imag_ = value_type{};
-
-                return *this;
-            }
-
-            complex& operator+=(const value_type& val)
-            {
-                real_ += val;
-
-                return *this;
-            }
-
-            complex& operator-=(const value_type& val)
-            {
-                real_ -= val;
-
-                return *this;
-            }
-
-            complex& operator*=(const value_type& val)
-            {
-                real_ *= val;
-                imag_ *= val;
-
-                return *this;
-            }
-
-            complex& operator/=(const value_type& val)
-            {
-                real_ /= val;
-                imag_ /= val;
-
-                return *this;
-            }
-
-            complex& operator=(const complex& other)
-            {
-                real_ = other.real_;
-                imag_ = other.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator=(const complex<U>& rhs)
-            {
-                real_ = rhs.real_;
-                imag_ = rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator+=(const complex<U>& rhs)
-            {
-                real_ += rhs.real_;
-                imag_ += rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator-=(const complex<U>& rhs)
-            {
-                real_ -= rhs.real_;
-                imag_ -= rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator*=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
-                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator/=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-
-                return *this;
-            }
-
-        private:
-            value_type real_;
-            value_type imag_;
-    };
-
-    template<>
-    class complex<float>
-    {
-        public:
-            using value_type = float;
-
-            constexpr complex(const value_type& re = value_type{},
-                              const value_type& im = value_type{})
-                : real_{re}, imag_{im}
-            { /* DUMMY BODY */ }
-
-            constexpr complex(const complex& other)
-                : real_{other.real_}, imag_{other.imag_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            constexpr complex(const complex<U>& other)
-                : real_(other.real()), imag_(other.imag())
-            { /* DUMMY BODY */ }
-
-            constexpr value_type real() const
-            {
-                return real_;
-            }
-
-            void real(value_type val)
-            {
-                real_ = val;
-            }
-
-            constexpr value_type imag() const
-            {
-                return imag_;
-            }
-
-            void imag(value_type val)
-            {
-                imag_ = val;
-            }
-
-            complex& operator=(const value_type& val)
-            {
-                real_ = val;
-                imag_ = value_type{};
-
-                return *this;
-            }
-
-            complex& operator+=(const value_type& val)
-            {
-                real_ += val;
-
-                return *this;
-            }
-
-            complex& operator-=(const value_type& val)
-            {
-                real_ -= val;
-
-                return *this;
-            }
-
-            complex& operator*=(const value_type& val)
-            {
-                real_ *= val;
-                imag_ *= val;
-
-                return *this;
-            }
-
-            complex& operator/=(const value_type& val)
-            {
-                real_ /= val;
-                imag_ /= val;
-
-                return *this;
-            }
-
-            complex& operator=(const complex& other)
-            {
-                real_ = other.real_;
-                imag_ = other.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator=(const complex<U>& rhs)
-            {
-                real_ = rhs.real_;
-                imag_ = rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator+=(const complex<U>& rhs)
-            {
-                real_ += rhs.real_;
-                imag_ += rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator-=(const complex<U>& rhs)
-            {
-                real_ -= rhs.real_;
-                imag_ -= rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator*=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
-                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator/=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-
-                return *this;
-            }
-
-        private:
-            value_type real_;
-            value_type imag_;
-    };
-
-    template<>
-    class complex<double>
-    {
-        public:
-            using value_type = double;
-
-            constexpr complex(const value_type& re = value_type{},
-                              const value_type& im = value_type{})
-                : real_{re}, imag_{im}
-            { /* DUMMY BODY */ }
-
-            constexpr complex(const complex& other)
-                : real_{other.real_}, imag_{other.imag_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            constexpr complex(const complex<U>& other)
-                : real_(other.real()), imag_(other.imag())
-            { /* DUMMY BODY */ }
-
-            constexpr value_type real() const
-            {
-                return real_;
-            }
-
-            void real(value_type val)
-            {
-                real_ = val;
-            }
-
-            constexpr value_type imag() const
-            {
-                return imag_;
-            }
-
-            void imag(value_type val)
-            {
-                imag_ = val;
-            }
-
-            complex& operator=(const value_type& val)
-            {
-                real_ = val;
-                imag_ = value_type{};
-
-                return *this;
-            }
-
-            complex& operator+=(const value_type& val)
-            {
-                real_ += val;
-
-                return *this;
-            }
-
-            complex& operator-=(const value_type& val)
-            {
-                real_ -= val;
-
-                return *this;
-            }
-
-            complex& operator*=(const value_type& val)
-            {
-                real_ *= val;
-                imag_ *= val;
-
-                return *this;
-            }
-
-            complex& operator/=(const value_type& val)
-            {
-                real_ /= val;
-                imag_ /= val;
-
-                return *this;
-            }
-
-            complex& operator=(const complex& other)
-            {
-                real_ = other.real_;
-                imag_ = other.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator=(const complex<U>& rhs)
-            {
-                real_ = rhs.real_;
-                imag_ = rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator+=(const complex<U>& rhs)
-            {
-                real_ += rhs.real_;
-                imag_ += rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator-=(const complex<U>& rhs)
-            {
-                real_ -= rhs.real_;
-                imag_ -= rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator*=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
-                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator/=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-                imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-
-                return *this;
-            }
-
-        private:
-            value_type real_;
-            value_type imag_;
-    };
-
-    template<>
-    class complex<long double>
-    {
-        public:
-            using value_type = long double;
-
-            constexpr complex(const value_type& re = value_type{},
-                              const value_type& im = value_type{})
-                : real_{re}, imag_{im}
-            { /* DUMMY BODY */ }
-
-            constexpr complex(const complex& other)
-                : real_{other.real_}, imag_{other.imag_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            constexpr complex(const complex<U>& other)
-                : real_(other.real()), imag_(other.imag())
-            { /* DUMMY BODY */ }
-
-            constexpr value_type real() const
-            {
-                return real_;
-            }
-
-            void real(value_type val)
-            {
-                real_ = val;
-            }
-
-            constexpr value_type imag() const
-            {
-                return imag_;
-            }
-
-            void imag(value_type val)
-            {
-                imag_ = val;
-            }
-
-            complex& operator=(const value_type& val)
-            {
-                real_ = val;
-                imag_ = value_type{};
-
-                return *this;
-            }
-
-            complex& operator+=(const value_type& val)
-            {
-                real_ += val;
-
-                return *this;
-            }
-
-            complex& operator-=(const value_type& val)
-            {
-                real_ -= val;
-
-                return *this;
-            }
-
-            complex& operator*=(const value_type& val)
-            {
-                real_ *= val;
-                imag_ *= val;
-
-                return *this;
-            }
-
-            complex& operator/=(const value_type& val)
-            {
-                real_ /= val;
-                imag_ /= val;
-
-                return *this;
-            }
-
-            complex& operator=(const complex& other)
-            {
-                real_ = other.real_;
-                imag_ = other.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator=(const complex<U>& rhs)
-            {
-                real_ = rhs.real_;
-                imag_ = rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator+=(const complex<U>& rhs)
-            {
-                real_ += rhs.real_;
-                imag_ += rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator-=(const complex<U>& rhs)
-            {
-                real_ -= rhs.real_;
-                imag_ -= rhs.imag_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator*=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
-                imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
-
-                return *this;
-            }
-
-            template<class U>
-            complex& operator/=(const complex<U>& rhs)
-            {
-                auto old_real = real_;
-                real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-                imag_ = (imag_ * rhs.real_ - old_real* rhs.imag_)
-                      / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
-
-                return *this;
-            }
-
-        private:
-            value_type real_;
-            value_type imag_;
-    };
-
-    /**
-     * 26.4.6, operators:
-     */
-
-    template<class T>
-    complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} += rhs;
-    }
-
-    template<class T>
-    complex<T> operator+(const complex<T>& lhs, const T& rhs)
-    {
-        return complex<T>{lhs} += rhs;
-    }
-
-    template<class T>
-    complex<T> operator+(const T& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} += rhs;
-    }
-
-    template<class T>
-    complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} -= rhs;
-    }
-
-    template<class T>
-    complex<T> operator-(const complex<T>& lhs, const T& rhs)
-    {
-        return complex<T>{lhs} -= rhs;
-    }
-
-    template<class T>
-    complex<T> operator-(const T& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} -= rhs;
-    }
-
-    template<class T>
-    complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} *= rhs;
-    }
-
-    template<class T>
-    complex<T> operator*(const complex<T>& lhs, const T& rhs)
-    {
-        return complex<T>{lhs} *= rhs;
-    }
-
-    template<class T>
-    complex<T> operator*(const T& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} *= rhs;
-    }
-
-    template<class T>
-    complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} /= rhs;
-    }
-
-    template<class T>
-    complex<T> operator/(const complex<T>& lhs, const T& rhs)
-    {
-        return complex<T>{lhs} /= rhs;
-    }
-
-    template<class T>
-    complex<T> operator/(const T& lhs, const complex<T>& rhs)
-    {
-        return complex<T>{lhs} /= rhs;
-    }
-
-    template<class T>
-    complex<T> operator+(const complex<T>& c)
-    {
-        return complex<T>{c};
-    }
-
-    template<class T>
-    complex<T> operator-(const complex<T>& c)
-    {
-        return complex<T>{-c.real(), -c.imag()};
-    }
-
-    template<class T>
-    constexpr bool operator==(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
-    }
-
-    template<class T>
-    constexpr bool operator==(const complex<T>& lhs, const T& rhs)
-    {
-        return lhs.real() == rhs && lhs.imag() == T{};
-    }
-
-    template<class T>
-    constexpr bool operator==(const T& lhs, const complex<T>& rhs)
-    {
-        return lhs == rhs.real() && T{} == rhs.imag();
-    }
-
-    template<class T>
-    constexpr bool operator!=(const complex<T>& lhs, const complex<T>& rhs)
-    {
-        return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
-    }
-
-    template<class T>
-    constexpr bool operator!=(const complex<T>& lhs, const T& rhs)
-    {
-        return lhs.real() != rhs || lhs.imag() != T{};
-    }
-
-    template<class T>
-    constexpr bool operator!=(const T& lhs, const complex<T>& rhs)
-    {
-        return lhs != rhs.real() || T{} != rhs.imag();
-    }
-
-    template<class T, class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            const complex<T>& c)
-    {
-        // TODO: implement
-    }
-
-    template<class T, class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const complex<T>& c)
-    {
-        basic_ostringstream<Char, Traits> oss{};
-        oss.flags(os.flags());
-        oss.imbue(os.getloc());
-        oss.precision(os.precision());
-
-        oss << "(" << c.real() << "," << c.imag() << ")";
-
-        return os << oss.str();
-    }
-
-    /**
-     * 26.4.7, values:
-     */
-
-    template<class T>
-    constexpr T real(const complex<T>& c)
-    {
-        return c.real();
-    }
-
-    template<class T>
-    constexpr T imag(const complex<T>& c)
-    {
-        return c.imag();
-    }
-
-    template<class T>
-    T abs(const complex<T>& c)
-    {
-        return c.real() * c.real() + c.imag() * c.imag();
-    }
-
-    template<class T>
-    T arg(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    T norm(const complex<T>& c)
-    {
-        return abs(c) * abs(c);
-    }
-
-    template<class T>
-    complex<T> conj(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> proj(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> polar(const T&, const T& = T{})
-    {
-        // TODO: implement
-        return complex<T>{};
-    }
-
-    /**
-     * 26.4.8, transcendentals:
-     */
-
-    template<class T>
-    complex<T> acos(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> asin(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> atan(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> acosh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> asinh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> atanh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> cos(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> cosh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> exp(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> log(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> log10(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> pow(const complex<T>& base, const T& exp)
-    {
-        // TODO: implement
-        return base;
-    }
-
-    template<class T>
-    complex<T> pow(const complex<T>& base, const complex<T>& exp)
-    {
-        // TODO: implement
-        return base;
-    }
-
-    template<class T>
-    complex<T> pow(const T& base, const complex<T>& exp)
-    {
-        // TODO: implement
-        return complex<T>{base};
-    }
-
-    template<class T>
-    complex<T> sin(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> sinh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> sqrt(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> tan(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    template<class T>
-    complex<T> tanh(const complex<T>& c)
-    {
-        // TODO: implement
-        return c;
-    }
-
-    /**
-     * 26.4.10, complex literals:
-     */
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wliteral-suffix"
-inline namespace literals {
-inline namespace complex_literals
-{
-    constexpr complex<long double> operator ""il(long double val)
-    {
-        return complex<long double>{0.0L, val};
-    }
-
-    constexpr complex<long double> operator ""il(unsigned long long val)
-    {
-        return complex<long double>{0.0L, static_cast<long double>(val)};
-    }
-
-    constexpr complex<double> operator ""i(long double val)
-    {
-        return complex<double>{0.0, static_cast<double>(val)};
-    }
-
-    constexpr complex<double> operator ""i(unsigned long long val)
-    {
-        return complex<double>{0.0, static_cast<double>(val)};
-    }
-
-    constexpr complex<float> operator ""if(long double val)
-    {
-        return complex<float>{0.0f, static_cast<float>(val)};
-    }
-
-    constexpr complex<float> operator ""if(unsigned long long val)
-    {
-        return complex<float>{0.0f, static_cast<float>(val)};
-    }
-}}
-#pragma GCC diagnostic pop
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/condition_variable.hpp
===================================================================
--- uspace/lib/cpp/include/impl/condition_variable.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,228 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_CONDITION_VARIABLE
-#define LIBCPP_CONDITION_VARIABLE
-
-#include <__bits/thread.hpp>
-#include <mutex>
-
-namespace std
-{
-    extern "C" {
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-
-    enum class cv_status
-    {
-        no_timeout,
-        timeout
-    };
-
-    namespace aux
-    {
-        template<class Clock, class Duration>
-        aux::time_unit_t time_until(const chrono::time_point<Clock, Duration>& abs_time)
-        {
-            return aux::threading::time::convert(abs_time - Clock::now());
-        }
-    }
-
-    /**
-     * 30.5.1, class condition_variable:
-     */
-
-    class condition_variable
-    {
-        public:
-            condition_variable();
-            ~condition_variable();
-
-            condition_variable(const condition_variable&) = delete;
-            condition_variable& operator=(const condition_variable&) = delete;
-
-            void notify_one() noexcept;
-            void notify_all() noexcept;
-
-            void wait(unique_lock<mutex>&);
-
-            template<class Predicate>
-            void wait(unique_lock<mutex>& lock, Predicate pred)
-            {
-                /**
-                 * Note: lock is supposed to be locked here,
-                 *       so no need to lock it.
-                 */
-                while (!pred())
-                    wait(lock);
-            }
-
-            template<class Clock, class Duration>
-            cv_status wait_until(unique_lock<mutex>& lock,
-                                 const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                auto ret = aux::threading::condvar::wait_for(
-                    cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
-                );
-
-                if (ret == EOK)
-                    return cv_status::no_timeout;
-                else
-                    return cv_status::timeout;
-            }
-
-            template<class Clock, class Duration, class Predicate>
-            bool wait_until(unique_lock<mutex>& lock,
-                            const chrono::time_point<Clock, Duration>& abs_time,
-                            Predicate pred)
-            {
-                while (!pred())
-                {
-                    if (wait_until(lock, abs_time) == cv_status::timeout)
-                        return pred();
-                }
-
-                return true;
-            }
-
-            template<class Rep, class Period>
-            cv_status wait_for(unique_lock<mutex>& lock,
-                               const chrono::duration<Rep, Period>& rel_time)
-            {
-                return wait_until(
-                    lock, chrono::steady_clock::now() + rel_time
-                );
-            }
-
-            template<class Rep, class Period, class Predicate>
-            bool wait_for(unique_lock<mutex>& lock,
-                          const chrono::duration<Rep, Period>& rel_time,
-                          Predicate pred)
-            {
-                return wait_until(
-                    lock, chrono::steady_clock::now() + rel_time,
-                    move(pred)
-                );
-            }
-
-            using native_handle_type = aux::condvar_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::condvar_t cv_;
-    };
-
-    /**
-     * 30.5.2, class condition_variable_any:
-     */
-
-    class condition_variable_any
-    {
-        public:
-            condition_variable_any();
-            ~condition_variable_any();
-
-            condition_variable_any(const condition_variable_any&) = delete;
-            condition_variable_any& operator=(const condition_variable_any&) = delete;
-
-            void notify_one() noexcept;
-            void notify_all() noexcept;
-
-            template<class Lock>
-            void wait(Lock& lock)
-            {
-                aux::threading::condvar::wait(cv_, *lock.native_handle());
-            }
-
-            template<class Lock, class Predicate>
-            void wait(Lock& lock, Predicate pred)
-            {
-                while (!pred())
-                    wait(lock);
-            }
-
-            template<class Lock, class Clock, class Duration>
-            cv_status wait_until(Lock& lock,
-                                 const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                auto ret = aux::threading::condvar::wait_for(
-                    cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
-                );
-
-                if (ret == EOK)
-                    return cv_status::no_timeout;
-                else
-                    return cv_status::timeout;
-            }
-
-            template<class Lock, class Clock, class Duration, class Predicate>
-            bool wait_until(Lock& lock,
-                            const chrono::time_point<Clock, Duration>& abs_time,
-                            Predicate pred)
-            {
-                while (!pred())
-                {
-                    if (wait_until(lock, abs_time) == cv_status::timeout)
-                        return pred();
-                }
-
-                return true;
-            }
-
-            template<class Lock, class Rep, class Period>
-            cv_status wait_for(Lock& lock,
-                               const chrono::duration<Rep, Period>& rel_time)
-            {
-                return wait_until(
-                    lock, chrono::steady_clock::now() + rel_time
-                );
-            }
-
-            template<class Lock, class Rep, class Period, class Predicate>
-            bool wait_for(Lock& lock,
-                          const chrono::duration<Rep, Period>& rel_time,
-                          Predicate pred)
-            {
-                return wait_until(
-                    lock, chrono::steady_clock::now() + rel_time,
-                    move(pred)
-                );
-            }
-
-            using native_handle_type = aux::condvar_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::condvar_t cv_;
-    };
-
-    void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>&);
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/deque.hpp
===================================================================
--- uspace/lib/cpp/include/impl/deque.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1218 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_DEQUE
-#define LIBCPP_DEQUE
-
-#include <algorithm>
-#include <initializer_list>
-#include <__bits/insert_iterator.hpp>
-#include <iterator>
-#include <memory>
-
-namespace std
-{
-    template<class T, class Allocator = allocator<T>>
-    class deque;
-
-    namespace aux
-    {
-        /**
-         * Note: We decided that these iterators contain a
-         *       reference to the container and an index, which
-         *       allows us to use the already implemented operator[]
-         *       on deque and also allows us to conform to the requirement
-         *       of the standard that functions such as push_back
-         *       invalidate the .end() iterator.
-         */
-
-        template<class T, class Allocator>
-        class deque_iterator;
-
-        template<class T, class Allocator>
-        class deque_const_iterator
-        {
-            public:
-                using size_type         = typename deque<T, Allocator>::size_type;
-                using value_type        = typename deque<T, Allocator>::value_type;
-                using reference         = typename deque<T, Allocator>::const_reference;
-                using difference_type   = size_type;
-                using pointer           = const value_type*;
-                using iterator_category = random_access_iterator_tag;
-
-                deque_const_iterator(const deque<T, Allocator>& deq, size_type idx)
-                    : deq_{deq}, idx_{idx}
-                { /* DUMMY BODY */ }
-
-                deque_const_iterator(const deque_const_iterator& other)
-                    : deq_{other.deq_}, idx_{other.idx_}
-                { /* DUMMY BODY */ }
-
-                deque_const_iterator& operator=(const deque_const_iterator& other)
-                {
-                    deq_ = other.deq_;
-                    idx_ = other.idx_;
-
-                    return *this;
-                }
-
-                reference operator*() const
-                {
-                    return deq_[idx_];
-                }
-
-                pointer operator->() const
-                {
-                    return addressof(deq_[idx_]);
-                }
-
-                deque_const_iterator& operator++()
-                {
-                    ++idx_;
-
-                    return *this;
-                }
-
-                deque_const_iterator operator++(int)
-                {
-                    return deque_const_iterator{deq_, idx_++};
-                }
-
-                deque_const_iterator& operator--()
-                {
-                    --idx_;
-
-                    return *this;
-                }
-
-                deque_const_iterator operator--(int)
-                {
-                    return deque_const_iterator{deq_, idx_--};
-                }
-
-                deque_const_iterator operator+(difference_type n)
-                {
-                    return deque_const_iterator{deq_, idx_ + n};
-                }
-
-                deque_const_iterator& operator+=(difference_type n)
-                {
-                    idx_ += n;
-
-                    return *this;
-                }
-
-                deque_const_iterator operator-(difference_type n)
-                {
-                    return deque_const_iterator{deq_, idx_ - n};
-                }
-
-                deque_const_iterator& operator-=(difference_type n)
-                {
-                    idx_ -= n;
-
-                    return *this;
-                }
-
-                reference operator[](difference_type n) const
-                {
-                    return deq_[idx_ + n];
-                }
-
-                difference_type operator-(const deque_const_iterator& rhs)
-                {
-                    return idx_ - rhs.idx_;
-                }
-
-                size_type idx() const
-                {
-                    return idx_;
-                }
-
-                operator deque_iterator<T, Allocator>()
-                {
-                    return deque_iterator{
-                        const_cast<deque<T, Allocator>&>(deq_), idx_
-                    };
-                }
-
-            private:
-                const deque<T, Allocator>& deq_;
-                size_type idx_;
-        };
-
-        template<class T, class Allocator>
-        bool operator==(const deque_const_iterator<T, Allocator>& lhs,
-                        const deque_const_iterator<T, Allocator>& rhs)
-        {
-            return lhs.idx() == rhs.idx();
-        }
-
-        template<class T, class Allocator>
-        bool operator!=(const deque_const_iterator<T, Allocator>& lhs,
-                        const deque_const_iterator<T, Allocator>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-
-        template<class T, class Allocator>
-        class deque_iterator
-        {
-            public:
-                using size_type         = typename deque<T, Allocator>::size_type;
-                using value_type        = typename deque<T, Allocator>::value_type;
-                using reference         = typename deque<T, Allocator>::reference;
-                using difference_type   = size_type;
-                using pointer           = value_type*;
-                using iterator_category = random_access_iterator_tag;
-
-                deque_iterator(deque<T, Allocator>& deq, size_type idx)
-                    : deq_{deq}, idx_{idx}
-                { /* DUMMY BODY */ }
-
-                deque_iterator(const deque_iterator& other)
-                    : deq_{other.deq_}, idx_{other.idx_}
-                { /* DUMMY BODY */ }
-
-                deque_iterator(const deque_const_iterator<T, Allocator>& other)
-                    : deq_{other.deq_}, idx_{other.idx_}
-                { /* DUMMY BODY */ }
-
-                deque_iterator& operator=(const deque_iterator& other)
-                {
-                    deq_ = other.deq_;
-                    idx_ = other.idx_;
-
-                    return *this;
-                }
-
-                deque_iterator& operator=(const deque_const_iterator<T, Allocator>& other)
-                {
-                    deq_ = other.deq_;
-                    idx_ = other.idx_;
-
-                    return *this;
-                }
-
-                reference operator*()
-                {
-                    return deq_[idx_];
-                }
-
-                pointer operator->()
-                {
-                    return addressof(deq_[idx_]);
-                }
-
-                deque_iterator& operator++()
-                {
-                    ++idx_;
-
-                    return *this;
-                }
-
-                deque_iterator operator++(int)
-                {
-                    return deque_iterator{deq_, idx_++};
-                }
-
-                deque_iterator& operator--()
-                {
-                    --idx_;
-
-                    return *this;
-                }
-
-                deque_iterator operator--(int)
-                {
-                    return deque_iterator{deq_, idx_--};
-                }
-
-                deque_iterator operator+(difference_type n)
-                {
-                    return deque_iterator{deq_, idx_ + n};
-                }
-
-                deque_iterator& operator+=(difference_type n)
-                {
-                    idx_ += n;
-
-                    return *this;
-                }
-
-                deque_iterator operator-(difference_type n)
-                {
-                    return deque_iterator{deq_, idx_ - n};
-                }
-
-                deque_iterator& operator-=(difference_type n)
-                {
-                    idx_ -= n;
-
-                    return *this;
-                }
-
-                reference operator[](difference_type n) const
-                {
-                    return deq_[idx_ + n];
-                }
-
-                difference_type operator-(const deque_iterator& rhs)
-                {
-                    return idx_ - rhs.idx_;
-                }
-
-                size_type idx() const
-                {
-                    return idx_;
-                }
-
-                operator deque_const_iterator<T, Allocator>()
-                {
-                    return deque_const_iterator{deq_, idx_};
-                }
-
-            private:
-                deque<T, Allocator>& deq_;
-                size_type idx_;
-        };
-
-        template<class T, class Allocator>
-        bool operator==(const deque_iterator<T, Allocator>& lhs,
-                        const deque_iterator<T, Allocator>& rhs)
-        {
-            return lhs.idx() == rhs.idx();
-        }
-
-        template<class T, class Allocator>
-        bool operator!=(const deque_iterator<T, Allocator>& lhs,
-                        const deque_iterator<T, Allocator>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-    }
-
-    /**
-     * 23.3.3 deque:
-     */
-
-    template<class T, class Allocator>
-    class deque
-    {
-        public:
-            using allocator_type  = Allocator;
-            using value_type      = T;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-
-            using iterator               = aux::deque_iterator<T, Allocator>;
-            using const_iterator         = aux::deque_const_iterator<T, Allocator>;
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            using size_type       = typename allocator_traits<allocator_type>::size_type;
-            using difference_type = typename allocator_traits<allocator_type>::difference_type;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-
-            /**
-             * 23.3.3.2, construct/copy/destroy:
-             */
-
-            deque()
-                : deque{allocator_type{}}
-            { /* DUMMY BODY */ }
-
-            explicit deque(const allocator_type& alloc)
-                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
-                  back_bucket_idx_{0}, front_bucket_{default_front_},
-                  back_bucket_{default_back_}, bucket_count_{default_bucket_count_},
-                  bucket_capacity_{default_bucket_capacity_}, size_{}, data_{}
-            {
-                init_();
-            }
-
-            explicit deque(size_type n, const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, front_bucket_idx_{bucket_size_}, back_bucket_idx_{},
-                  front_bucket_{}, back_bucket_{}, bucket_count_{},
-                  bucket_capacity_{}, size_{n}, data_{}
-            {
-                prepare_for_size_(n);
-                init_();
-
-                for (size_type i = 0; i < size_; ++i)
-                    allocator_.construct(&(*this)[i]);
-                back_bucket_idx_ = size_ % bucket_size_;
-            }
-
-            deque(size_type n, const value_type& value, const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, front_bucket_idx_{bucket_size_}, back_bucket_idx_{},
-                  front_bucket_{}, back_bucket_{}, bucket_count_{},
-                  bucket_capacity_{}, size_{n}, data_{}
-            {
-                prepare_for_size_(n);
-                init_();
-
-                for (size_type i = 0; i < size_; ++i)
-                    (*this)[i] = value;
-                back_bucket_idx_ = size_ % bucket_size_;
-            }
-
-            template<class InputIterator>
-            deque(InputIterator first, InputIterator last,
-                  const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
-                  back_bucket_idx_{}, front_bucket_{}, back_bucket_{},
-                  bucket_count_{}, bucket_capacity_{}, size_{},
-                  data_{}
-            {
-                copy_from_range_(first, last);
-            }
-
-            deque(const deque& other)
-                : deque{other.begin(), other.end(), other.allocator_}
-            { /* DUMMY BODY */ }
-
-            deque(deque&& other)
-                : allocator_{move(other.allocator_)},
-                  front_bucket_idx_{other.front_bucket_idx_},
-                  back_bucket_idx_{other.back_bucket_idx_},
-                  front_bucket_{other.front_bucket_},
-                  back_bucket_{other.back_bucket_},
-                  bucket_count_{other.bucket_count_},
-                  bucket_capacity_{other.bucket_capacity_},
-                  size_{other.size_}, data_{other.data_}
-            {
-                other.data_ = nullptr;
-                other.clear();
-            }
-
-            deque(const deque& other, const allocator_type& alloc)
-                : deque{other.begin(), other.end(), alloc}
-            { /* DUMMY BODY */ }
-
-            deque(deque&& other, const allocator_type& alloc)
-                : allocator_{alloc},
-                  front_bucket_idx_{other.front_bucket_idx_},
-                  back_bucket_idx_{other.front_bucket_idx_},
-                  front_bucket_{other.front_bucket_},
-                  back_bucket_{other.back_bucket_},
-                  bucket_count_{other.bucket_count_},
-                  bucket_capacity_{other.bucket_capacity_},
-                  size_{other.size_}, data_{other.data_}
-            {
-                other.data_ = nullptr;
-                other.clear();
-            }
-
-            deque(initializer_list<T> init, const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, front_bucket_idx_{bucket_size_},
-                  back_bucket_idx_{}, front_bucket_{}, back_bucket_{},
-                  bucket_count_{}, bucket_capacity_{}, size_{},
-                  data_{}
-            {
-                copy_from_range_(init.begin(), init.end());
-            }
-
-            ~deque()
-            {
-                fini_();
-            }
-
-            deque& operator=(const deque& other)
-            {
-                if (data_)
-                    fini_();
-
-                copy_from_range_(other.begin(), other.end());
-
-                return *this;
-            }
-
-            deque& operator=(deque&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                swap(other);
-                other.clear();
-
-                return *this;
-            }
-
-            deque& operator=(initializer_list<T> init)
-            {
-                if (data_)
-                    fini_();
-
-                copy_from_range_(init.begin(), init.end());
-
-                return *this;
-            }
-
-            template<class InputIterator>
-            void assign(InputIterator first, InputIterator last)
-            {
-                copy_from_range_(first, last);
-            }
-
-            void assign(size_type n, const T& value)
-            {
-                prepare_for_size_(n);
-                init_();
-                size_ = n;
-
-                auto it = begin();
-                for (size_type i = size_type{}; i < n; ++i)
-                    *it++ = value;
-            }
-
-            void assign(initializer_list<T> init)
-            {
-                copy_from_range_(init.begin(), init.end());
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return aux::deque_iterator{*this, 0};
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return aux::deque_const_iterator{*this, 0};
-            }
-
-            iterator end() noexcept
-            {
-                return aux::deque_iterator{*this, size_};
-            }
-
-            const_iterator end() const noexcept
-            {
-                return aux::deque_const_iterator{*this, size_};
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return make_reverse_iterator(end());
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return make_reverse_iterator(begin());
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return aux::deque_const_iterator{*this, 0};
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return aux::deque_const_iterator{*this, size_};
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            /**
-             * 23.3.3.3, capacity:
-             */
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type max_size() const noexcept
-            {
-                return allocator_traits<allocator_type>::max_size(allocator_);
-            }
-
-            void resize(size_type sz)
-            {
-                if (sz <= size_)
-                {
-                    auto count = size_ - sz;
-                    for (size_type i = 0; i < count; ++i)
-                        pop_back();
-                }
-                else
-                {
-                    value_type value{};
-                    auto count = sz - size_;
-                    for (size_type i = 0; i < count; ++i)
-                        push_back(value);
-                }
-            }
-
-            void resize(size_type sz, const value_type& value)
-            {
-                if (sz <= size_)
-                {
-                    auto count = size_ - sz;
-                    for (size_type i = 0; i < count; ++i)
-                        pop_back();
-                }
-                else
-                {
-                    auto count = sz - size_;
-                    for (size_type i = 0; i < count; ++i)
-                        push_back(value);
-                }
-            }
-
-            void shrink_to_fit()
-            {
-                /**
-                 * We lazily allocate buckets and eagerily deallocate them.
-                 * We cannot go into smaller pieces as buckets have fixed size.
-                 * Because of this, shrink_to_fit has no effect (as permitted
-                 * by the standard).
-                 */
-            }
-
-            bool empty() const noexcept
-            {
-                return size_ == size_type{};
-            }
-
-            reference operator[](size_type idx)
-            {
-                return data_[get_bucket_index_(idx)][get_element_index_(idx)];
-            }
-
-            const_reference operator[](size_type idx) const
-            {
-                return data_[get_bucket_index_(idx)][get_element_index_(idx)];
-            }
-
-            reference at(size_type idx)
-            {
-                // TODO: bounds checking
-                return operator[](idx);
-            }
-
-            const_reference at(size_type idx) const
-            {
-                // TODO: bounds checking
-                return operator[](idx);
-            }
-
-            reference front()
-            {
-                return *begin();
-            }
-
-            const_reference front() const
-            {
-                return *cbegin();
-            }
-
-            reference back()
-            {
-                auto tmp = end();
-
-                return *(--tmp);
-            }
-
-            const_reference back() const
-            {
-                auto tmp = cend();
-
-                return *(--tmp);
-            }
-
-            /**
-             * 23.3.3.4, modifiers:
-             */
-
-            template<class... Args>
-            void emplace_front(Args&&... args)
-            {
-                if (front_bucket_idx_ == 0)
-                    add_new_bucket_front_();
-
-                allocator_traits<allocator_type>::construct(
-                    allocator_,
-                    &data_[front_bucket_][--front_bucket_idx_],
-                    forward<Args>(args)...
-                );
-
-                ++size_;
-            }
-
-            template<class... Args>
-            void emplace_back(Args&&... args)
-            {
-                allocator_traits<allocator_type>::construct(
-                    allocator_,
-                    &data_[back_bucket_][back_bucket_idx_++],
-                    forward<Args>(args)...
-                );
-
-                ++size_;
-
-                if (back_bucket_idx_ >= bucket_size_)
-                    add_new_bucket_back_();
-            }
-
-            template<class... Args>
-            iterator emplace(const_iterator position, Args&&... args)
-            {
-                auto idx = position.idx();
-                shift_right_(idx, 1);
-
-                allocator_traits<allocator_type>::construct(
-                    allocator_,
-                    &data_[get_bucket_index_(idx)][get_element_index_(idx)],
-                    forward<Args>(args)...
-                );
-                ++size_;
-
-                return iterator{*this, idx};
-            }
-
-            void push_front(const value_type& value)
-            {
-                if (front_bucket_idx_ == 0)
-                    add_new_bucket_front_();
-
-                data_[front_bucket_][--front_bucket_idx_] = value;
-                ++size_;
-            }
-
-            void push_front(value_type&& value)
-            {
-                if (front_bucket_idx_ == 0)
-                    add_new_bucket_front_();
-
-                data_[front_bucket_][--front_bucket_idx_] = forward<value_type>(value);
-                ++size_;
-            }
-
-            void push_back(const value_type& value)
-            {
-                data_[back_bucket_][back_bucket_idx_++] = value;
-                ++size_;
-
-                if (back_bucket_idx_ >= bucket_size_)
-                    add_new_bucket_back_();
-            }
-
-            void push_back(value_type&& value)
-            {
-                data_[back_bucket_][back_bucket_idx_++] = forward<value_type>(value);
-                ++size_;
-
-                if (back_bucket_idx_ >= bucket_size_)
-                    add_new_bucket_back_();
-            }
-
-            iterator insert(const_iterator position, const value_type& value)
-            {
-                auto idx = position.idx();
-                shift_right_(idx, 1);
-
-                /**
-                 * Note: One may notice that when working with the deque
-                 *       iterator, we use its index without any checks.
-                 *       This is because a valid iterator will always have
-                 *       a valid index as functions like pop_back or erase
-                 *       invalidate iterators.
-                 */
-                data_[get_bucket_index_(idx)][get_element_index_(idx)] = value;
-                ++size_;
-
-                return iterator{*this, idx};
-            }
-
-            iterator insert(const_iterator position, value_type&& value)
-            {
-                auto idx = position.idx();
-                shift_right_(idx, 1);
-
-                data_[get_bucket_index_(idx)][get_element_index_(idx)] = forward<value_type>(value);
-                ++size_;
-
-                return iterator{*this, idx};
-            }
-
-            iterator insert(const_iterator position, size_type n, const value_type& value)
-            {
-                return insert(
-                    position,
-                    aux::insert_iterator<int>{0u, value},
-                    aux::insert_iterator<int>{n}
-                );
-            }
-
-            template<class InputIterator>
-            iterator insert(const_iterator position, InputIterator first, InputIterator last)
-            {
-                auto idx = position.idx();
-                auto count = distance(first, last);
-
-                if (idx < size_ / 2)
-                {
-                    shift_left_(idx, count);
-
-                    iterator it{*this, idx - 1};
-                    while (first != last)
-                        *it++ = *first++;
-                }
-                else
-                {
-                    shift_right_(idx, count);
-
-                    iterator it{*this, idx};
-                    while (first != last)
-                        *it++ = *first++;
-                }
-
-                size_ += count;
-
-                return iterator{*this, idx};
-            }
-
-            iterator insert(const_iterator position, initializer_list<value_type> init)
-            {
-                return insert(position, init.begin(), init.end());
-            }
-
-            void pop_back()
-            {
-                if (empty())
-                    return;
-
-                if (back_bucket_idx_ == 0)
-                { // Means we gotta pop data_[back_bucket_ - 1][bucket_size_ - 1]!
-                    if (data_[back_bucket_])
-                        allocator_.deallocate(data_[back_bucket_], bucket_size_);
-
-                    --back_bucket_;
-                    back_bucket_idx_ = bucket_size_ - 1;
-                }
-                else
-                    --back_bucket_idx_;
-
-                allocator_.destroy(&data_[back_bucket_][back_bucket_idx_]);
-                --size_;
-            }
-
-            void pop_front()
-            {
-                if (empty())
-                    return;
-
-                if (front_bucket_idx_ >= bucket_size_)
-                { // Means we gotta pop data_[front_bucket_ + 1][0]!
-                    if (data_[front_bucket_])
-                        allocator_.deallocate(data_[front_bucket_], bucket_size_);
-
-                    ++front_bucket_;
-                    front_bucket_idx_ = 1;
-
-                    allocator_.destroy(&data_[front_bucket_][0]);
-                }
-                else
-                {
-                    allocator_.destroy(&data_[front_bucket_][front_bucket_idx_]);
-
-                    ++front_bucket_idx_;
-                }
-
-                --size_;
-            }
-
-            iterator erase(const_iterator position)
-            {
-                auto idx = position.idx();
-                copy(
-                    iterator{*this, idx + 1},
-                    end(),
-                    iterator{*this, idx}
-                );
-
-                /**
-                 * Note: We need to not only decrement size,
-                 *       but also take care of any issues caused
-                 *       by decrement bucket indices, which pop_back
-                 *       does for us.
-                 */
-                pop_back();
-
-                return iterator{*this, idx};
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                if (first == last)
-                    return first;
-
-                auto first_idx = first.idx();
-                auto last_idx = last.idx();
-                auto count = distance(first, last);
-
-                copy(
-                    iterator{*this, last_idx},
-                    end(),
-                    iterator{*this, first_idx}
-                );
-
-                for (size_type i = 0; i < count; ++i)
-                    pop_back();
-
-                return iterator{*this, first_idx};
-            }
-
-            void swap(deque& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                std::swap(allocator_, other.allocator_);
-                std::swap(front_bucket_idx_, other.front_bucket_idx_);
-                std::swap(back_bucket_idx_, other.back_bucket_idx_);
-                std::swap(front_bucket_, other.front_bucket_);
-                std::swap(back_bucket_, other.back_bucket_);
-                std::swap(bucket_count_, other.bucket_count_);
-                std::swap(bucket_capacity_, other.bucket_capacity_);
-                std::swap(size_, other.size_);
-                std::swap(data_, other.data_);
-            }
-
-            void clear() noexcept
-            {
-                if (data_)
-                    fini_();
-
-                front_bucket_ = default_front_;
-                back_bucket_ = default_back_;
-                bucket_count_ = default_bucket_count_;
-                bucket_capacity_ = default_bucket_capacity_;
-                size_ = size_type{};
-
-                init_();
-            }
-
-        private:
-            allocator_type allocator_;
-
-            /**
-             * Note: In our implementation, front_bucket_idx_
-             *       points at the first element and back_bucket_idx_
-             *       points at the one past last element. Because of this,
-             *       some operations may be done in inverse order
-             *       depending on the side they are applied to.
-             */
-            size_type front_bucket_idx_;
-            size_type back_bucket_idx_;
-            size_type front_bucket_;
-            size_type back_bucket_;
-
-            static constexpr size_type bucket_size_{16};
-            static constexpr size_type default_bucket_count_{2};
-            static constexpr size_type default_bucket_capacity_{4};
-            static constexpr size_type default_front_{1};
-            static constexpr size_type default_back_{2};
-
-            size_type bucket_count_;
-            size_type bucket_capacity_;
-            size_type size_{};
-
-            value_type** data_;
-
-            void init_()
-            {
-                data_ = new value_type*[bucket_capacity_];
-
-                for (size_type i = front_bucket_; i <= back_bucket_; ++i)
-                    data_[i] = allocator_.allocate(bucket_size_);
-            }
-
-            void prepare_for_size_(size_type size)
-            {
-                if (data_)
-                    fini_();
-
-                bucket_count_ = bucket_capacity_ = size / bucket_size_ + 2;
-
-                front_bucket_ = 0;
-                back_bucket_ = bucket_capacity_ - 1;
-
-                front_bucket_idx_ = bucket_size_;
-                back_bucket_idx_ = size % bucket_size_;
-            }
-
-            template<class Iterator>
-            void copy_from_range_(Iterator first, Iterator last)
-            {
-                size_ = distance(first, last);
-                prepare_for_size_(size_);
-                init_();
-
-                auto it = begin();
-                while (first != last)
-                    *it++ = *first++;
-            }
-
-            void ensure_space_front_(size_type idx, size_type count)
-            {
-                auto free_space = bucket_size_ - elements_in_front_bucket_();
-                if (front_bucket_idx_ == 0)
-                    free_space = 0;
-
-                if (count <= free_space)
-                {
-                    front_bucket_idx_ -= count;
-                    return;
-                }
-
-                count -= free_space;
-
-                auto buckets_needed = count / bucket_size_;
-                if (count % bucket_size_ != 0)
-                    ++buckets_needed;
-
-                for (size_type i = size_type{}; i < buckets_needed; ++i)
-                    add_new_bucket_front_();
-
-                front_bucket_idx_ = bucket_size_ - (count % bucket_size_);
-            }
-
-            void ensure_space_back_(size_type idx, size_type count)
-            {
-                auto free_space = bucket_size_ - back_bucket_idx_;
-                if (count < free_space)
-                    return;
-
-                count -= free_space;
-                auto buckets_needed = count / bucket_size_;
-                if (count % bucket_size_ != 0)
-                    ++buckets_needed;
-
-                for (size_type i = size_type{}; i < buckets_needed; ++i)
-                    add_new_bucket_back_();
-
-                back_bucket_idx_ = (back_bucket_idx_ + count) % bucket_size_;
-            }
-
-            void shift_right_(size_type idx, size_type count)
-            {
-                ensure_space_back_(idx, count);
-
-                iterator it{*this, idx};
-                copy_backward(it, end(), end() + count - 1);
-
-            }
-
-            void shift_left_(size_type idx, size_type count)
-            {
-                ensure_space_front_(idx, count);
-
-                copy(
-                    iterator{*this, count},
-                    iterator{*this, idx + count - 1},
-                    iterator{*this, 0}
-                );
-            }
-
-            void fini_()
-            {
-                for (size_type i = front_bucket_; i <= back_bucket_; ++i)
-                    allocator_.deallocate(data_[i], bucket_size_);
-
-                delete[] data_;
-                data_ = nullptr;
-            }
-
-            bool has_bucket_space_back_() const
-            {
-                return back_bucket_ < bucket_capacity_ - 1;
-            }
-
-            bool has_bucket_space_front_() const
-            {
-                return front_bucket_ > 0;
-            }
-
-            void add_new_bucket_back_()
-            {
-                if (!has_bucket_space_back_())
-                    expand_();
-
-                ++back_bucket_;
-                ++bucket_count_;
-                data_[back_bucket_] = allocator_.allocate(bucket_size_);
-                back_bucket_idx_ = size_type{};
-            }
-
-            void add_new_bucket_front_()
-            {
-                if (!has_bucket_space_front_())
-                    expand_();
-
-                --front_bucket_;
-                ++bucket_count_;
-                data_[front_bucket_] = allocator_.allocate(bucket_size_);
-                front_bucket_idx_ = bucket_size_;
-            }
-
-            void expand_()
-            {
-                bucket_capacity_ *= 2;
-                value_type** new_data = new value_type*[bucket_capacity_];
-
-                /**
-                 * Note: This currently expands both sides whenever one reaches
-                 *       its limit. Might be better to expand only one (or both when
-                 *       the other is near its limit)?
-                 */
-                size_type new_front = bucket_capacity_ / 4;
-                size_type new_back = new_front + bucket_count_ - 1;
-
-                for (size_type i = new_front, j = front_bucket_; i <= new_back; ++i, ++j)
-                    new_data[i] = move(data_[j]);
-                std::swap(data_, new_data);
-
-                delete[] new_data;
-                front_bucket_ = new_front;
-                back_bucket_ = new_back;
-            }
-
-            size_type get_bucket_index_(size_type idx) const
-            {
-                if (idx < elements_in_front_bucket_())
-                    return front_bucket_;
-
-                idx -= elements_in_front_bucket_();
-                return idx / bucket_size_ + front_bucket_ + 1;
-            }
-
-            size_type get_element_index_(size_type idx) const
-            {
-                if (idx < elements_in_front_bucket_())
-                    return bucket_size_ - elements_in_front_bucket_() + idx;
-
-                idx -= elements_in_front_bucket_();
-                return idx % bucket_size_;
-            }
-
-            size_type elements_in_front_bucket_() const
-            {
-                return bucket_size_ - front_bucket_idx_;
-            }
-    };
-
-    template<class T, class Allocator>
-    bool operator==(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        if (lhs.size() != rhs.size())
-            return false;
-
-        for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i)
-        {
-            if (lhs[i] != rhs[i])
-                return false;
-        }
-
-        return true;
-    }
-
-    template<class T, class Allocator>
-    bool operator<(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        auto min_size = min(lhs.size(), rhs.size());
-        for (decltype(lhs.size()) i = 0; i < min_size; ++i)
-        {
-            if (lhs[i] >= rhs[i])
-                return false;
-        }
-
-        if (lhs.size() == rhs.size())
-            return true;
-        else
-            return lhs.size() < rhs.size();
-    }
-
-    template<class T, class Allocator>
-    bool operator!=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class T, class Allocator>
-    bool operator>(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class T, class Allocator>
-    bool operator<=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class T, class Allocator>
-    bool operator>=(const deque<T, Allocator>& lhs, const deque<T, Allocator>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    /**
-     * 23.3.3.5, deque specialized algorithms:
-     */
-
-    template<class T, class Allocator>
-    void swap(deque<T, Allocator>& lhs, deque<T, Allocator>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/exception.hpp
===================================================================
--- uspace/lib/cpp/include/impl/exception.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,140 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_EXCEPTION
-#define LIBCPP_EXCEPTION
-
-#include <__bits/trycatch.hpp>
-
-namespace std
-{
-    /**
-     * 18.8.1, class exception:
-     */
-
-    class exception
-    {
-        public:
-            exception() noexcept = default;
-            exception(const exception&) noexcept = default;
-            exception& operator=(const exception&) noexcept = default;
-            virtual ~exception() = default;
-
-            virtual const char* what() const noexcept;
-    };
-
-    /**
-     * 18.8.2, class bad_exception:
-     */
-
-    class bad_exception: public exception
-    {
-        public:
-            bad_exception() noexcept = default;
-            bad_exception(const bad_exception&) noexcept = default;
-            bad_exception& operator=(const bad_exception&) noexcept = default;
-
-            virtual const char* what() const noexcept;
-    };
-
-    /**
-     * 18.8.3, abnormal termination:
-     */
-
-    using terminate_handler = void (*)();
-
-    terminate_handler get_terminate() noexcept;
-    terminate_handler set_terminate(terminate_handler) noexcept;
-    [[noreturn]] void terminate() noexcept;
-
-    /**
-     * 18.8.4, uncaght_exceptions:
-     */
-
-    bool uncaught_exception() noexcept;
-    int uncaught_exceptions() noexcept;
-
-    using unexpected_handler = void (*)();
-
-    unexpected_handler get_unexpected() noexcept;
-    unexpected_handler set_unexpected(unexpected_handler) noexcept;
-    [[noreturn]] void unexpected();
-
-    /**
-     * 18.8.5, exception propagation:
-     */
-
-    namespace aux
-    {
-        class exception_ptr_t
-        { /* DUMMY BODY */ };
-    }
-
-    using exception_ptr = aux::exception_ptr_t;
-
-    exception_ptr current_exception() noexcept;
-    [[noreturn]] void rethrow_exception(exception_ptr);
-
-    template<class E>
-    exception_ptr make_exception_ptr(E e) noexcept
-    {
-        return exception_ptr{};
-    }
-
-    class nested_exception
-    {
-        public:
-            nested_exception() noexcept = default;
-            nested_exception(const nested_exception&) noexcept = default;
-            nested_exception& operator=(const nested_exception&) noexcept = default;
-            virtual ~nested_exception() = default;
-
-            [[noreturn]] void throw_nested() const;
-            exception_ptr nested_ptr() const noexcept;
-
-        private:
-            exception_ptr ptr_;
-    };
-
-    template<class E>
-    [[noreturn]] void throw_with_nested(E&& e)
-    {
-        terminate();
-    }
-
-    template<class E>
-    void rethrow_if_nested(const E& e)
-    {
-        auto casted = dynamic_cast<const nested_exception*>(&e);
-        if (casted)
-            casted->throw_nested();
-    }
-}
-
-#endif
-
Index: uspace/lib/cpp/include/impl/forward_list.hpp
===================================================================
--- uspace/lib/cpp/include/impl/forward_list.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_FORWARD_LIST
-#define LIBCPP_FORWARD_LIST
-
-#error "<forward_list> is not implemented"
-
-#endif
Index: uspace/lib/cpp/include/impl/fstream.hpp
===================================================================
--- uspace/lib/cpp/include/impl/fstream.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,713 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_FSTREAM
-#define LIBCPP_FSTREAM
-
-#include <cstdio>
-#include <ios>
-#include <iosfwd>
-#include <locale>
-#include <streambuf>
-#include <string>
-
-namespace std
-{
-    /**
-     * 27.9.1.1, class template basic_filebuf:
-     */
-    template<class Char, class Traits>
-    class basic_filebuf: public basic_streambuf<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.9.1.2, constructors/destructor:
-             */
-
-            basic_filebuf()
-                : basic_streambuf<char_type, traits_type>{},
-                  obuf_{nullptr}, ibuf_{nullptr}, mode_{}, file_{nullptr}
-            { /* DUMMY BODY */ }
-
-            basic_filebuf(const basic_filebuf&) = delete;
-
-            basic_filebuf(basic_filebuf&& other)
-                : mode_{other.mode_}
-            {
-                close();
-                std::swap(obuf_, other.obuf_);
-                std::swap(ibuf_, other.ibuf_);
-                std::swap(file_, other.file_);
-
-                basic_streambuf<char_type, traits_type>::swap(other);
-            }
-
-            virtual ~basic_filebuf()
-            {
-                // TODO: exception here caught and not rethrown
-                close();
-            }
-
-            /**
-             * 27.9.1.3: assign/swap:
-             */
-
-            basic_filebuf& operator=(const basic_filebuf&) = delete;
-
-            basic_filebuf& operator=(basic_filebuf&& other)
-            {
-                close();
-                swap(other);
-
-                return *this;
-            }
-
-            void swap(basic_filebuf& rhs)
-            {
-                std::swap(mode_, rhs.mode_);
-                std::swap(obuf_, rhs.obuf_);
-                std::swap(ibuf_, rhs.ibuf_);
-
-                basic_streambuf<char_type, traits_type>::swap(rhs);
-            }
-
-            /**
-             * 27.9.1.4, members:
-             */
-
-            bool is_open() const
-            {
-                return file_ != nullptr;
-            }
-
-            basic_filebuf<char_type, traits_type>* open(const char* name, ios_base::openmode mode)
-            {
-                if (file_)
-                    return nullptr;
-
-                mode_ = mode;
-                mode = (mode & (~ios_base::ate));
-                const char* mode_str = get_mode_str_(mode);
-
-                if (!mode_str)
-                    return nullptr;
-
-                file_ = fopen(name, mode_str);
-                if (!file_)
-                    return nullptr;
-
-                if ((mode_ & ios_base::ate) != 0)
-                {
-                    if (fseek(file_, 0, SEEK_END) != 0)
-                    {
-                        close();
-                        return nullptr;
-                    }
-                }
-
-                if (!ibuf_ && mode_is_in_(mode_))
-                    ibuf_ = new char_type[buf_size_];
-                if (!obuf_ && mode_is_out_(mode_))
-                    obuf_ = new char_type[buf_size_];
-                init_();
-
-                return this;
-            }
-
-            basic_filebuf<char_type, traits_type>* open(const string& name, ios_base::openmode mode)
-            {
-                return open(name.c_str(), mode);
-            }
-
-            basic_filebuf<char_type, traits_type>* close()
-            {
-                // TODO: caught exceptions are to be rethrown after closing the file
-                if (!file_)
-                    return nullptr;
-                // TODO: deallocate buffers?
-
-                if (this->output_next_ != this->output_begin_)
-                    overflow(traits_type::eof());
-                // TODO: unshift? (p. 1084 at the top)
-
-                fclose(file_);
-                file_ = nullptr;
-
-                return this;
-            }
-
-        protected:
-            /**
-             * 27.9.1.5, overriden virtual functions:
-             */
-
-            int_type underflow() override
-            {
-                // TODO: use codecvt
-                if (!mode_is_in_(mode_))
-                    return traits_type::eof();
-
-                if (!ibuf_)
-                {
-                    ibuf_ = new char_type[buf_size_];
-                    this->input_begin_ = this->input_next_ = this->input_end_ = ibuf_;
-                }
-
-                off_type i{};
-                if (this->input_next_ < this->input_end_)
-                {
-                    auto idx = static_cast<off_type>(this->input_next_ - this->input_begin_);
-                    auto count = static_cast<off_type>(buf_size_) - idx;
-
-                    for (; i < count; ++i, ++idx)
-                        ibuf_[i] = ibuf_[idx];
-                }
-
-                for (; i < static_cast<off_type>(buf_size_); ++i)
-                {
-                    auto c = fgetc(file_);
-                    if (c == traits_type::eof())
-                        break;
-
-                    ibuf_[i] = static_cast<char_type>(c);
-
-                    if (ibuf_[i] == '\n')
-                    {
-                        ++i;
-                        break;
-                    }
-                }
-
-                this->input_next_ = this->input_begin_;
-                this->input_end_ = this->input_begin_ + i;
-
-                if (i == 0)
-                    return traits_type::eof();
-
-                return traits_type::to_int_type(*this->input_next_);
-            }
-
-            int_type pbackfail(int_type c = traits_type::eof()) override
-            {
-                auto cc = traits_type::to_char_type(c);
-                if (!traits_type::eq_int_type(c, traits_type::eof()) &&
-                    this->putback_avail_() &&
-                    traits_type::eq(cc, this->gptr()[-1]))
-                {
-                    --this->input_next_;
-
-                    return c;
-                }
-                else if (!traits_type::eq_int_type(c, traits_type::eof()) &&
-                         this->putback_avail_() && (mode_ & ios_base::out) != 0)
-                {
-                    *--this->input_next_ = cc;
-
-                    return c;
-                }
-                else if (traits_type::eq_int_type(c, traits_type::eof()) &&
-                         this->putback_avail_())
-                {
-                    --this->input_next_;
-
-                    return traits_type::not_eof(c);
-                }
-
-                return traits_type::eof();
-            }
-
-            int_type overflow(int_type c = traits_type::eof()) override
-            {
-                // TODO: use codecvt
-                if (!mode_is_out_(mode_))
-                    return traits_type::eof();
-
-                auto count = static_cast<size_t>(this->output_next_ - this->output_begin_);
-                fwrite(obuf_, sizeof(char_type), count, file_);
-                fflush(file_);
-
-                this->output_next_ = this->output_begin_;
-
-                return traits_type::not_eof(c);
-            }
-
-            basic_streambuf<char_type, traits_type>*
-            setbuf(char_type* s, streamsize n) override
-            {
-                // TODO: implement
-                return nullptr;
-            }
-
-            pos_type seekoff(off_type off, ios_base::seekdir dir,
-                             ios_base::openmode mode = ios_base::in | ios_base::out) override
-            {
-                // TODO: implement
-                return pos_type{};
-            }
-
-            pos_type seekpos(pos_type pos,
-                             ios_base::openmode mode = ios_base::in | ios_base::out) override
-            {
-                // TODO: implement
-                return pos_type{};
-            }
-
-            int sync() override
-            {
-                if (mode_is_out_(mode_))
-                    overflow();
-
-                return 0; // TODO: what is the correct return value?
-            }
-
-            void imbue(const locale& loc) override
-            {
-                // TODO: codecvt should be cached when we start using it
-                basic_streambuf<char_type, traits_type>::imbue(loc);
-            }
-
-        private:
-            char_type* obuf_;
-            char_type* ibuf_;
-
-            ios_base::openmode mode_;
-
-            FILE* file_;
-
-            static constexpr size_t buf_size_{128};
-
-            const char* get_mode_str_(ios_base::openmode mode)
-            {
-                /**
-                 * See table 132.
-                 */
-                switch (mode)
-                {
-                    case ios_base::out:
-                    case ios_base::out | ios_base::trunc:
-                        return "w";
-                    case ios_base::out | ios_base::app:
-                    case ios_base::app:
-                        return "a";
-                    case ios_base::in:
-                        return "r";
-                    case ios_base::in | ios_base::out:
-                        return "r+";
-                    case ios_base::in | ios_base::out | ios_base::trunc:
-                        return "w+";
-                    case ios_base::in | ios_base::out | ios_base::app:
-                    case ios_base::in | ios_base::app:
-                        return "a+";
-                    case ios_base::binary | ios_base::out:
-                    case ios_base::binary | ios_base::out | ios_base::trunc:
-                        return "wb";
-                    case ios_base::binary | ios_base::out | ios_base::app:
-                    case ios_base::binary | ios_base::app:
-                        return "ab";
-                    case ios_base::binary | ios_base::in:
-                        return "rb";
-                    case ios_base::binary | ios_base::in | ios_base::out:
-                        return "r+b";
-                    case ios_base::binary | ios_base::in | ios_base::out | ios_base::trunc:
-                        return "w+b";
-                    case ios_base::binary | ios_base::in | ios_base::out | ios_base::app:
-                    case ios_base::binary | ios_base::in | ios_base::app:
-                        return "a+b";
-                    default:
-                        return nullptr;
-                }
-            }
-
-            bool mode_is_in_(ios_base::openmode mode)
-            {
-                return (mode & ios_base::in) != 0;
-            }
-
-            bool mode_is_out_(ios_base::openmode mode)
-            {
-                return (mode & (ios_base::out | ios_base::app | ios_base::trunc)) != 0;
-            }
-
-            void init_()
-            {
-                if (ibuf_)
-                    this->input_begin_ = this->input_next_ = this->input_end_ = ibuf_;
-
-                if (obuf_)
-                {
-                    this->output_begin_ = this->output_next_ = obuf_;
-                    this->output_end_ = obuf_ + buf_size_;
-                }
-            }
-    };
-
-    template<class Char, class Traits>
-    void swap(basic_filebuf<Char, Traits>& lhs, basic_filebuf<Char, Traits>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 27.9.1.6, class template basic_ifstream:
-     */
-
-    template<class Char, class Traits>
-    class basic_ifstream: public basic_istream<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.9.1.7, constructors:
-             */
-
-            basic_ifstream()
-                : basic_istream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            { /* DUMMY BODY */ }
-
-            explicit basic_ifstream(const char* name, ios_base::openmode mode = ios_base::in)
-                : basic_istream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode | ios_base::in))
-                    this->setstate(ios_base::failbit);
-            }
-
-            explicit basic_ifstream(const string& name, ios_base::openmode mode = ios_base::in)
-                : basic_istream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode | ios_base::in))
-                    this->setstate(ios_base::failbit);
-            }
-
-            basic_ifstream(const basic_ifstream&) = delete;
-
-            basic_ifstream(basic_ifstream&& other)
-                : basic_istream<char_type, traits_type>{move(other)},
-                  rdbuf_{other.rdbuf_}
-            {
-                basic_istream<char_type, traits_type>::set_rdbuf(&rdbuf_);
-            }
-
-            /**
-             * 27.9.1.8, assign/swap:
-             */
-
-            basic_ifstream& operator=(const basic_ifstream&) = delete;
-
-            basic_ifstream& operator=(basic_ifstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_ifstream& rhs)
-            {
-                basic_istream<char_type, traits_type>::swap(rhs);
-                rdbuf_.swap(rhs.rdbuf_);
-            }
-
-            /**
-             * 27.9.1.9, members:
-             */
-
-            basic_filebuf<char_type, traits_type>* rdbuf() const
-            {
-                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
-            }
-
-            bool is_open() const
-            {
-                return rdbuf_.is_open();
-            }
-
-            void open(const char* name, ios_base::openmode mode = ios_base::in)
-            {
-                if (!rdbuf_.open(name, mode | ios_base::in))
-                    this->setstate(ios_base::failbit);
-                else
-                    this->clear();
-            }
-
-            void open(const string& name, ios_base::openmode mode = ios_base::in)
-            {
-                open(name.c_str(), mode);
-            }
-
-            void close()
-            {
-                if (!rdbuf_.close())
-                    this->setstate(ios_base::failbit);
-            }
-
-        private:
-            basic_filebuf<char_type, traits_type> rdbuf_;
-    };
-
-    template<class Char, class Traits>
-    void swap(basic_ifstream<Char, Traits>& lhs,
-              basic_ifstream<Char, Traits>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 27.9.1.10, class template basic_ofstream:
-     */
-
-    template<class Char, class Traits>
-    class basic_ofstream: public basic_ostream<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.9.1.11, constructors:
-             */
-
-            basic_ofstream()
-                : basic_ostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            { /* DUMMY BODY */ }
-
-            explicit basic_ofstream(const char* name, ios_base::openmode mode = ios_base::out)
-                : basic_ostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode | ios_base::out))
-                    this->setstate(ios_base::failbit);
-            }
-
-            explicit basic_ofstream(const string& name, ios_base::openmode mode = ios_base::out)
-                : basic_ostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode | ios_base::out))
-                    this->setstate(ios_base::failbit);
-            }
-
-            basic_ofstream(const basic_ofstream&) = delete;
-
-            basic_ofstream(basic_ofstream&& other)
-                : basic_ostream<char_type, traits_type>{move(other)},
-                  rdbuf_{other.rdbuf_}
-            {
-                basic_ostream<char_type, traits_type>::set_rdbuf(&rdbuf_);
-            }
-
-            /**
-             * 27.9.1.12, assign/swap:
-             */
-
-            basic_ofstream& operator=(const basic_ofstream&) = delete;
-
-            basic_ofstream& operator=(basic_ofstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_ofstream& rhs)
-            {
-                basic_ostream<char_type, traits_type>::swap(rhs);
-                rdbuf_.swap(rhs.rdbuf_);
-            }
-
-            /**
-             * 27.9.1.13, members:
-             */
-
-            basic_filebuf<char_type, traits_type>* rdbuf() const
-            {
-                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
-            }
-
-            bool is_open() const
-            {
-                return rdbuf_.is_open();
-            }
-
-            void open(const char* name, ios_base::openmode mode = ios_base::out)
-            {
-                if (!rdbuf_.open(name, mode | ios_base::out))
-                    this->setstate(ios_base::failbit);
-                else
-                    this->clear();
-            }
-
-            void open(const string& name, ios_base::openmode mode = ios_base::out)
-            {
-                open(name.c_str(), mode);
-            }
-
-            void close()
-            {
-                if (!rdbuf_.close())
-                    this->setstate(ios_base::failbit);
-            }
-
-        private:
-            basic_filebuf<char_type, traits_type> rdbuf_;
-    };
-
-    template<class Char, class Traits>
-    void swap(basic_ofstream<Char, Traits>& lhs,
-              basic_ofstream<Char, Traits>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 27.9.1.14, class template basic_fstream:
-     */
-
-    template<class Char, class Traits>
-    class basic_fstream: public basic_iostream<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.9.1.15, constructors:
-             */
-
-            basic_fstream()
-                : basic_iostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            { /* DUMMY BODY */ }
-
-            explicit basic_fstream(const char* name,
-                                   ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_iostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode))
-                    this->setstate(ios_base::failbit);
-            }
-
-            explicit basic_fstream(const string& name,
-                                   ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_iostream<char_type, traits_type>{&rdbuf_},
-                  rdbuf_{}
-            {
-                if (!rdbuf_.open(name, mode))
-                    this->setstate(ios_base::failbit);
-            }
-
-            basic_fstream(const basic_fstream&) = delete;
-
-            basic_fstream(basic_fstream&& other)
-                : basic_iostream<char_type, traits_type>{move(other)},
-                  rdbuf_{other.rdbuf_}
-            {
-                basic_iostream<char_type, traits_type>::set_rdbuf(&rdbuf_);
-            }
-
-            /**
-             * 27.9.1.16, assign/swap:
-             */
-
-            basic_fstream& operator=(const basic_fstream&) = delete;
-
-            basic_fstream& operator=(basic_fstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_fstream& rhs)
-            {
-                basic_iostream<char_type, traits_type>::swap(rhs);
-                rdbuf_.swap(rhs.rdbuf_);
-            }
-
-            /**
-             * 27.9.1.17, members:
-             */
-
-            basic_filebuf<char_type, traits_type>* rdbuf() const
-            {
-                return const_cast<basic_filebuf<char_type, traits_type>*>(&rdbuf_);
-            }
-
-            bool is_open() const
-            {
-                return rdbuf_.is_open();
-            }
-
-            void open(const char* name,
-                      ios_base::openmode mode = ios_base::in | ios_base::out)
-            {
-                if (!rdbuf_.open(name, mode))
-                    this->setstate(ios_base::failbit);
-                else
-                    this->clear();
-            }
-
-            void open(const string& name,
-                      ios_base::openmode mode = ios_base::in | ios_base::out)
-            {
-                open(name.c_str(), mode);
-            }
-
-            void close()
-            {
-                if (!rdbuf_.close())
-                    this->setstate(ios_base::failbit);
-            }
-
-        private:
-            basic_filebuf<char_type, traits_type> rdbuf_;
-    };
-
-    template<class Char, class Traits>
-    void swap(basic_fstream<Char, Traits>& lhs,
-              basic_fstream<Char, Traits>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/functional.hpp
===================================================================
--- uspace/lib/cpp/include/impl/functional.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_FUNCTIONAL
-#define LIBCPP_FUNCTIONAL
-
-#include <__bits/functional/conditional_function_typedefs.hpp>
-#include <__bits/functional/invoke.hpp>
-#include <limits>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 20.9.3, invoke:
-     */
-
-    template<class F, class... Args>
-    decltype(auto) invoke(F&& f, Args&&... args)
-    {
-        return aux::INVOKE(forward<F>(f)(forward<Args>(args)...));
-    }
-
-    /**
-     * 20.9.11, member function adaptors:
-     */
-
-    namespace aux
-    {
-        template<class F>
-        class mem_fn_t
-            : public conditional_function_typedefs<remove_cv_t<remove_reference_t<F>>>
-        {
-            public:
-                mem_fn_t(F f)
-                    : func_{f}
-                { /* DUMMY BODY */ }
-
-                template<class... Args>
-                decltype(auto) operator()(Args&&... args)
-                {
-                    return INVOKE(func_, forward<Args>(args)...);
-                }
-
-            private:
-                F func_;
-        };
-    }
-
-    template<class R, class T>
-    aux::mem_fn_t<R T::*> mem_fn(R T::* f)
-    {
-        return aux::mem_fn_t<R T::*>{f};
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/future.hpp
===================================================================
--- uspace/lib/cpp/include/impl/future.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,183 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_FUTURE
-#define LIBCPP_FUTURE
-
-#include <memory>
-#include <system_error>
-#include <type_traits>
-
-namespace std
-{
-    /**
-     * 30.6, futures:
-     */
-
-    enum class future_errc
-    { // The 5001 start is to not collide with system_error's codes.
-        broken_promise = 5001,
-        future_already_retrieved,
-        promise_already_satisfied,
-        no_state
-    };
-
-    enum class launch
-    {
-        async,
-        deferred
-    };
-
-    enum class future_status
-    {
-        ready,
-        timeout,
-        deferred
-    };
-
-    /**
-     * 30.6.2, error handling:
-     */
-
-    template<>
-    struct is_error_code_enum<future_errc>: true_type
-    { /* DUMMY BODY */ };
-
-    error_code make_error_code(future_errc) noexcept;
-    error_condition make_error_condition(future_errc) noexcept;
-
-    const error_category& future_category() noexcept;
-
-    /**
-     * 30.6.3, class future_error:
-     */
-
-    class future_error: public logic_error
-    {
-        public:
-            future_error(error_code ec);
-
-            const error_code& code() const noexcept;
-
-        private:
-            error_code code_;
-    };
-
-    /**
-     * 30.6.4, shared state:
-     */
-
-    template<class R>
-    class promise
-    {
-    };
-
-    template<class R>
-    class promise<R&>
-    {
-    };
-
-    template<>
-    class promise<void>
-    {
-    };
-
-    template<class R>
-    void swap(promise<R>& lhs, promise<R>& rhs) noexcept
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class R, class Alloc>
-    struct uses_allocator<promise<R>, Alloc>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class R>
-    class future
-    {
-    };
-
-    template<class R>
-    class future<R&>
-    {
-    };
-
-    template<>
-    class future<void>
-    {
-    };
-
-    template<class R>
-    class shared_future
-    {
-    };
-
-    template<class R>
-    class shared_future<R&>
-    {
-    };
-
-    template<>
-    class shared_future<void>
-    {
-    };
-
-    template<class>
-    class packaged_task; // undefined
-
-    template<class R, class... Args>
-    class packaged_task<R(Args...)>
-    {
-    };
-
-    template<class R, class... Args>
-    void swap(packaged_task<R(Args...)>& lhs, packaged_task<R(Args...)>& rhs) noexcept
-    {
-        lhs.swap(rhs);
-    };
-
-    template<class R, class Alloc>
-    struct uses_allocator<packaged_task<R>, Alloc>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class F, class... Args>
-    future<result_of_t<decay_t<F>(decay_t<Args>...)>>
-    async(F&& f, Args&&... args)
-    {
-        // TODO: implement
-    }
-
-    template<class F, class... Args>
-    future<result_of_t<decay_t<F>(decay_t<Args>...)>>
-    async(launch, F&& f, Args&&... args)
-    {
-        // TODO: implement
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/initializer_list.hpp
===================================================================
--- uspace/lib/cpp/include/impl/initializer_list.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,96 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_INITIALIZER_LIST
-#define LIBCPP_INITIALIZER_LIST
-
-#include <cstdlib>
-
-namespace std
-{
-    /**
-     * 18.9, initializer lists:
-     */
-
-    template<class T>
-    class initializer_list
-    {
-        public:
-            using value_type      = T;
-            using const_reference = const T&;
-            using reference       = const_reference;
-            using size_type       = size_t;
-            using const_iterator  = const T*;
-            using iterator        = const_iterator;
-
-            constexpr initializer_list() noexcept
-                : begin_{nullptr}, size_{0}
-            { /* DUMMY BODY */ }
-
-            constexpr size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            constexpr iterator begin() const noexcept
-            {
-                return begin_;
-            }
-
-            constexpr iterator end() const noexcept
-            {
-                return begin_ + size_;
-            }
-
-        private:
-            iterator begin_;
-            size_type size_;
-
-            constexpr initializer_list(iterator begin, size_type size)
-                : begin_{begin}, size_{size}
-            { /* DUMMY BODY */ }
-    };
-
-    /**
-     * 18.9.3, initializer list range access:
-     */
-
-    template<class T>
-    constexpr auto begin(initializer_list<T> init)
-    {
-        return init.begin();
-    }
-
-    template<class T>
-    constexpr auto end(initializer_list<T> init)
-    {
-        return init.end();
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/iomanip.hpp
===================================================================
--- uspace/lib/cpp/include/impl/iomanip.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_IOMANIP
-#define LIBCPP_IOMANIP
-
-#include <__bits/iomanip.hpp>
-#include <iosfwd>
-
-namespace std
-{
-    /**
-     * 27.7.4, standard manipulators:
-     */
-
-    aux::manip_wrapper<aux::resetiosflags_t> resetiosflags(ios_base::fmtflags mask);
-    aux::manip_wrapper<aux::setiosflags_t> setiosflags(ios_base::fmtflags mask);
-    aux::manip_wrapper<aux::setbase_t> setbase(int base);
-
-    template<class Char>
-    aux::setfill_t<Char> setfill(Char c)
-    {
-        return aux::setfill_t<Char>{c};
-    }
-
-    aux::manip_wrapper<aux::setprecision_t> setprecision(int prec);
-    aux::manip_wrapper<aux::setw_t> setw(int width);
-
-    /**
-     * 27.7.5, extended manipulators:
-     */
-
-    // TODO: implement
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/ios.hpp
===================================================================
--- uspace/lib/cpp/include/impl/ios.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,612 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_IOS
-#define LIBCPP_IOS
-
-#include <cstdlib>
-#include <__bits/locale.hpp>
-#include <__bits/locale/ctype.hpp>
-#include <iosfwd>
-#include <system_error>
-#include <utility>
-#include <vector>
-
-namespace std
-{
-    using streamoff = long long;
-    using streamsize = hel::ssize_t;
-
-    /**
-     * 27.5.3, ios_base:
-     */
-
-    class ios_base
-    {
-        public:
-            virtual ~ios_base();
-
-            ios_base(const ios_base&) = delete;
-            ios_base& operator=(const ios_base&) = delete;
-
-            /**
-             * 27.5.3.1.1, failure:
-             */
-
-            class failure: public system_error
-            {
-                // TODO: implement
-            };
-
-            /**
-             * 27.5.3.1.2, fmtflags:
-             */
-
-            using fmtflags = uint16_t;
-            static constexpr fmtflags boolalpha   = 0b0000'0000'0000'0001;
-            static constexpr fmtflags dec         = 0b0000'0000'0000'0010;
-            static constexpr fmtflags fixed       = 0b0000'0000'0000'0100;
-            static constexpr fmtflags hex         = 0b0000'0000'0000'1000;
-            static constexpr fmtflags internal    = 0b0000'0000'0001'0000;
-            static constexpr fmtflags left        = 0b0000'0000'0010'0000;
-            static constexpr fmtflags oct         = 0b0000'0000'0100'0000;
-            static constexpr fmtflags right       = 0b0000'0000'1000'0000;
-            static constexpr fmtflags scientific  = 0b0000'0001'0000'0000;
-            static constexpr fmtflags showbase    = 0b0000'0010'0000'0000;
-            static constexpr fmtflags showpoint   = 0b0000'0100'0000'0000;
-            static constexpr fmtflags showpos     = 0b0000'1000'0000'0000;
-            static constexpr fmtflags skipws      = 0b0001'0000'0000'0000;
-            static constexpr fmtflags unitbuf     = 0b0010'0000'0000'0000;
-            static constexpr fmtflags uppercase   = 0b0100'0000'0000'0000;
-            static constexpr fmtflags adjustfield = left | right | internal;
-            static constexpr fmtflags basefield   = dec  | oct   | hex;
-            static constexpr fmtflags floatfield  = scientific   | fixed;
-
-            /**
-             * 27.5.3.1.3, iostate:
-             */
-
-            using iostate = uint8_t;
-            static constexpr iostate badbit  = 0b0001;
-            static constexpr iostate eofbit  = 0b0010;
-            static constexpr iostate failbit = 0b0100;
-            static constexpr iostate goodbit = 0b0000;
-
-            /**
-             * 27.5.3.1.4, openmode:
-             */
-
-            using openmode = uint8_t;
-            static constexpr openmode app    = 0b00'0001;
-            static constexpr openmode ate    = 0b00'0010;
-            static constexpr openmode binary = 0b00'0100;
-            static constexpr openmode in     = 0b00'1000;
-            static constexpr openmode out    = 0b01'0000;
-            static constexpr openmode trunc  = 0b10'0000;
-
-            /**
-             * 27.5.3.1.5, seekdir:
-             */
-
-            using seekdir = uint8_t;
-            static constexpr seekdir beg = 0b001;
-            static constexpr seekdir cur = 0b010;
-            static constexpr seekdir end = 0b100;
-
-            /**
-             * 27.5.3.1.6, class Init:
-             */
-
-            class Init
-            {
-                public:
-                    Init();
-                    ~Init();
-
-                private:
-                    static int init_cnt_;
-            };
-
-            /**
-             * 27.5.3.2, fmtflags state:
-             */
-
-            fmtflags flags() const;
-            fmtflags flags(fmtflags fmtfl);
-            fmtflags setf(fmtflags fmtfl);
-            fmtflags setf(fmtflags fmtfl, fmtflags mask);
-            void unsetf(fmtflags mask);
-
-            streamsize precision() const;
-            streamsize precision(streamsize prec);
-            streamsize width() const;
-            streamsize width(streamsize wide);
-
-            /**
-             * 27.5.3.3, locales:
-             */
-
-            locale imbue(const locale& loc);
-            locale getloc() const;
-
-            /**
-             * 27.5.3.5, storage:
-             */
-
-            static int xalloc()
-            {
-                // TODO: Concurrent access to this function
-                //       by multiple threads shall not result
-                //       in a data race.
-                return index_++;
-            }
-
-            long& iword(int index);
-            void*& pword(int index);
-
-            /**
-             * 27.5.3.6, callbacks:
-             */
-
-            enum event
-            {
-                erase_event,
-                imbue_event,
-                copyfmt_event
-            };
-
-            using event_callback = void (*)(event, ios_base&, int);
-            void register_callback(event_callback fn, int index);
-
-            static bool sync_with_stdio(bool sync = true)
-            {
-                auto old = sync_;
-                sync_ = sync;
-
-                return old;
-            }
-
-        protected:
-            ios_base();
-
-            static int index_;
-            static bool sync_;
-
-            static long ierror_;
-            static void* perror_;
-            static constexpr size_t initial_size_{10};
-
-            long* iarray_;
-            void** parray_;
-            size_t iarray_size_;
-            size_t parray_size_;
-
-            fmtflags flags_;
-            streamsize precision_;
-            streamsize width_;
-
-            locale locale_;
-
-            vector<pair<event_callback, int>> callbacks_;
-
-        private:
-            static constexpr size_t buffer_size_{64};
-            char buffer_[buffer_size_];
-
-            template<class Char, class Iterator>
-            friend class num_put;
-
-            template<class Char, class Iterator>
-            friend class num_get;
-    };
-
-    /**
-     * 27.5.4, fpos:
-     */
-
-    template<class State>
-    class fpos
-    {
-        public:
-            State state() const
-            {
-                return state_;
-            }
-
-            void state(State st)
-            {
-                state_ = st;
-            }
-
-        private:
-            State state_;
-    };
-
-    /**
-     * 27.5.4.2, fpos requirements:
-     */
-
-    // TODO: implement
-
-    /**
-     * 27.5.5, basic_ios:
-     */
-
-    template<class Char, class Traits>
-    class basic_ios: public ios_base
-    {
-        public:
-            using traits_type = Traits;
-            using char_type   = Char;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            basic_ios(const basic_ios&) = delete;
-            basic_ios& operator=(const basic_ios&) = delete;
-
-            explicit operator bool() const
-            {
-                return !fail();
-            }
-
-            bool operator!() const
-            {
-                return fail();
-            }
-
-            iostate rdstate() const
-            {
-                return rdstate_;
-            }
-
-            void clear(iostate state = goodbit)
-            {
-                if (rdbuf_)
-                    rdstate_ = state;
-                else
-                    rdstate_ = state | badbit;
-
-                if (((state | (rdbuf_ ? goodbit : badbit)) & exceptions_) == 0)
-                    return;
-                // TODO: Else throw failure.
-                return;
-            }
-
-            void setstate(iostate state)
-            {
-                clear(rdstate_ | state);
-            }
-
-            bool good() const
-            {
-                return rdstate_ == 0;
-            }
-
-            bool eof() const
-            {
-                return (rdstate_ & eofbit) != 0;
-            }
-
-            bool fail() const
-            {
-                return (rdstate_ & (failbit | badbit)) != 0;
-            }
-
-            bool bad() const
-            {
-                return (rdstate_ & badbit) != 0;
-            }
-
-            iostate exceptions() const
-            {
-                return exceptions_;
-            }
-
-            void exceptions(iostate except)
-            {
-                exceptions_ = except;
-                clear(rdstate_);
-            }
-
-            /**
-             * 27.5.5.2, constructor/destructor:
-             */
-
-            explicit basic_ios(basic_streambuf<Char, Traits>* sb)
-            {
-                init(sb);
-            }
-
-            virtual ~basic_ios()
-            { /* DUMMY BODY */ }
-
-            /**
-             * 27.5.5.3, members:
-             */
-
-            basic_ostream<Char, Traits>* tie() const
-            {
-                return tie_;
-            }
-
-            basic_ostream<Char, Traits>* tie(basic_ostream<Char, Traits>* tiestr)
-            {
-                auto old = tie_;
-                tie_ = tiestr;
-
-                return old;
-            }
-
-            basic_streambuf<Char, Traits>* rdbuf() const
-            {
-                return rdbuf_;
-            }
-
-            basic_streambuf<Char, Traits>* rdbuf(basic_streambuf<Char, Traits>* sb)
-            {
-                auto old = rdbuf_;
-                rdbuf_ = sb;
-
-                clear();
-
-                return old;
-            }
-
-            basic_ios& copyfmt(const basic_ios& rhs)
-            {
-                if (this == &rhs)
-                    return *this;
-
-                for (auto& callback: callbacks_)
-                    callback.first(erase_event, *this, index_);
-
-                tie_        = rhs.tie_;
-                flags_      = rhs.flags_;
-                width_      = rhs.width_;
-                precision_  = rhs.precision_;
-                fill_      = rhs.fill_;
-                locale_     = rhs.locale_;
-
-                delete[] iarray_;
-                iarray_size_ = rhs.iarray_size_;
-                iarray_ = new long[iarray_size_];
-
-                for (size_t i = 0; i < iarray_size_; ++i)
-                    iarray_[i] = rhs.iarray_[i];
-
-                delete[] parray_;
-                parray_size_ = rhs.parray_size_;
-                parray_ = new long[parray_size_];
-
-                for (size_t i = 0; i < parray_size_; ++i)
-                    parray_[i] = rhs.parray_[i];
-
-                for (auto& callback: callbacks_)
-                    callback.first(copyfmt_event, *this, index_);
-
-                exceptions(rhs.exceptions());
-            }
-
-            char_type fill() const
-            {
-                return fill_;
-            }
-
-            char_type fill(char_type c)
-            {
-                char_type old;
-                traits_type::assign(old, fill_);
-                traits_type::assign(fill_, c);
-
-                return old;
-            }
-
-            locale imbue(const locale& loc)
-            {
-                auto res = ios_base::imbue(loc);
-
-                if (rdbuf_)
-                    rdbuf_->pubimbue(loc);
-
-                return res;
-            }
-
-            char narrow(char_type c, char def) const
-            {
-                return use_facet<ctype<char_type>>(locale_).narrow(c, def);
-            }
-
-            char_type widen(char c) const
-            {
-                return use_facet<ctype<char_type>>(locale_).widen(c);
-            }
-
-        protected:
-            basic_ios()
-            { /* DUMMY BODY */ }
-
-            void init(basic_streambuf<Char, Traits>* sb)
-            {
-                // Initialized according to Table 128.
-                rdbuf_ = sb;
-                tie_ = nullptr;
-                rdstate_ = sb ? goodbit : badbit;
-                exceptions_ = goodbit;
-                flags(skipws | dec);
-
-                width(0);
-                precision(6);
-
-                fill_ = widen(' ');
-                locale_ = locale();
-
-                iarray_ = nullptr;
-                parray_ = nullptr;
-            }
-
-            void move(basic_ios& rhs)
-            {
-                rdbuf_      = nullptr; // rhs keeps it!
-                tie_        = rhs.tie_;
-                exceptions_ = rhs.exceptions_;
-                flags_      = rhs.flags_;
-                width_      = rhs.width_;
-                precision_  = rhs.precision_;
-                fill_       = rhs.fill_;
-                locale_     = move(rhs.locale_);
-                rdstate_    = rhs.rdstate_;
-                callbacks_  = move(rhs.callbacks_);
-
-                delete[] iarray_;
-                iarray_      = rhs.iarray_;
-                iarray_size_ = rhs.iarray_size_;
-
-                delete[] parray_;
-                parray_      = rhs.parray_;
-                parray_size_ = rhs.parray_size_;
-
-                rhs.tie_ = nullptr;
-                rhs.iarray_ = nullptr;
-                rhs.parray_ = nullptr;
-            }
-
-            void move(basic_ios&& rhs)
-            {
-                rdbuf_      = nullptr; // rhs keeps it!
-                tie_        = rhs.tie_;
-                exceptions_ = rhs.exceptions_;
-                flags_      = rhs.flags_;
-                width_      = rhs.width_;
-                precision_  = rhs.precision_;
-                fill_       = rhs.fill_;
-                locale_     = move(rhs.locale_);
-                rdstate_    = rhs.rdstate_;
-                callbacks_.swap(rhs.callbacks_);
-
-                delete[] iarray_;
-                iarray_      = rhs.iarray_;
-                iarray_size_ = rhs.iarray_size_;
-
-                delete[] parray_;
-                parray_      = rhs.parray_;
-                parray_size_ = rhs.parray_size_;
-
-                rhs.tie_ = nullptr;
-                rhs.iarray_ = nullptr;
-                rhs.parray_ = nullptr;
-            }
-
-            void swap(basic_ios& rhs) noexcept
-            {
-                // Swap everything but rdbuf_.
-                swap(tie_, rhs.tie_);
-                swap(exceptions_, rhs.exceptions_);
-                swap(flags_, rhs.flags_);
-                swap(width_, rhs.width_);
-                swap(precision_, rhs.precision_);
-                swap(fill_, rhs.fill_);
-                swap(locale_, rhs.locale_);
-                swap(rdstate_, rhs.rdstate_);
-                swap(callbacks_, rhs.callbacks_);
-                swap(iarray_);
-                swap(iarray_size_);
-                swap(parray_);
-                swap(parray_size_);
-            }
-
-            void set_rdbuf(basic_streambuf<Char, Traits>* sb)
-            {
-                // No call to clear is intentional.
-                rdbuf_ = sb;
-            }
-
-        private:
-            basic_streambuf<Char, Traits>* rdbuf_;
-            basic_ostream<Char, Traits>* tie_;
-            iostate rdstate_;
-            iostate exceptions_;
-            char_type fill_;
-    };
-
-    /**
-     * 27.5.6, ios_base manipulators:
-     */
-
-    /**
-     * 27.5.6.1, fmtflags manipulators:
-     */
-
-    ios_base& boolalpha(ios_base& str);
-    ios_base& noboolalpha(ios_base& str);
-    ios_base& showbase(ios_base& str);
-    ios_base& noshowbase(ios_base& str);
-    ios_base& showpoint(ios_base& str);
-    ios_base& noshowpoint(ios_base& str);
-    ios_base& showpos(ios_base& str);
-    ios_base& noshowpos(ios_base& str);
-    ios_base& skipws(ios_base& str);
-    ios_base& noskipws(ios_base& str);
-    ios_base& uppercase(ios_base& str);
-    ios_base& nouppercase(ios_base& str);
-    ios_base& unitbuf(ios_base& str);
-    ios_base& nounitbuf(ios_base& str);
-
-    /**
-     * 27.5.6.2, adjustfield manipulators:
-     */
-
-    ios_base& internal(ios_base& str);
-    ios_base& left(ios_base& str);
-    ios_base& right(ios_base& str);
-
-    /**
-     * 27.5.6.3, basefield manupulators:
-     */
-
-    ios_base& dec(ios_base& str);
-    ios_base& hex(ios_base& str);
-    ios_base& oct(ios_base& str);
-
-    /**
-     * 27.5.6.4, floatfield manupulators:
-     */
-
-    ios_base& fixed(ios_base& str);
-    ios_base& scientific(ios_base& str);
-    ios_base& hexfloat(ios_base& str);
-    ios_base& defaultfloat(ios_base& str);
-
-    /**
-     * 27.5.6.5, error reporting:
-     */
-
-    // TODO: implement
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/iosfwd.hpp
===================================================================
--- uspace/lib/cpp/include/impl/iosfwd.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_IOSFWD
-#define LIBCPP_IOSFWD
-
-namespace std
-{
-    /**
-     * 27.3, forward declarations:
-     */
-
-    template<class Char>
-    class char_traits;
-
-    template<>
-    class char_traits<char>;
-
-    template<>
-    class char_traits<char16_t>;
-
-    template<>
-    class char_traits<char32_t>;
-
-    template<>
-    class char_traits<wchar_t>;
-
-
-
-    template<class T>
-    class allocator;
-
-
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_ios;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_streambuf;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_istream;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_ostream;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_iostream;
-
-
-
-    template<class Char, class Traits = char_traits<Char>,
-             class Allocator = allocator<Char>>
-    class basic_stringbuf;
-
-    template<class Char, class Traits = char_traits<Char>,
-             class Allocator = allocator<Char>>
-    class basic_istringstream;
-
-    template<class Char, class Traits = char_traits<Char>,
-             class Allocator = allocator<Char>>
-    class basic_ostringstream;
-
-    template<class Char, class Traits = char_traits<Char>,
-             class Allocator = allocator<Char>>
-    class basic_stringstream;
-
-
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_filebuf;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_ifstream;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_ofstream;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class basic_fstream;
-
-
-
-    template<class Char, class Traits = char_traits<Char>>
-    class istreambuf_iterator;
-
-    template<class Char, class Traits = char_traits<Char>>
-    class ostreambuf_iterator;
-
-    using ios  = basic_ios<char>;
-    using wios = basic_ios<wchar_t>;
-
-    using streambuf = basic_streambuf<char>;
-    using istream   = basic_istream<char>;
-    using ostream   = basic_ostream<char>;
-    using iostream  = basic_iostream<char>;
-
-    using stringbuf     = basic_stringbuf<char>;
-    using istringstream = basic_istringstream<char>;
-    using ostringstream = basic_ostringstream<char>;
-    using stringstream  = basic_stringstream<char>;
-
-    using filebuf  = basic_filebuf<char>;
-    using ifstream = basic_ifstream<char>;
-    using ofstream = basic_ofstream<char>;
-    using fstream  = basic_fstream<char>;
-
-    using wstreambuf = basic_streambuf<wchar_t>;
-    using wistream   = basic_istream<wchar_t>;
-    using wostream   = basic_ostream<wchar_t>;
-    using wiostream  = basic_iostream<wchar_t>;
-
-    using wstringbuf     = basic_stringbuf<wchar_t>;
-    using wistringstream = basic_istringstream<wchar_t>;
-    using wostringstream = basic_ostringstream<wchar_t>;
-    using wstringstream  = basic_stringstream<wchar_t>;
-
-    using wfilebuf  = basic_filebuf<wchar_t>;
-    using wifstream = basic_ifstream<wchar_t>;
-    using wofstream = basic_ofstream<wchar_t>;
-    using wfstream  = basic_fstream<wchar_t>;
-
-    template<class State>
-    class fpos;
-
-    // TODO: standard p. 1012, this is circular, it offers fix
-    /* using streampos  = fpos<char_traits<char>::state_type>; */
-    /* using wstreampos = fpos<char_traits<wchar_t>::state_type>; */
-    // Temporary workaround.
-    using streampos =  unsigned long long;
-    using wstreampos = unsigned long long;
-    // TODO: This should be in ios and not here?
-    using streamoff = long long;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/iostream.hpp
===================================================================
--- uspace/lib/cpp/include/impl/iostream.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_IOSTREAM
-#define LIBCPP_IOSTREAM
-
-#include <ios>
-#include <streambuf>
-#include <istream>
-#include <ostream>
-
-namespace std
-{
-    extern istream cin;
-    extern ostream cout;
-
-    // TODO: add the rest
-
-    namespace aux
-    {
-        extern ios_base::Init init;
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/istream.hpp
===================================================================
--- uspace/lib/cpp/include/impl/istream.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,965 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_ISTREAM
-#define LIBCPP_ISTREAM
-
-#include <ios>
-#include <iosfwd>
-#include <limits>
-#include <locale>
-#include <ostream>
-#include <utility>
-
-namespace std
-{
-
-    /**
-     * 27.7.2.1, class template basic_stream:
-     */
-
-    template<class Char, class Traits>
-    class basic_istream: virtual public basic_ios<Char, Traits>
-    {
-        public:
-            using traits_type = Traits;
-            using char_type   = Char;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.7.2.1.1, constructor/destructor:
-             */
-
-            explicit basic_istream(basic_streambuf<Char, Traits>* sb)
-                : gcount_{0}
-            {
-                basic_ios<Char, Traits>::init(sb);
-            }
-
-            virtual ~basic_istream()
-            { /* DUMMY BODY */ }
-
-            /**
-             * 27.7.2.1.3, prefix/suffix:
-             */
-
-            class sentry
-            {
-                public:
-                    explicit sentry(basic_istream<Char, Traits>& is, bool noskipws = false)
-                        : ok_{false}
-                    {
-                        if (!is.good())
-                            is.setstate(ios_base::failbit);
-                        else
-                        {
-                            if (is.tie())
-                                is.tie()->flush();
-
-                            if (!noskipws && ((is.flags() & ios_base::skipws) != 0))
-                            {
-                                const auto& ct = use_facet<ctype<Char>>(is.getloc());
-                                while (true)
-                                {
-                                    auto i = is.rdbuf()->sgetc();
-                                    if (Traits::eq_int_type(i, Traits::eof()))
-                                    {
-                                        is.setstate(ios_base::failbit | ios_base::eofbit);
-                                        break;
-                                    }
-
-                                    auto c = Traits::to_char_type(i);
-                                    if (!ct.is(ctype_base::space, c))
-                                        break;
-                                    else
-                                        is.rdbuf()->sbumpc();
-                                }
-                            }
-                        }
-
-                        if (is.good())
-                            ok_ = true;
-                    }
-
-                    ~sentry() = default;
-
-                    explicit operator bool() const
-                    {
-                        return ok_;
-                    }
-
-                    sentry(const sentry&) = delete;
-                    sentry& operator=(const sentry&) = delete;
-
-                private:
-                    using traits_type = Traits;
-                    bool ok_;
-            };
-
-            /**
-             * 27.7.2.2, formatted input:
-             */
-
-            basic_istream<Char, Traits>& operator>>(
-                basic_istream<Char, Traits>& (*pf)(basic_istream<Char, Traits>&)
-            )
-            {
-                return pf(*this);
-            }
-
-            basic_istream<Char, Traits>& operator>>(
-                basic_ios<Char, Traits>& (*pf)(basic_ios<Char, Traits>&)
-            )
-            {
-                pf(*this);
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(
-                ios_base& (*pf)(ios_base&)
-            )
-            {
-                pf(*this);
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(bool& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(short& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    long tmp{};
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, tmp);
-
-                    if (tmp < numeric_limits<short>::min())
-                    {
-                        err |= ios_base::failbit;
-                        x = numeric_limits<short>::min();
-                    }
-                    else if (numeric_limits<short>::max() < tmp)
-                    {
-                        err |= ios_base::failbit;
-                        x = numeric_limits<short>::max();
-                    }
-                    else
-                        x = static_cast<short>(tmp);
-
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(unsigned short& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(int& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    long tmp{};
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, tmp);
-
-                    if (tmp < numeric_limits<int>::min())
-                    {
-                        err |= ios_base::failbit;
-                        x = numeric_limits<int>::min();
-                    }
-                    else if (numeric_limits<int>::max() < tmp)
-                    {
-                        err |= ios_base::failbit;
-                        x = numeric_limits<int>::max();
-                    }
-                    else
-                        x = static_cast<int>(tmp);
-
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(unsigned int& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(long& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(unsigned long& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(long long& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(unsigned long long& x)
-            {
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    using num_get = num_get<Char, istreambuf_iterator<Char, Traits>>;
-                    auto err = ios_base::goodbit;
-
-                    auto loc = this->getloc();
-                    use_facet<num_get>(loc).get(*this, 0, *this, err, x);
-                    this->setstate(err);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& operator>>(float& x)
-            {
-                // TODO: implement
-            }
-
-            basic_istream<Char, Traits>& operator>>(double& x)
-            {
-                // TODO: implement
-            }
-
-            basic_istream<Char, Traits>& operator>>(long double& x)
-            {
-                // TODO: implement
-            }
-
-            basic_istream<Char, Traits>& operator>>(void*& p)
-            {
-                // TODO: implement
-            }
-
-            basic_istream<Char, Traits>& operator>>(basic_streambuf<Char, Traits>* sb)
-            {
-                if (!sb)
-                {
-                    this->setstate(ios_base::failbit);
-                    return *this;
-                }
-
-                gcount_ = 0;
-                sentry sen{*this, false};
-
-                if (sen)
-                {
-                    while (true)
-                    {
-                        auto ic = this->rdbuf()->sgetc();
-                        if (traits_type::eq_int_type(ic, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::eofbit);
-                            break;
-                        }
-
-                        auto res = sb->sputc(traits_type::to_char_type(ic));
-                        if (traits_type::eq_int_type(res, traits_type::eof()))
-                            break;
-
-                        ++gcount_;
-                        this->rdbuf()->sbumpc();
-                    }
-                }
-
-                return *this;
-            }
-
-            /**
-             * 27.7.2.3, unformatted input:
-             * TODO: Once we have exceptions, implement
-             *       27.7.2.3 paragraph 1.
-             */
-
-            streamsize gcount() const
-            {
-                return gcount_;
-            }
-
-            int_type get()
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (sen)
-                {
-                    auto res = this->rdbuf()->sbumpc();
-                    if (!traits_type::eq_int_type(res, traits_type::eof()))
-                    {
-                        gcount_ = 1;
-                        return res;
-                    }
-
-                    this->setstate(ios_base::failbit | ios_base::eofbit);
-                }
-
-                return traits_type::eof();
-            }
-
-            basic_istream<Char, Traits>& get(char_type& c)
-            {
-                auto res = get();
-                if (res != traits_type::eof())
-                    c = traits_type::to_char_type(res);
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& get(char_type* s, streamsize n, char_type delim)
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (sen && n > 0)
-                {
-                    while(gcount_ < n - 1)
-                    {
-                        auto c = this->rdbuf()->sbumpc();
-
-                        if (traits_type::eq_int_type(c, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::eofbit);
-                            break;
-                        }
-
-                        s[gcount_++] = traits_type::to_char_type(c);
-
-                        auto peek = traits_type::to_char_type(this->rdbuf()->sgetc());
-                        if (traits_type::eq(peek, delim))
-                            break;
-                    }
-
-                    if (gcount_ == 0)
-                        this->setstate(ios_base::failbit);
-                    s[n] = char_type{};
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& get(char_type* s, streamsize n)
-            {
-                return get(s, n, this->widen('\n'));
-            }
-
-            basic_istream<Char, Traits>& get(basic_streambuf<Char, Traits>& sb)
-            {
-                get(sb, this->widen('\n'));
-            }
-
-            basic_istream<Char, Traits>& get(basic_streambuf<Char, Traits>& sb, char_type delim)
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (sen)
-                {
-                    while (true)
-                    {
-                        auto i = this->rdbuf()->sgetc();
-                        if (traits_type::eq_int_type(i, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::eofbit);
-                            break;
-                        }
-
-                        auto c = traits_type::to_char_type(i);
-                        if (traits_type::eq(c, delim))
-                            break;
-
-                        auto insert_ret = sb.sputc(c);
-                        if (traits_type::eq_int_type(insert_ret, traits_type::eof()))
-                            break;
-
-                        this->rdbuf()->sbumpc();
-                        ++gcount_;
-                    }
-
-                    if (gcount_ == 0)
-                        this->setstate(ios_base::failbit);
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& getline(char_type* s, streamsize n)
-            {
-                return getline(s, n, this->widen('\n'));
-            }
-
-            basic_istream<Char, Traits>& getline(char_type* s, streamsize n, char_type delim)
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (sen)
-                {
-                    while (true)
-                    { // We have exactly specified order of checks, easier to do them in the body.
-                        auto c = this->rdbuf()->sbumpc();
-
-                        if (traits_type::eq_int_type(c, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::eofbit);
-                            break;
-                        }
-
-                        if (traits_type::eq_int_type(c, traits_type::to_int_type(delim)))
-                            break;
-
-                        if (n < 1 || gcount_ >= n - 1)
-                        {
-                            this->setstate(ios_base::failbit);
-                            break;
-                        }
-
-                        s[gcount_++] = traits_type::to_char_type(c);
-                    }
-
-                    if (gcount_ == 0)
-                        this->setstate(ios_base::failbit);
-                    if (n > 0)
-                        s[gcount_] = char_type{};
-                }
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& ignore(streamsize n = 1, int_type delim = traits_type::eof())
-            {
-                sentry sen{*this, true};
-
-                if (sen)
-                {
-                    streamsize i{};
-                    while (n == numeric_limits<streamsize>::max() || i < n)
-                    {
-                        auto c = this->rdbuf()->sbumpc();
-
-                        if (traits_type::eq_int_type(c, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::eofbit);
-                            break;
-                        }
-
-                        if (traits_type::eq_int_type(c, delim))
-                            break;
-                    }
-                }
-
-                return *this;
-            }
-
-            int_type peek()
-            {
-                sentry sen{*this, true};
-
-                if (!this->good())
-                    return traits_type::eof();
-                else
-                    return this->rdbuf()->sgetc();
-            }
-
-            basic_istream<Char, Traits>& read(char_type* s, streamsize n)
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (!this->good())
-                {
-                    this->setstate(ios_base::failbit);
-                    return *this;
-                }
-
-                while (gcount_ < n)
-                {
-                    auto c = this->rdbuf()->sbumpc();
-                    if (traits_type::eq_int_type(c, traits_type::eof()))
-                    {
-                        this->setstate(ios_base::failbit | ios_base::eofbit);
-                        break;
-                    }
-
-                    s[gcount_++] = traits_type::to_char_type(c);
-                }
-
-                return *this;
-            }
-
-            streamsize readsome(char_type* s, streamsize n)
-            {
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (!this->good())
-                {
-                    this->setstate(ios_base::failbit);
-                    return streamsize{};
-                }
-
-                auto avail = this->rdbuf()->in_avail();
-                if (avail == -1)
-                {
-                    this->setstate(ios_base::eofbit);
-                    return streamsize{};
-                } else if (avail > 0)
-                {
-                    auto count = (avail < n ? avail : n);
-                    while (gcount_ < count)
-                        s[gcount_++] = traits_type::to_char_type(this->rdbuf()->sbumpc());
-                }
-
-                return gcount_;
-            }
-
-            basic_istream<Char, Traits>& putback(char_type c)
-            {
-                this->clear(this->rdstate() & (~ios_base::eofbit));
-
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (!this->good())
-                {
-                    this->setstate(ios_base::failbit);
-                    return *this;
-                }
-
-                if (this->rdbuf())
-                {
-                    auto ret = this->rdbuf()->sputbackc(c);
-                    if (traits_type::eq_int_type(ret, traits_type::eof()))
-                        this->setstate(ios_base::badbit);
-                }
-                else
-                    this->setstate(ios_base::badbit);
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& unget()
-            {
-                this->clear(this->rdstate() & (~ios_base::eofbit));
-
-                gcount_ = 0;
-                sentry sen{*this, true};
-
-                if (!this->good())
-                {
-                    this->setstate(ios_base::failbit);
-                    return *this;
-                }
-
-                if (this->rdbuf())
-                {
-                    auto ret = this->rdbuf()->sungetc();
-                    if (traits_type::eq_int_type(ret, traits_type::eof()))
-                        this->setstate(ios_base::badbit);
-                }
-                else
-                    this->setstate(ios_base::badbit);
-
-                return *this;
-            }
-
-            int sync()
-            {
-                sentry s{*this, true};
-
-                if (this->rdbuf())
-                {
-                    auto ret = this->rdbuf()->pubsync();
-                    if (ret == -1)
-                    {
-                        this->setstate(ios_base::badbit);
-                        return -1;
-                    }
-                    else
-                        return 0;
-                }
-                else
-                    return -1;
-            }
-
-            pos_type tellg()
-            {
-                sentry s{*this, true};
-
-                if (this->fail())
-                    return pos_type(-1);
-                else
-                    return this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
-            }
-
-            basic_istream<Char, Traits>& seekg(pos_type pos)
-            {
-                this->clear(this->rdstate() & (~ios_base::eofbit));
-
-                sentry sen{*this, true};
-
-                if (!this->fail())
-                    this->rdbuf()->pubseekoff(pos, ios_base::in);
-                else
-                    this->setstate(ios_base::failbit);
-
-                return *this;
-            }
-
-            basic_istream<Char, Traits>& seekg(off_type off, ios_base::seekdir dir)
-            {
-                sentry sen{*this, true};
-
-                if (!this->fail())
-                    this->rdbuf()->pubseekoff(off, dir, ios_base::in);
-                else
-                    this->setstate(ios_base::failbit);
-
-                return *this;
-            }
-
-        protected:
-            streamsize gcount_;
-
-            basic_istream(const basic_istream&) = delete;
-
-            basic_istream(basic_istream&& rhs)
-            {
-                gcount_ = rhs.gcout_;
-
-                basic_ios<Char, Traits>::move(rhs);
-
-                rhs.gcount_ = 0;
-            }
-
-            /**
-             * 27.7.2.1.2, assign/swap:
-             */
-
-            basic_istream& operator=(const basic_istream& rhs) = delete;
-
-            basic_istream& operator=(basic_istream&& rhs)
-            {
-                swap(rhs);
-
-                return *this;
-            }
-
-            void swap(basic_istream& rhs)
-            {
-                basic_ios<Char, Traits>::swap(rhs);
-                swap(gcount_, rhs.gcount_);
-            }
-    };
-
-    /**
-     * 27.7.2.2.3, character extraction templates:
-     */
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            Char& c)
-    {
-        typename basic_istream<Char, Traits>::sentry sen{is, false};
-
-        if (sen)
-        {
-            auto ic = is.rdbuf()->sgetc();
-            if (Traits::eq_int_type(ic, Traits::eof()))
-            {
-                is.setstate(ios_base::failbit | ios_base::eofbit);
-                return is;
-            }
-
-            c = Traits::to_char_type(is.rdbuf()->sbumpc());
-        }
-
-        return is;
-    }
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            unsigned char& c)
-    {
-        return is >> static_cast<char&>(c);
-    }
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            signed char& c)
-    {
-        return is >> static_cast<char&>(c);
-    }
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            Char* str)
-    {
-        typename basic_istream<Char, Traits>::sentry sen{is, false};
-
-        if (sen)
-        {
-            const auto& ct = use_facet<ctype<Char>>(is.getloc());
-
-            size_t n{};
-            if (is.width() > 0)
-                n = static_cast<size_t>(is.width());
-            else
-                n = (numeric_limits<size_t>::max() / sizeof(Char)) - sizeof(Char);
-
-            size_t i{};
-            for (; i < n - 1; ++i)
-            {
-                auto ic = is.rdbuf()->sgetc();
-                if (Traits::eq_int_type(ic, Traits::eof()))
-                    break;
-
-                auto c = Traits::to_char_type(ic);
-                if (ct.is(ctype_base::space, c))
-                    break;
-
-                str[i] = c;
-                is.rdbuf()->sbumpc();
-            }
-
-            str[i] = Char{};
-            if (i == 0)
-                is.setstate(ios_base::failbit);
-        }
-
-        return is;
-    }
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            unsigned char* str)
-    {
-        return is >> static_cast<char*>(str);
-    }
-
-    template<class Char, class Traits>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
-                                            signed char* str)
-    {
-        return is >> static_cast<char*>(str);
-    }
-
-    /**
-     * 27.7.2.4, standard basic_istream manipulators:
-     */
-
-    template<class Char, class Traits = char_traits<Char>>
-    basic_istream<Char, Traits>& ws(basic_istream<Char, Traits>& is)
-    {
-        using sentry = typename basic_istream<Char, Traits>::sentry;
-        sentry sen{is, true};
-
-        if (sen)
-        {
-            const auto& ct = use_facet<ctype<Char>>(is.getloc());
-            while (true)
-            {
-                auto i = is.rdbuf()->sgetc();
-                if (Traits::eq_int_type(i, Traits::eof()))
-                {
-                    is.setstate(ios_base::eofbit);
-                    break;
-                }
-
-                auto c = Traits::to_char_type(i);
-                if (!ct.is(c, ct.space))
-                    break;
-                else
-                    is.rdbuf()->sbumpc();
-            }
-        }
-
-        return is;
-    }
-
-    using istream  = basic_istream<char>;
-    using wistream = basic_istream<wchar_t>;
-
-    /**
-     * 27.7.2.5, class template basic_iostream:
-     */
-
-    template<class Char, class Traits>
-    class basic_iostream
-        : public basic_istream<Char, Traits>,
-          public basic_ostream<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            explicit basic_iostream(basic_streambuf<char_type, traits_type>* sb)
-                : basic_istream<char_type, traits_type>(sb),
-                  basic_ostream<char_type, traits_type>(sb)
-            { /* DUMMY BODY */ }
-
-            virtual ~basic_iostream()
-            { /* DUMMY BODY */ }
-
-        protected:
-            basic_iostream(const basic_iostream&) = delete;
-            basic_iostream& operator=(const basic_iostream&) = delete;
-
-            basic_iostream(basic_iostream&& other)
-                : basic_istream<char_type, traits_type>(move(other))
-            { /* DUMMY BODY */ }
-
-            basic_iostream& operator=(basic_iostream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_iostream& other)
-            {
-                basic_istream<char_type, traits_type>::swap(other);
-            }
-    };
-
-    using iostream  = basic_iostream<char>;
-    using wiostream = basic_iostream<wchar_t>;
-
-    /**
-     * 27.7.2.6, rvalue stream extraction:
-     */
-
-    template<class Char, class Traits, class T>
-    basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>&& is, T& x)
-    {
-        is >> x;
-
-        return is;
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/iterator.hpp
===================================================================
--- uspace/lib/cpp/include/impl/iterator.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1194 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_ITERATOR
-#define LIBCPP_ITERATOR
-
-#include <cstdlib>
-#include <initializer_list>
-#include <__bits/memory/addressof.hpp>
-#include <iosfwd>
-#include <type_traits>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 24.4.3, standard iterator tags:
-     */
-
-    struct input_iterator_tag
-    { /* DUMMY BODY */ };
-
-    struct output_iterator_tag
-    { /* DUMMY BODY */ };
-
-    struct forward_iterator_tag: input_iterator_tag
-    { /* DUMMY BODY */ };
-
-    struct bidirectional_iterator_tag: forward_iterator_tag
-    { /* DUMMY BODY */ };
-
-    struct random_access_iterator_tag: bidirectional_iterator_tag
-    { /* DUMMY BODY */ };
-
-    /**
-     * 24.4.1, iterator traits:
-     */
-
-    template<class Iterator>
-    struct iterator_traits
-    {
-        using difference_type   = typename Iterator::difference_type;
-        using value_type        = typename Iterator::value_type;
-        using iterator_category = typename Iterator::iterator_category;
-        using reference         = typename Iterator::reference;
-        using pointer           = typename Iterator::pointer;
-    };
-
-    template<class T>
-    struct iterator_traits<T*>
-    {
-        using difference_type   = ptrdiff_t;
-        using value_type        = T;
-        using iterator_category = random_access_iterator_tag;
-        using reference         = T&;
-        using pointer           = T*;
-    };
-
-    template<class T>
-    struct iterator_traits<const T*>
-    {
-        using difference_type   = ptrdiff_t;
-        using value_type        = T;
-        using iterator_category = random_access_iterator_tag;
-        using reference         = const T&;
-        using pointer           = const T*;
-    };
-
-    /**
-     * 24.4.2, basic iterator:
-     */
-
-    template<
-        class Category, class T, class Distance = ptrdiff_t,
-        class Pointer = T*, class Reference = T&
-    >
-    struct iterator
-    {
-        using difference_type   = Distance;
-        using value_type        = T;
-        using iterator_category = Category;
-        using reference         = Reference;
-        using pointer           = Pointer;
-    };
-
-    /**
-     * 24.4.4, iterator operations
-     */
-
-    template<class InputIterator, class Distance>
-    void advance(InputIterator& it, Distance n)
-    {
-        for (Distance i = Distance{}; i < n; ++i)
-            ++it;
-    }
-
-    template<class InputIterator>
-    typename iterator_traits<InputIterator>::difference_type
-    distance(InputIterator first, InputIterator last)
-    {
-        using cat_t = typename iterator_traits<InputIterator>::iterator_category;
-        using diff_t = typename iterator_traits<InputIterator>::difference_type;
-
-        if constexpr (is_same_v<cat_t, random_access_iterator_tag>)
-            return last - first;
-        else
-        {
-            diff_t diff{};
-            while (first != last)
-            {
-                ++diff;
-                ++first;
-            }
-
-            return diff;
-        }
-    }
-
-    template<class ForwardIterator>
-    ForwardIterator
-    next(ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1)
-    {
-        advance(it, n);
-
-        return it;
-    }
-
-    template<class BidirectionalIterator>
-    BidirectionalIterator
-    prev(BidirectionalIterator it,
-         typename iterator_traits<BidirectionalIterator>::difference_type n = 1)
-    {
-        advance(it, -n);
-
-        return it;
-    }
-
-    /**
-     * 24.5.1, reverse iterator:
-     */
-
-    template<class Iterator>
-    class reverse_iterator
-        : public iterator<
-            typename iterator_traits<Iterator>::iterator_category,
-            typename iterator_traits<Iterator>::value_type,
-            typename iterator_traits<Iterator>::difference_type,
-            typename iterator_traits<Iterator>::pointer,
-            typename iterator_traits<Iterator>::reference
-          >
-    {
-        public:
-            using iterator_type   = Iterator;
-            using difference_type = typename iterator_traits<Iterator>::difference_type;
-            using reference       = typename iterator_traits<Iterator>::reference;
-            using pointer         = typename iterator_traits<Iterator>::pointer;
-
-            reverse_iterator()
-                : current_{}
-            { /* DUMMY BODY */ }
-
-            explicit reverse_iterator(Iterator it)
-                : current_{it}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            reverse_iterator(const reverse_iterator<U>& other)
-                : current_{other.current_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            reverse_iterator& operator=(const reverse_iterator<U>& other)
-            {
-                current_ = other.base();
-
-                return *this;
-            }
-
-            Iterator base() const
-            {
-                return current_;
-            }
-
-            reference operator*() const
-            {
-                auto tmp = current_;
-
-                return *(--tmp);
-            }
-
-            pointer operator->() const
-            {
-                return addressof(operator*());
-            }
-
-            reverse_iterator& operator++()
-            {
-                --current_;
-
-                return *this;
-            }
-
-            reverse_iterator operator++(int)
-            {
-                auto tmp = *this;
-                --current_;
-
-                return tmp;
-            }
-
-            reverse_iterator& operator--()
-            {
-                ++current_;
-
-                return *this;
-            }
-
-            reverse_iterator operator--(int)
-            {
-                auto tmp = *this;
-                ++current_;
-
-                return tmp;
-            }
-
-            reverse_iterator operator+(difference_type n) const
-            {
-                return reverse_iterator{current_ - n};
-            }
-
-            reverse_iterator& operator+=(difference_type n)
-            {
-                current_ -= n;
-
-                return *this;
-            }
-
-            reverse_iterator operator-(difference_type n) const
-            {
-                return reverse_iterator{current_ + n};
-            }
-
-            reverse_iterator& operator-=(difference_type n)
-            {
-                current_ += n;
-
-                return *this;
-            }
-
-            auto operator[](difference_type n) const
-            {
-                return current_[-n - 1];
-            }
-
-        protected:
-            Iterator current_;
-    };
-
-    template<class Iterator1, class Iterator2>
-    bool operator==(const reverse_iterator<Iterator1>& lhs,
-                    const reverse_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() == rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator<(const reverse_iterator<Iterator1>& lhs,
-                   const reverse_iterator<Iterator2>& rhs)
-    {
-        // Remember: they are reversed!
-        return lhs.base() > rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator!=(const reverse_iterator<Iterator1>& lhs,
-                    const reverse_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() != rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator>(const reverse_iterator<Iterator1>& lhs,
-                   const reverse_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() < rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator>=(const reverse_iterator<Iterator1>& lhs,
-                    const reverse_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() <= rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator<=(const reverse_iterator<Iterator1>& lhs,
-                    const reverse_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() >= rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    auto operator-(const reverse_iterator<Iterator1>& lhs,
-                   const reverse_iterator<Iterator2>& rhs)
-        -> decltype(rhs.base() - lhs.base())
-    {
-        return rhs.base() - lhs.base();
-    }
-
-    template<class Iterator>
-    reverse_iterator<Iterator> operator+(
-        typename reverse_iterator<Iterator>::difference_type n,
-        const reverse_iterator<Iterator>& it
-    )
-    {
-        return reverse_iterator<Iterator>{it.base() - n};
-    }
-
-    template<class Iterator>
-    reverse_iterator<Iterator> make_reverse_iterator(Iterator it)
-    {
-        return reverse_iterator<Iterator>(it);
-    }
-
-    /**
-     * 24.5.2, insert iterators:
-     */
-
-    /**
-     * 24.5.2.1, back insert iterator:
-     */
-
-    template<class Container>
-    class back_insert_iterator
-        : public iterator<output_iterator_tag, void, void, void, void>
-    {
-        public:
-            using container_type = Container;
-
-            explicit back_insert_iterator(Container& cont)
-                : container{std::addressof(cont)}
-            { /* DUMMY BODY */ }
-
-            back_insert_iterator& operator=(const typename container_type::value_type& value)
-            {
-                container->push_back(value);
-                return *this;
-            }
-
-            back_insert_iterator& operator=(typename container_type::value_type&& value)
-            {
-                container->push_back(move(value));
-                return *this;
-            }
-
-            back_insert_iterator& operator*()
-            {
-                return *this;
-            }
-
-            back_insert_iterator& operator++()
-            {
-                return *this;
-            }
-
-            back_insert_iterator operator++(int)
-            {
-                return *this;
-            }
-
-        protected:
-            Container* container;
-    };
-
-    template<class Container>
-    back_insert_iterator<Container> back_inserter(Container& cont)
-    {
-        return back_insert_iterator<Container>(cont);
-    }
-
-    /**
-     * 24.5.2.3, front insert iterator:
-     */
-
-    template<class Container>
-    class front_insert_iterator
-        : public iterator<output_iterator_tag, void, void, void, void>
-    {
-        public:
-            using container_type = Container;
-
-            explicit front_insert_iterator(Container& cont)
-                : container{std::addressof(cont)}
-            { /* DUMMY BODY */ }
-
-            front_insert_iterator& operator=(const typename container_type::value_type& value)
-            {
-                container->push_front(value);
-                return *this;
-            }
-
-            front_insert_iterator& operator=(typename container_type::value_type&& value)
-            {
-                container->push_front(move(value));
-                return *this;
-            }
-
-            front_insert_iterator& operator*()
-            {
-                return *this;
-            }
-
-            front_insert_iterator& operator++()
-            {
-                return *this;
-            }
-
-            front_insert_iterator operator++(int)
-            {
-                return *this;
-            }
-
-        protected:
-            Container* container;
-    };
-
-    template<class Container>
-    front_insert_iterator<Container> front_inserter(Container& cont)
-    {
-        return front_insert_iterator<Container>(cont);
-    }
-
-    /**
-     * 24.5.2.5, front insert iterator:
-     */
-
-    template<class Container>
-    class insert_iterator
-        : public iterator<output_iterator_tag, void, void, void, void>
-    {
-        public:
-            using container_type = Container;
-
-            explicit insert_iterator(Container& cont, typename Container::iterator i)
-                : container{std::addressof(cont)}, iter{i}
-            { /* DUMMY BODY */ }
-
-            insert_iterator& operator=(const typename container_type::value_type& value)
-            {
-                iter = container.insert(iter, value);
-                ++iter;
-
-                return *this;
-            }
-
-            insert_iterator& operator=(typename container_type::value_type&& value)
-            {
-                iter = container.insert(iter, move(value));
-                ++iter;
-
-                return *this;
-            }
-
-            insert_iterator& operator*()
-            {
-                return *this;
-            }
-
-            insert_iterator& operator++()
-            {
-                return *this;
-            }
-
-            insert_iterator operator++(int)
-            {
-                return *this;
-            }
-
-        protected:
-            Container* container;
-            typename Container::iterator iter;
-    };
-
-    template<class Container>
-    insert_iterator<Container> inserter(Container& cont, typename Container::iterator i)
-    {
-        return insert_iterator<Container>(cont, i);
-    }
-
-    /**
-     * 24.5.3.1, move iterator:
-     */
-
-    namespace aux
-    {
-        template<class Iterator, class = void>
-        struct move_it_get_reference
-        {
-            using type = typename iterator_traits<Iterator>::reference;
-        };
-
-        template<class Iterator>
-        struct move_it_get_reference<
-            Iterator, enable_if_t<
-                is_reference<typename iterator_traits<Iterator>::reference>::value,
-                void
-            >
-        >
-        {
-            using type = remove_reference_t<typename iterator_traits<Iterator>::reference>&&;
-        };
-    }
-
-    template<class Iterator>
-    class move_iterator
-    {
-        public:
-            using iterator_type     = Iterator;
-            using pointer           = iterator_type;
-            using difference_type   = typename iterator_traits<iterator_type>::difference_type;
-            using value_type        = typename iterator_traits<iterator_type>::value_type;
-            using iterator_category = typename iterator_traits<iterator_type>::iterator_category;
-            using reference         = typename aux::move_it_get_reference<iterator_type>::type;
-
-            move_iterator()
-                : current_{}
-            { /* DUMMY BODY */ }
-
-            explicit move_iterator(iterator_type i)
-                : current_{i}
-            { /* DUMMY BODY */ }
-
-            // TODO: both require is_convertible
-            template<class U>
-            move_iterator(const move_iterator<U>& other)
-                : current_{other.current_}
-            { /* DUMMY BODY */ }
-
-            template<class U>
-            move_iterator& operator=(const move_iterator<U>& other)
-            {
-                current_ = other.current_;
-
-                return *this;
-            }
-
-            iterator_type base() const
-            {
-                return current_;
-            }
-
-            reference operator*() const
-            {
-                return static_cast<reference>(*current_);
-            }
-
-            pointer operator->() const
-            {
-                return current_;
-            }
-
-            move_iterator& operator++()
-            {
-                ++current_;
-
-                return *this;
-            }
-
-            move_iterator operator++(int)
-            {
-                auto tmp = *this;
-                ++current_;
-
-                return tmp;
-            }
-
-            move_iterator& operator--()
-            {
-                --current_;
-
-                return *this;
-            }
-
-            move_iterator operator--(int)
-            {
-                auto tmp = *this;
-                --current_;
-
-                return tmp;
-            }
-
-            move_iterator operator+(difference_type n) const
-            {
-                return move_iterator(current_ + n);
-            }
-
-            move_iterator& operator+=(difference_type n)
-            {
-                current_ += n;
-
-                return *this;
-            }
-
-            move_iterator operator-(difference_type n) const
-            {
-                return move_iterator(current_ - n);
-            }
-
-            move_iterator& operator-=(difference_type n)
-            {
-                current_ -= n;
-
-                return *this;
-            }
-
-            auto operator[](difference_type idx) const
-            {
-                return move(current_[idx]);
-            }
-
-        private:
-            iterator_type current_;
-    };
-
-    template<class Iterator1, class Iterator2>
-    bool operator==(const move_iterator<Iterator1>& lhs,
-                    const move_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() == rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator!=(const move_iterator<Iterator1>& lhs,
-                    const move_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() != rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator<(const move_iterator<Iterator1>& lhs,
-                   const move_iterator<Iterator2>& rhs)
-    {
-        return lhs.base() < rhs.base();
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator<=(const move_iterator<Iterator1>& lhs,
-                    const move_iterator<Iterator2>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator>(const move_iterator<Iterator1>& lhs,
-                   const move_iterator<Iterator2>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Iterator1, class Iterator2>
-    bool operator>=(const move_iterator<Iterator1>& lhs,
-                    const move_iterator<Iterator2>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class Iterator1, class Iterator2>
-    auto operator-(const move_iterator<Iterator1>& lhs,
-                   const move_iterator<Iterator2>& rhs)
-        -> decltype(rhs.base() - lhs.base())
-    {
-        return lhs.base() - rhs.base();
-    }
-
-    template<class Iterator>
-    move_iterator<Iterator> operator+(
-        typename move_iterator<Iterator>::difference_type n,
-        const move_iterator<Iterator>& it
-    )
-    {
-        return it + n;
-    }
-
-    template<class Iterator>
-    move_iterator<Iterator> make_move_iterator(Iterator it)
-    {
-        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:
-                    proxy_type(int_type c, streambuf_type* sbuf)
-                        : char_{c}, sbuf_{sbuf}
-                    { /* DUMMY BODY */ }
-
-                    char_type operator*()
-                    {
-                        return traits_type::to_char_type(char_);
-                    }
-
-                private:
-                    int_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 */ // TODO: Should be 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();
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/limits.hpp
===================================================================
--- uspace/lib/cpp/include/impl/limits.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,627 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_LIMITS
-#define LIBCPP_LIMITS
-
-#include <cstdint>
-#include <climits>
-
-namespace std
-{
-
-    /**
-     * 18.3.2.5, type float_round_style:
-     */
-
-    enum float_round_style
-    {
-        round_indeterminate       = -1,
-        round_toward_zero         =  0,
-        round_to_nearest          =  1,
-        round_toward_infinity     =  2,
-        round_toward_neg_infinity =  3
-    };
-
-    /**
-     * 18.3.2.6, type float_denorm_style:
-     */
-
-    enum float_denorm_style
-    {
-        denorm_indeterminate = -1,
-        denorm_absent        =  0,
-        denorm_present       =  1
-    };
-
-    /**
-     * 18.3.2.3, class template numeric_limits:
-     */
-
-    namespace aux
-    {
-        template<class T>
-        class numeric_limits
-        {
-            public:
-                static constexpr bool is_specialized = false;
-
-                static constexpr T min() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T max() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T lowest() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr int digits       = 0;
-                static constexpr int digits10     = 0;
-                static constexpr int max_digits10 = 0;
-
-                static constexpr bool is_signed  = false;
-                static constexpr bool is_integer = false;
-                static constexpr bool is_exact   = false;
-
-                static constexpr int radix = 0;
-
-                static constexpr T epsilon() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T round_error() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr int min_exponent   = 0;
-                static constexpr int min_exponent10 = 0;
-                static constexpr int max_exponent   = 0;
-                static constexpr int max_exponent10 = 0;
-
-                static constexpr bool has_infinity      = false;
-                static constexpr bool has_quiet_NaN     = false;
-                static constexpr bool has_signaling_NaN = false;
-
-                static constexpr float_denorm_style has_denorm = denorm_absent;
-                static constexpr bool has_denorm_loss          = false;
-
-                static constexpr T infinity() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T quiet_NaN() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T signaling_NaN() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr T denorm_min() noexcept
-                {
-                    return T{};
-                }
-
-                static constexpr bool is_iec559  = false;
-                static constexpr bool is_bounded = false;
-                static constexpr bool is_modulo  = false;
-
-                static constexpr bool traps           = false;
-                static constexpr bool tinyness_before = false;
-
-                static constexpr float_round_style round_style = round_toward_zero;
-        };
-    }
-
-    template<class T>
-    class numeric_limits: public aux::numeric_limits<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    class numeric_limits<const T>: public numeric_limits<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    class numeric_limits<volatile T>: public numeric_limits<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    class numeric_limits<const volatile T>: public numeric_limits<T>
-    { /* DUMMY BODY */ };
-
-    /**
-     * 18.3.2.3, class template numeric_limits:
-     */
-
-    template<>
-    class numeric_limits<float>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr float min() noexcept
-            {
-                return 1.17549435e-38f;
-            }
-
-            static constexpr float max() noexcept
-            {
-                return 3.40282347e+38f;
-            }
-
-            static constexpr float lowest() noexcept
-            {
-                return -3.40282347e+38f;
-            }
-
-            static constexpr int digits       = 24;
-            static constexpr int digits10     =  6;
-            static constexpr int max_digits10 =  9;
-
-            static constexpr bool is_signed  = true;
-            static constexpr bool is_integer = false;
-            static constexpr bool is_exact   = false;
-
-            static constexpr int radix = 2;
-
-            static constexpr float epsilon() noexcept
-            {
-                return 1.19209290e-07f;
-            }
-
-            static constexpr float round_error() noexcept
-            {
-                return 0.5f;
-            }
-
-            static constexpr int min_exponent   = -127;
-            static constexpr int min_exponent10 =  -37;
-            static constexpr int max_exponent   =  128;
-            static constexpr int max_exponent10 =   38;
-
-            static constexpr bool has_infinity      = true;
-            static constexpr bool has_quiet_NaN     = true;
-            static constexpr bool has_signaling_NaN = true;
-
-            static constexpr float_denorm_style has_denorm = denorm_absent;
-            static constexpr bool has_denorm_loss          = false;
-
-            static constexpr float infinity() noexcept
-            {
-                // TODO: implement
-                return 0.f;
-            }
-
-            static constexpr float quiet_NaN() noexcept
-            {
-                // TODO: implement
-                return 0.f;
-            }
-
-            static constexpr float signaling_NaN() noexcept
-            {
-                // TODO: implement
-                return 0.f;
-            }
-
-            static constexpr float denorm_min() noexcept
-            {
-                return min();
-            }
-
-            static constexpr bool is_iec559  = true;
-            static constexpr bool is_bounded = true;
-            static constexpr bool is_modulo  = false;
-
-            static constexpr bool traps           = true;
-            static constexpr bool tinyness_before = true;
-
-            static constexpr float_round_style round_style = round_to_nearest;
-    };
-
-    template<>
-    class numeric_limits<bool>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr bool min() noexcept
-            {
-                return false;
-            }
-
-            static constexpr bool max() noexcept
-            {
-                return true;
-            }
-
-            static constexpr bool lowest() noexcept
-            {
-                return false;
-            }
-
-            static constexpr int digits       = 1;
-            static constexpr int digits10     = 0;
-            static constexpr int max_digits10 = 0;
-
-            static constexpr bool is_signed  = false;
-            static constexpr bool is_integer = true;
-            static constexpr bool is_exact   = true;
-
-            static constexpr int radix = 2;
-
-            static constexpr bool epsilon() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr bool round_error() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr int min_exponent   = 0;
-            static constexpr int min_exponent10 = 0;
-            static constexpr int max_exponent   = 0;
-            static constexpr int max_exponent10 = 0;
-
-            static constexpr bool has_infinity      = false;
-            static constexpr bool has_quiet_NaN     = false;
-            static constexpr bool has_signaling_NaN = false;
-
-            static constexpr float_denorm_style has_denorm = denorm_absent;
-            static constexpr bool has_denorm_loss          = false;
-
-            static constexpr bool infinity() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr bool quiet_NaN() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr bool signaling_NaN() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr bool denorm_min() noexcept
-            {
-                return 0;
-            }
-
-            static constexpr bool is_iec559  = false;
-            static constexpr bool is_bounded = true;
-            static constexpr bool is_modulo  = false;
-
-            static constexpr bool traps           = false;
-            static constexpr bool tinyness_before = false;
-
-            static constexpr float_round_style round_style = round_toward_zero;
-    };
-
-    /**
-     * Note: Because of the limited state of limit.h, we define only
-     *       the most basic properties of the most basic types (that are likely
-     *       to be used in a program that is being ported to HelenOS).
-     */
-
-    template<>
-    class numeric_limits<char>: public aux::numeric_limits<char>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(char) * 8;
-
-            static constexpr char max()
-            {
-                return CHAR_MAX;
-            }
-
-            static constexpr char min()
-            {
-                return CHAR_MIN;
-            }
-
-            static constexpr char lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<signed char>: public aux::numeric_limits<signed char>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(signed char) * 8 - 1;
-
-            static constexpr signed char max()
-            {
-                return SCHAR_MAX;
-            }
-
-            static constexpr signed char min()
-            {
-                return SCHAR_MIN;
-            }
-
-            static constexpr signed char lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<short>: public aux::numeric_limits<short>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(short) * 8 - 1;
-
-            static constexpr short max()
-            {
-                return SHRT_MAX;
-            }
-
-            static constexpr short min()
-            {
-                return SHRT_MIN;
-            }
-
-            static constexpr short lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<int>: public aux::numeric_limits<int>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(int) * 8 - 1;
-
-            static constexpr int max()
-            {
-                return INT_MAX;
-            }
-
-            static constexpr int min()
-            {
-                return INT_MIN;
-            }
-
-            static constexpr int lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<long>: public aux::numeric_limits<long>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(long) * 8 - 1;
-
-            static constexpr long max()
-            {
-                return LONG_MAX;
-            }
-
-            static constexpr long min()
-            {
-                return LONG_MIN;
-            }
-
-            static constexpr long lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<long long>: public aux::numeric_limits<long long>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(long long) * 8 - 1;
-
-            static constexpr long long max()
-            {
-                return LLONG_MAX;
-            }
-
-            static constexpr long long min()
-            {
-                return LLONG_MIN;
-            }
-
-            static constexpr long long lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<unsigned char>: public aux::numeric_limits<unsigned char>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(unsigned char) * 8;
-
-            static constexpr unsigned char max()
-            {
-                return SCHAR_MAX;
-            }
-
-            static constexpr unsigned char min()
-            {
-                return SCHAR_MIN;
-            }
-
-            static constexpr unsigned char lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<unsigned short>: public aux::numeric_limits<unsigned short>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(unsigned short) * 8;
-
-            static constexpr unsigned short max()
-            {
-                return USHRT_MAX;
-            }
-
-            static constexpr unsigned short min()
-            {
-                return USHRT_MIN;
-            }
-
-            static constexpr unsigned short lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<unsigned int>: public aux::numeric_limits<unsigned int>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(unsigned int) * 8;
-
-            static constexpr unsigned int max()
-            {
-                return UINT_MAX;
-            }
-
-            static constexpr unsigned int min()
-            {
-                return UINT_MIN;
-            }
-
-            static constexpr unsigned int lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<unsigned long>: public aux::numeric_limits<unsigned long>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(unsigned long) * 8;
-
-            static constexpr unsigned long max()
-            {
-                return ULONG_MAX;
-            }
-
-            static constexpr unsigned long min()
-            {
-                return ULONG_MIN;
-            }
-
-            static constexpr unsigned long lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<unsigned long long>: public aux::numeric_limits<unsigned long long>
-    {
-        public:
-            static constexpr bool is_specialized = true;
-
-            static constexpr int digits = sizeof(unsigned long long) * 8;
-
-            static constexpr unsigned long long max()
-            {
-                return ULLONG_MAX;
-            }
-
-            static constexpr unsigned long long min()
-            {
-                return ULLONG_MIN;
-            }
-
-            static constexpr unsigned long long lowest()
-            {
-                return min();
-            }
-    };
-
-    template<>
-    class numeric_limits<double>: public aux::numeric_limits<double>
-    {
-        public:
-        // TODO: implement
-            static constexpr int digits = sizeof(short) * 8 - 1;
-    };
-
-    template<>
-    class numeric_limits<long double>: public aux::numeric_limits<long double>
-    {
-        public:
-        // TODO: implement
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/list.hpp
===================================================================
--- uspace/lib/cpp/include/impl/list.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1195 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_LIST
-#define LIBCPP_LIST
-
-#include <__bits/insert_iterator.hpp>
-#include <__bits/list_node.hpp>
-#include <cstdlib>
-#include <iterator>
-#include <memory>
-#include <utility>
-
-namespace std
-{
-    template<class T, class Allocator = allocator<T>>
-    class list;
-
-    namespace aux
-    {
-        template<class T>
-        class list_iterator;
-
-        template<class T>
-        class list_const_iterator
-        {
-            public:
-                using value_type      = typename list<T>::value_type;
-                using reference       = typename list<T>::const_reference;
-                using pointer         = typename list<T>::const_pointer;
-                using difference_type = typename list<T>::difference_type;
-                using size_type       = typename list<T>::size_type;
-
-                using iterator_category = bidirectional_iterator_tag;
-
-                list_const_iterator(list_node<value_type>* node = nullptr,
-                                    list_node<value_type>* head = nullptr,
-                                    bool end = true)
-                    : current_{node}, head_{head}, end_{end}
-                { /* DUMMY BODY */ }
-
-                list_const_iterator(const list_const_iterator&) = default;
-                list_const_iterator& operator=(const list_const_iterator&) = default;
-                list_const_iterator(list_const_iterator&&) = default;
-                list_const_iterator& operator=(list_const_iterator&&) = default;
-
-                list_const_iterator(const list_iterator<T>& other)
-                    : current_{other.node()}, head_{other.head()}, end_{other.end()}
-                { /* DUMMY BODY */ }
-
-                reference operator*() const
-                {
-                    return current_->value;
-                }
-
-                list_const_iterator& operator++()
-                {
-                    if (!end_ && current_)
-                    {
-                        if (current_->next == head_)
-                            end_ = true;
-                        else
-                            current_ = current_->next;
-                    }
-
-                    return *this;
-                }
-
-                list_const_iterator operator++(int)
-                {
-                    auto old = *this;
-                    ++(*this);
-
-                    return old;
-                }
-
-                list_const_iterator& operator--()
-                {
-                    if (end_)
-                        end_ = false;
-                    else if (current_)
-                    {
-                        if (current_ != head_)
-                            current_ = current_->prev;
-                        else
-                            end_ = true;
-                    }
-
-                    return *this;
-                }
-
-                list_const_iterator operator--(int)
-                {
-                    auto old = *this;
-                    --(*this);
-
-                    return old;
-                }
-
-                list_node<value_type>* node()
-                {
-                    return const_cast<list_node<value_type>*>(current_);
-                }
-
-                const list_node<value_type>* node() const
-                {
-                    return current_;
-                }
-
-                list_node<value_type>* head()
-                {
-                    return const_cast<list_node<value_type>*>(head_);
-                }
-
-                const list_node<value_type>* head() const
-                {
-                    return head_;
-                }
-
-                list_const_iterator operator-(difference_type n) const
-                {
-                    /**
-                     * Note: This operator is for internal purposes only,
-                     *       so we do not provide inverse operator or shortcut
-                     *       -= operator.
-                     */
-                    auto tmp = current_;
-
-                    for (difference_type i = 0; i < n; ++i)
-                        tmp = tmp->prev;
-
-                    return list_const_iterator{tmp};
-                }
-
-                bool end() const
-                {
-                    return end_;
-                }
-
-            private:
-                const list_node<value_type>* current_;
-                const list_node<value_type>* head_;
-                bool end_;
-        };
-
-        template<class T>
-        bool operator==(const list_const_iterator<T>& lhs, const list_const_iterator<T>& rhs)
-        {
-            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-        }
-
-        template<class T>
-        bool operator!=(const list_const_iterator<T>& lhs, const list_const_iterator<T>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-
-        template<class T>
-        class list_iterator
-        {
-            public:
-                using value_type      = typename list<T>::value_type;
-                using reference       = typename list<T>::reference;
-                using pointer         = typename list<T>::pointer;
-                using difference_type = typename list<T>::difference_type;
-                using size_type       = typename list<T>::size_type;
-
-                using iterator_category = bidirectional_iterator_tag;
-
-                list_iterator(list_node<value_type>* node = nullptr,
-                              list_node<value_type>* head = nullptr,
-                              bool end = true)
-                    : current_{node}, head_{head}, end_{end}
-                { /* DUMMY BODY */ }
-
-                list_iterator(const list_iterator&) = default;
-                list_iterator& operator=(const list_iterator&) = default;
-                list_iterator(list_iterator&&) = default;
-                list_iterator& operator=(list_iterator&&) = default;
-
-                reference operator*() const
-                {
-                    return current_->value;
-                }
-
-                list_iterator& operator++()
-                {
-                    if (!end_ && current_)
-                    {
-                        if (current_->next == head_)
-                            end_ = true;
-                        else
-                            current_ = current_->next;
-                    }
-
-                    return *this;
-                }
-
-                list_iterator operator++(int)
-                {
-                    auto old = *this;
-                    ++(*this);
-
-                    return old;
-                }
-
-                list_iterator& operator--()
-                {
-                    if (end_)
-                        end_ = false;
-                    else if (current_)
-                    {
-                        if (current_ != head_)
-                            current_ = current_->prev;
-                        else
-                            end_ = true;
-                    }
-
-                    return *this;
-                }
-
-                list_iterator operator--(int)
-                {
-                    auto old = *this;
-                    --(*this);
-
-                    return old;
-                }
-
-                list_node<value_type>* node()
-                {
-                    return current_;
-                }
-
-                const list_node<value_type>* node() const
-                {
-                    return current_;
-                }
-
-                list_node<value_type>* head()
-                {
-                    return head_;
-                }
-
-                const list_node<value_type>* head() const
-                {
-                    return head_;
-                }
-
-                list_iterator operator-(difference_type n) const
-                {
-                    /**
-                     * Note: This operator is for internal purposes only,
-                     *       so we do not provide inverse operator or shortcut
-                     *       -= operator.
-                     */
-                    auto tmp = current_;
-
-                    for (difference_type i = 0; i < n; ++i)
-                        tmp = tmp->prev;
-
-                    return list_iterator{tmp};
-                }
-
-                bool end() const
-                {
-                    return end_;
-                }
-
-            private:
-                list_node<value_type>* current_;
-                list_node<value_type>* head_;
-                bool end_;
-        };
-
-        template<class T>
-        bool operator==(const list_iterator<T>& lhs, const list_iterator<T>& rhs)
-        {
-            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-        }
-
-        template<class T>
-        bool operator!=(const list_iterator<T>& lhs, const list_iterator<T>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-
-        template<class T>
-        bool operator==(const list_const_iterator<T>& lhs, const list_iterator<T>& rhs)
-        {
-            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-        }
-
-        template<class T>
-        bool operator!=(const list_const_iterator<T>& lhs, const list_iterator<T>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-
-        template<class T>
-        bool operator==(const list_iterator<T>& lhs, const list_const_iterator<T>& rhs)
-        {
-            return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
-        }
-
-        template<class T>
-        bool operator!=(const list_iterator<T>& lhs, const list_const_iterator<T>& rhs)
-        {
-            return !(lhs == rhs);
-        }
-    }
-
-    /**
-     * 23.3.5, class template list:
-     */
-
-    template<class T, class Allocator>
-    class list
-    {
-        public:
-            using value_type      = T;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using allocator_type  = Allocator;
-
-            using iterator        = aux::list_iterator<value_type>;
-            using const_iterator  = aux::list_const_iterator<value_type>;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using pointer       = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer = typename allocator_traits<allocator_type>::const_pointer;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            /**
-             * 23.3.5.2, construct/copy/destroy:
-             */
-
-            list()
-                : list{allocator_type{}}
-            { /* DUMMY BODY */ }
-
-            explicit list(const allocator_type& alloc)
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            { /* DUMMY BODY */ }
-
-            explicit list(size_type n, const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            {
-                init_(
-                    aux::insert_iterator<value_type>{size_type{}, value_type{}},
-                    aux::insert_iterator<value_type>{size_, value_type{}}
-                );
-            }
-
-            list(size_type n, const value_type& val,
-                 const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            {
-                init_(
-                    aux::insert_iterator<value_type>{size_type{}, val},
-                    aux::insert_iterator<value_type>{n, value_type{}}
-                );
-            }
-
-            template<class InputIterator>
-            list(InputIterator first, InputIterator last,
-                 const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            {
-                init_(first, last);
-            }
-
-            list(const list& other)
-                : list{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            list(list&& other)
-                : allocator_{move(other.allocator_)},
-                  head_{move(other.head_)},
-                  size_{move(other.size_)}
-            {
-                other.head_ = nullptr;
-                other.size_ = size_type{};
-            }
-
-            list(const list& other, const allocator_type alloc)
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            { // Size is set in init_.
-                init_(other.begin(), other.end());
-            }
-
-            list(list&& other, const allocator_type& alloc)
-                : allocator_{alloc},
-                  head_{move(other.head_)},
-                  size_{move(other.size_)}
-            {
-                other.head_ = nullptr;
-                other.size_ = size_type{};
-            }
-
-            list(initializer_list<value_type> init, const allocator_type& alloc = allocator_type{})
-                : allocator_{alloc}, head_{nullptr}, size_{}
-            {
-                init_(init.begin(), init.end());
-            }
-
-            ~list()
-            {
-                fini_();
-            }
-
-            list& operator=(const list& other)
-            {
-                fini_();
-
-                allocator_ = other.allocator_;
-
-                init_(other.begin(), other.end());
-
-                return *this;
-            }
-
-            list& operator=(list&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                fini_();
-
-                head_ = move(other.head_);
-                size_ = move(other.size_);
-                allocator_ = move(other.allocator_);
-
-                other.head_ = nullptr;
-                other.size_ = size_type{};
-
-                return *this;
-            }
-
-            list& operator=(initializer_list<value_type> init)
-            {
-                fini_();
-
-                init_(init.begin(), init.end());
-
-                return *this;
-            }
-
-            template<class InputIterator>
-            void assign(InputIterator first, InputIterator last)
-            {
-                fini_();
-
-                init_(first, last);
-            }
-
-            void assign(size_type n, const value_type& val)
-            {
-                fini_();
-
-                init_(
-                    aux::insert_iterator<value_type>{size_type{}, val},
-                    aux::insert_iterator<value_type>{n, value_type{}}
-                );
-            }
-
-            void assign(initializer_list<value_type> init)
-            {
-                fini_();
-
-                init_(init.begin(), init.end());
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return iterator{head_, head_, size_ == 0U};
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return cbegin();
-            }
-
-            iterator end() noexcept
-            {
-                return iterator{get_last_(), head_, true};
-            }
-
-            const_iterator end() const noexcept
-            {
-                return cend();
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return make_reverse_iterator(end());
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return make_reverse_iterator(begin());
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return const_iterator{head_, head_, size_ == 0U};
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return const_iterator{get_last_(), head_, true};
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return rbegin();
-            }
-
-            /**
-             * 23.3.5.3, capacity:
-             */
-
-            bool empty() const noexcept
-            {
-                return size_ == 0;
-            }
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type max_size() const noexcept
-            {
-                return allocator_traits<allocator_type>::max_size(allocator_);
-            }
-
-            void resize(size_type sz)
-            {
-                // TODO: implement
-            }
-
-            void resize(size_type sz, const value_type& val)
-            {
-                // TODO: implement
-            }
-
-            reference front()
-            {
-                // TODO: bounds checking
-                return head_->value;
-            }
-
-            const_reference front() const
-            {
-                // TODO: bounds checking
-                return head_->value;
-            }
-
-            reference back()
-            {
-                // TODO: bounds checking
-                return head_->prev->value;
-            }
-
-            const_reference back() const
-            {
-                // TODO: bounds checking
-                return head_->prev->value;
-            }
-
-            /**
-             * 23.3.5.4, modifiers:
-             * Note: These should have no effect when an exception
-             *       is thrown while inserting, but since the only
-             *       functions that can throw are the constructors,
-             *       creating the node before any modifications to the
-             *       list itself will satisfy this requirement.
-             */
-
-            template<class... Args>
-            void emplace_front(Args&&... args)
-            {
-                prepend_new_(forward<Args>(args)...);
-            }
-
-            void pop_front()
-            {
-                if (head_)
-                {
-                    --size_;
-
-                    if (head_->next == head_)
-                    {
-                        delete head_;
-                        head_ = nullptr;
-                    }
-                    else
-                    {
-                        auto tmp = head_;
-                        head_->prev->next = head_->next;
-                        head_->next->prev = head_->prev;
-                        head_ = head_->next;
-
-                        delete tmp;
-                    }
-                }
-            }
-
-            template<class... Args>
-            void emplace_back(Args&&... args)
-            {
-                append_new_(forward<Args>(args)...);
-            }
-
-            void push_front(const value_type& value)
-            {
-                prepend_new_(value);
-            }
-
-            void push_front(value_type&& value)
-            {
-                prepend_new_(forward<value_type>(value));
-            }
-
-            void push_back(const value_type& value)
-            {
-                append_new_(value);
-            }
-
-            void push_back(value_type&& value)
-            {
-                append_new_(forward<value_type>(value));
-            }
-
-            void pop_back()
-            {
-                if (head_)
-                {
-                    --size_;
-                    auto target = head_->prev;
-
-                    if (!target)
-                    {
-                        delete head_;
-                        head_ = nullptr;
-                    }
-                    else
-                    {
-                        auto tmp = target;
-                        target->prev->next = target->next;
-                        target->next->prev = target->prev;
-                        target = target->next;
-
-                        delete tmp;
-                    }
-                }
-            }
-
-            template<class... Args>
-            iterator emplace(const_iterator position, Args&&... args)
-            {
-                auto node = position.node();
-                node->prepend(new aux::list_node<value_type>{forward<Args>(args)...});
-                ++size_;
-
-                if (node == head_)
-                    head_ = head_->prev;
-
-                return iterator{node->prev, head_, false};
-            }
-
-            iterator insert(const_iterator position, const value_type& val)
-            {
-                return emplace(position, val);
-            }
-
-            iterator insert(const_iterator position, value_type&& val)
-            {
-                return emplace(position, forward<value_type>(val));
-            }
-
-            iterator insert(const_iterator position, size_type n, const value_type& val)
-            {
-                return insert(
-                    position,
-                    aux::insert_iterator<value_type>{size_type{}, val},
-                    aux::insert_iterator<value_type>{n, value_type{}}
-                );
-            }
-
-            template<class InputIterator>
-            iterator insert(const_iterator position, InputIterator first, InputIterator last)
-            {
-                auto node = position.node()->prev;
-
-                while (first != last)
-                {
-                    node->append(new aux::list_node<value_type>{*first++});
-                    node = node->next;
-                    ++size_;
-                }
-
-                return iterator{position.node()->next, head_, false};
-            }
-
-            iterator insert(const_iterator position, initializer_list<value_type> init)
-            {
-                return insert(position, init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                auto node = position.node();
-
-                if (node == head_)
-                {
-                    if (size_ == 1)
-                    {
-                        delete head_;
-                        head_ = nullptr;
-                        size_ = 0;
-
-                        return end();
-                    }
-                    else
-                        head_ = node->next;
-                }
-
-                auto next = node->next;
-
-                --size_;
-
-                node->unlink();
-                delete node;
-
-                return iterator{next, head_, size_ == 0U};
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                if (first == last)
-                    return end();
-
-                auto first_node = first.node();
-                auto last_node = last.node()->prev;
-                auto prev = first_node->prev;
-                auto next = last_node->next;
-
-                first_node->prev = nullptr;
-                last_node->next = nullptr;
-                prev->next = next;
-                next->prev = prev;
-
-                while (first_node)
-                {
-                    if (first_node == head_)
-                    {
-                        head_ = next;
-                        head_->prev = prev;
-                    }
-
-                    auto tmp = first_node;
-                    first_node = first_node->next;
-                    --size_;
-
-                    delete tmp;
-                }
-
-                return iterator{next, head_, size_ == 0U};
-            }
-
-            void swap(list& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                std::swap(allocator_, other.allocator_);
-                std::swap(head_, other.head_);
-                std::swap(size_, other.size_);
-            }
-
-            void clear() noexcept
-            {
-                fini_();
-            }
-
-            /**
-             * 23.3.5.5, list operations:
-             */
-
-            void splice(const_iterator position, list& other)
-            {
-                if (!head_)
-                {
-                    swap(other);
-                    return;
-                }
-
-                auto other_first = other.head_;
-                auto other_last = other.get_last_();
-                auto node = position.node();
-                auto prev = node->prev;
-
-                // Insert a link range.
-                prev->next = other_first;
-                other_first->prev = prev;
-                node->prev = other_last;
-                other_last->next = node;
-
-                size_ += other.size_;
-
-                if (node == head_)
-                    head_ = other_first;
-                other.head_ = nullptr;
-                other.size_ = 0;
-            }
-
-            void splice(const_iterator position, list&& other)
-            {
-                splice(position, other);
-            }
-
-            void splice(const_iterator position, list& other, const_iterator it)
-            {
-                if (&other == this)
-                    return;
-
-                auto node = position.node();
-                auto target = it.node();
-
-                // Unlink from other.
-                target->prev->next = target->next;
-                target->next->prev = target->prev;
-
-                // Link to us.
-                node->prev->next = target;
-                target->prev = node->prev;
-
-                node->prev = target;
-                target->next = node;
-
-                --other.size_;
-                ++size_;
-
-                if (it.node() == other.head_)
-                    other.advance_head_();
-            }
-
-            void splice(const_iterator position, list&& other, const_iterator it)
-            {
-                splice(position, other, it);
-            }
-
-            void splice(const_iterator position, list& other,
-                        const_iterator first, const_iterator last)
-            {
-                if (&other == this || other.empty())
-                    return;
-
-                if (first == other.begin() && last == other.end())
-                { // [first, last) is everything in other.
-                    splice(position, other);
-                    return;
-                }
-
-                // [first_node, last_node] is the inserted range.
-                aux::list_node<value_type>* first_node{};
-                aux::list_node<value_type>* last_node{};
-
-                if (first == other.begin())
-                { // The range is a prefix of other.
-                    other.head_ = last.node();
-                    other.head_->prev = first.node()->prev;
-                    first.node()->prev->next = last.node();
-
-                    first_node = first.node();
-                    last_node = last.node()->prev;
-                }
-                else if (last == other.end())
-                { // The range is a suffix of other.
-                    auto new_last = first.node()->prev;
-                    auto old_last = other.head_->prev;
-                    other.head_->prev = new_last;
-                    new_last->next = other.head_;
-
-                    first_node = first.node();
-                    last_node = old_last;
-                }
-                else
-                { // The range is a subrange of other.
-                    first_node = first.node();
-                    last_node = last.node()->prev;
-
-                    first_node->prev->next = last.node();
-                    last.node()->prev = first_node->prev;
-                }
-
-                if (!head_)
-                { // Assimilate the range.
-                    head_ = first_node;
-                    first_node->prev = last_node;
-                    last_node->next = first_node;
-                }
-                else
-                {
-                    auto target = position.node();
-                    target->prev->next = first_node;
-                    first_node->prev = target->prev;
-
-                    target->prev = last_node;
-                    last_node->next = target;
-                }
-
-                auto count = distance(
-                    iterator{first_node, nullptr, false},
-                    iterator{last_node, nullptr, false}
-                );
-                ++count;
-
-                size_ += count;
-                other.size_ -= count;
-            }
-
-            void splice(const_iterator position, list&& other,
-                        const_iterator first, const_iterator last)
-            {
-                splice(position, other, first, last);
-            }
-
-            void remove(const value_type& val)
-            {
-                if (!head_)
-                    return;
-
-                auto it = begin();
-                while (it != end())
-                {
-                    if (*it == val)
-                        it = erase(it);
-                    else
-                        ++it;
-                }
-            }
-
-            template<class Predicate>
-            void remove_if(Predicate pred)
-            {
-                if (!head_)
-                    return;
-
-                auto it = begin();
-                while (it != end())
-                {
-                    if (pred(*it))
-                        it = erase(it);
-                    else
-                        ++it;
-                }
-            }
-
-            void unique()
-            {
-                if (!head_)
-                    return;
-
-                auto it = begin();
-                ++it;
-
-                while (it != end())
-                {
-                    if (*it == *(it - 1))
-                        it = erase(it);
-                    else
-                        ++it;
-                }
-            }
-
-            template<class BinaryPredicate>
-            void unique(BinaryPredicate pred)
-            {
-                if (!head_)
-                    return;
-
-                auto it = begin();
-                ++it;
-
-                while (it != end())
-                {
-                    if (pred(*it, *(it - 1)))
-                        it = erase(it);
-                    else
-                        ++it;
-                }
-            }
-
-            // TODO: make a generic base for algorithms like merge
-            //       and quicksort that uses a swapper (the <algorithm>
-            //       versions would use std::swap and list versions would
-            //       use a swapper that swaps list nodes)
-
-            void merge(list& other)
-            {
-                // TODO: implement
-            }
-
-            void merge(list&& other)
-            {
-                merge(other);
-            }
-
-            template<class Compare>
-            void merge(list& other, Compare comp)
-            {
-                // TODO: implement
-            }
-
-            template<class Compare>
-            void merge(list&& other, Compare comp)
-            {
-                merge(other, comp);
-            }
-
-            void reverse() noexcept
-            {
-                // TODO: implement
-            }
-
-            void sort()
-            {
-                // TODO: implement
-            }
-
-            template<class Compare>
-            void sort(Compare comp)
-            {
-                // TODO: implement
-            }
-
-        private:
-            allocator_type allocator_;
-            aux::list_node<value_type>* head_;
-            size_type size_;
-
-            template<class InputIterator>
-            void init_(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                {
-                    auto node = append_new_();
-                    allocator_.construct(&node->value, *first++);
-                }
-            }
-
-            void fini_()
-            {
-                if (!head_)
-                    return;
-
-                head_->prev->next = nullptr;
-                while (head_)
-                {
-                    auto tmp = head_;
-                    head_ = head_->next;
-
-                    delete tmp;
-                }
-
-                head_ = nullptr;
-                size_ = size_type{};
-            }
-
-            template<class... Args>
-            aux::list_node<value_type>* append_new_(Args&&... args)
-            {
-                auto node = new aux::list_node<value_type>{forward<Args>(args)...};
-                auto last = get_last_();
-
-                if (!last)
-                    head_ = node;
-                else
-                    last->append(node);
-
-                ++size_;
-
-                return node;
-            }
-
-            template<class... Args>
-            aux::list_node<value_type>* prepend_new_(Args&&... args)
-            {
-                auto node = new aux::list_node<value_type>{forward<Args>(args)...};
-
-                if (!head_)
-                    head_ = node;
-                else
-                {
-                    head_->prepend(node);
-                    head_ = head_->prev;
-                }
-
-                ++size_;
-
-                return node;
-            }
-
-            aux::list_node<value_type>* get_last_() const
-            {
-                if (!head_)
-                    return nullptr;
-
-                return head_->prev;
-            }
-
-            template<class InputIterator>
-            void insert_range_(InputIterator first, InputIterator last,
-                               aux::list_node<value_type>* where = nullptr)
-            {
-                if (first == last)
-                    return;
-
-                if (!where)
-                    where = get_last_();
-
-                while (first != last)
-                {
-                    where->append(new aux::list_node<value_type>{*first++});
-                    where = where->next;
-                }
-            }
-
-            void advance_head_()
-            {
-                if (size_ == 1)
-                {
-                    head_ = nullptr;
-                    size_ = 0;
-                }
-                else
-                { // The head_ is deleted outside.
-                    head_->next->prev = head_->prev;
-                    head_->prev->next = head_->next;
-                    head_ = head_->next;
-                }
-            }
-    };
-
-    template<class T, class Allocator>
-    void swap(list<T, Allocator>& lhs, list<T, Allocator>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/locale.hpp
===================================================================
--- uspace/lib/cpp/include/impl/locale.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_LOCALE
-#define LIBCPP_LOCALE
-
-#include <cstdlib>
-#include <ios>
-#include <iosfwd>
-#include <string>
-
-#include <__bits/locale.hpp>
-#include <__bits/locale/ctype.hpp>
-#include <__bits/locale/num_get.hpp>
-#include <__bits/locale/num_put.hpp>
-#include <__bits/locale/numpunct.hpp>
-
-namespace std
-{
-    /**
-     * Note: This is a very simplistic implementation of <locale>.
-     *       We have a single locale that has all of its facets.
-     *       This should behave correctly on the outside but will prevent
-     *       us from using multiple locales so if that becomes necessary
-     *       in the future, TODO: implement :)
-     */
-
-    /**
-     * 22.3.3, convenience interfaces:
-     */
-
-    /**
-     * 22.3.3.1, character classification:
-     */
-
-    template<class Char>
-    bool isspace(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::space, c);
-    }
-
-    template<class Char>
-    bool isprint(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::print, c);
-    }
-
-    template<class Char>
-    bool iscntrl(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::cntrl, c);
-    }
-
-    template<class Char>
-    bool isupper(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::upper, c);
-    }
-
-    template<class Char>
-    bool islower(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::lower, c);
-    }
-
-    template<class Char>
-    bool isalpha(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::alpha, c);
-    }
-
-    template<class Char>
-    bool isdigit(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::digit, c);
-    }
-
-    template<class Char>
-    bool ispunct(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::punct, c);
-    }
-
-    template<class Char>
-    bool isxdigit(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::xdigit, c);
-    }
-
-    template<class Char>
-    bool isalnum(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::alnum, c);
-    }
-
-    template<class Char>
-    bool isgraph(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::graph, c);
-    }
-
-    template<class Char>
-    bool isblank(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).is(ctype_base::blank, c);
-    }
-
-    /**
-     * 22.3.3.2, conversions:
-     */
-
-    /**
-     * 22.3.3.2.1, character conversions:
-     */
-
-    template<class Char>
-    Char toupper(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).toupper(c);
-    }
-
-    template<class Char>
-    Char tolower(Char c, const locale& loc)
-    {
-        return use_facet<ctype<Char>>(loc).tolower(c);
-    }
-
-    /**
-     * 22.3.3.2.2, string conversions:
-     */
-
-    // TODO: implement
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/map.hpp
===================================================================
--- uspace/lib/cpp/include/impl/map.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1224 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_MAP
-#define LIBCPP_MAP
-
-#include <functional>
-#include <__bits/rbtree.hpp>
-#include <iterator>
-#include <memory>
-#include <utility>
-#include <type_traits>
-
-namespace std
-{
-    /**
-     * 23.4.4, class template map:
-     */
-
-    template<
-        class Key, class Value,
-        class Compare = less<Key>,
-        class Alloc = allocator<pair<const Key, Value>>
-    >
-    class map
-    {
-        public:
-            using key_type        = Key;
-            using mapped_type     = Value;
-            using value_type      = pair<const key_type, mapped_type>;
-            using key_compare     = Compare;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using node_type = aux::rbtree_single_node<value_type>;
-
-            using iterator             = aux::rbtree_iterator<
-                value_type, reference, pointer, size_type, node_type
-            >;
-            using const_iterator       = aux::rbtree_const_iterator<
-                value_type, const_reference, const_pointer, size_type, node_type
-            >;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            class value_compare
-            {
-                friend class map;
-
-                protected:
-                    key_compare comp;
-
-                    value_compare(key_compare c)
-                        : comp{c}
-                    { /* DUMMY BODY */ }
-
-                public:
-                    using result_type          = bool;
-                    using first_argument_type  = value_type;
-                    using second_argument_type = value_type;
-
-                    bool operator()(const value_type& lhs, const value_type& rhs) const
-                    {
-                        return comp(lhs.first, rhs.first);
-                    }
-            };
-
-            /**
-             * 24.4.4.2, construct/copy/destroy:
-             */
-
-            map()
-                : map{key_compare{}}
-            { /* DUMMY BODY */ }
-
-            explicit map(const key_compare& comp,
-                         const allocator_type& alloc = allocator_type{})
-                : tree_{comp}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            map(InputIterator first, InputIterator last,
-                const key_compare& comp = key_compare{},
-                const allocator_type& alloc = allocator_type{})
-                : map{comp, alloc}
-            {
-                insert(first, last);
-            }
-
-            map(const map& other)
-                : map{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            map(map&& other)
-                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit map(const allocator_type& alloc)
-                : tree_{}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            map(const map& other, const allocator_type& alloc)
-                : tree_{other.tree_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            map(map&& other, const allocator_type& alloc)
-                : tree_{move(other.tree_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            map(initializer_list<value_type> init,
-                const key_compare& comp = key_compare{},
-                const allocator_type& alloc = allocator_type{})
-                : map{comp, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class InputIterator>
-            map(InputIterator first, InputIterator last,
-                const allocator_type& alloc)
-                : map{first, last, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            map(initializer_list<value_type> init,
-                const allocator_type& alloc)
-                : map{init, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~map()
-            { /* DUMMY BODY */ }
-
-            map& operator=(const map& other)
-            {
-                tree_ = other.tree_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            map& operator=(map&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<key_compare>::value)
-            {
-                tree_ = move(other.tree_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            map& operator=(initializer_list<value_type>& init)
-            {
-                tree_.clear();
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return tree_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return tree_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return tree_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return tree_.end();
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return tree_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return tree_.cend();
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return tree_.crbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return tree_.crend();
-            }
-
-            bool empty() const noexcept
-            {
-                return tree_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return tree_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return tree_.max_size(allocator_);
-            }
-
-            /**
-             * 23.4.4.3, element access:
-             */
-
-            mapped_type& operator[](const key_type& key)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                    return parent->value.second;
-
-                auto node = new node_type{value_type{key, mapped_type{}}};
-                tree_.insert_node(node, parent);
-
-                return node->value.second;
-            }
-
-            mapped_type& operator[](key_type&& key)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                    return parent->value.second;
-
-                auto node = new node_type{value_type{move(key), mapped_type{}}};
-                tree_.insert_node(node, parent);
-
-                return node->value.second;
-            }
-
-            mapped_type& at(const key_type& key)
-            {
-                auto it = find(key);
-
-                // TODO: throw out_of_range if it == end()
-                return it->second;
-            }
-
-            const mapped_type& at(const key_type& key) const
-            {
-                auto it = find(key);
-
-                // TODO: throw out_of_range if it == end()
-                return it->second;
-            }
-
-            /**
-             * 23.4.4.4, modifiers:
-             */
-
-            template<class... Args>
-            pair<iterator, bool> emplace(Args&&... args)
-            {
-                return tree_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...).first;
-            }
-
-            pair<iterator, bool> insert(const value_type& val)
-            {
-                return tree_.insert(val);
-            }
-
-            pair<iterator, bool> insert(value_type&& val)
-            {
-                return tree_.insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            pair<iterator, bool> insert(
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace(forward<T>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val).first;
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val)).first;
-            }
-
-            template<class T>
-            iterator insert(
-                const_iterator hint,
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace_hint(hint, forward<T>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class... Args>
-            pair<iterator, bool> try_emplace(const key_type& key, Args&&... args)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                    return make_pair(iterator{parent, false}, false);
-                else
-                {
-                    auto node = new node_type{value_type{key, forward<Args>(args)...}};
-                    tree_.insert_node(node, parent);
-
-                    return make_pair(iterator{node, false}, true);
-                }
-            }
-
-            template<class... Args>
-            pair<iterator, bool> try_emplace(key_type&& key, Args&&... args)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                    return make_pair(iterator{parent, false}, false);
-                else
-                {
-                    auto node = new node_type{value_type{move(key), forward<Args>(args)...}};
-                    tree_.insert_node(node, parent);
-
-                    return make_pair(iterator{node, false}, true);
-                }
-            }
-
-            template<class... Args>
-            iterator try_emplace(const_iterator, const key_type& key, Args&&... args)
-            {
-                return try_emplace(key, forward<Args>(args)...).first;
-            }
-
-            template<class... Args>
-            iterator try_emplace(const_iterator, key_type&& key, Args&&... args)
-            {
-                return try_emplace(move(key), forward<Args>(args)...).first;
-            }
-
-            template<class T>
-            pair<iterator, bool> insert_or_assign(const key_type& key, T&& val)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                {
-                    parent->value.second = forward<T>(val);
-
-                    return make_pair(iterator{parent, false}, false);
-                }
-                else
-                {
-                    auto node = new node_type{value_type{key, forward<T>(val)}};
-                    tree_.insert_node(node, parent);
-
-                    return make_pair(iterator{node, false}, true);
-                }
-            }
-
-            template<class T>
-            pair<iterator, bool> insert_or_assign(key_type&& key, T&& val)
-            {
-                auto parent = tree_.find_parent_for_insertion(key);
-                if (parent && tree_.keys_equal(tree_.get_key(parent->value), key))
-                {
-                    parent->value.second = forward<T>(val);
-
-                    return make_pair(iterator{parent, false}, false);
-                }
-                else
-                {
-                    auto node = new node_type{value_type{move(key), forward<T>(val)}};
-                    tree_.insert_node(node, parent);
-
-                    return make_pair(iterator{node, false}, true);
-                }
-            }
-
-            template<class T>
-            iterator insert_or_assign(const_iterator, const key_type& key, T&& val)
-            {
-                return insert_or_assign(key, forward<T>(val)).first;
-            }
-
-            template<class T>
-            iterator insert_or_assign(const_iterator, key_type&& key, T&& val)
-            {
-                return insert_or_assign(move(key), forward<T>(val)).first;
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return tree_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return tree_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    first.node(), first.end()
-                };
-            }
-
-            void swap(map& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
-            {
-                tree_.swap(other.tree_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            void clear() noexcept
-            {
-                tree_.clear();
-            }
-
-            key_compare key_comp() const
-            {
-                return tree_.key_comp();
-            }
-
-            value_compare value_comp() const
-            {
-                return value_compare{tree_.key_comp()};
-            }
-
-            iterator find(const key_type& key)
-            {
-                return tree_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            const_iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return tree_.count(key);
-            }
-
-            template<class K>
-            size_type count(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.count(key);
-            }
-
-            iterator lower_bound(const key_type& key)
-            {
-                return tree_.lower_bound(key);
-            }
-
-            const_iterator lower_bound(const key_type& key) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            const_iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            iterator upper_bound(const key_type& key)
-            {
-                return tree_.upper_bound(key);
-            }
-
-            const_iterator upper_bound(const key_type& key) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            const_iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return tree_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<iterator, iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<const_iterator, const_iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.equal_range(key);
-            }
-
-        private:
-            using tree_type = aux::rbtree<
-                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
-                key_compare, allocator_type, size_type,
-                iterator, const_iterator,
-                aux::rbtree_single_policy, node_type
-            >;
-
-            tree_type tree_;
-            allocator_type allocator_;
-
-            template<class K, class C, class A>
-            friend bool operator==(const map<K, C, A>&,
-                                   const map<K, C, A>&);
-    };
-
-    template<class Key, class Compare, class Allocator>
-    bool operator==(const map<Key, Compare, Allocator>& lhs,
-                    const map<Key, Compare, Allocator>& rhs)
-    {
-        return lhs.tree_.is_eq_to(rhs.tree_);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<(const map<Key, Compare, Allocator>& lhs,
-                   const map<Key, Compare, Allocator>& rhs)
-    {
-        return lexicographical_compare(
-            lhs.begin(), lhs.end(),
-            rhs.begin(), rhs.end(),
-            lhs.value_comp()
-        );
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator!=(const map<Key, Compare, Allocator>& lhs,
-                    const map<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>(const map<Key, Compare, Allocator>& lhs,
-                   const map<Key, Compare, Allocator>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>=(const map<Key, Compare, Allocator>& lhs,
-                    const map<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<=(const map<Key, Compare, Allocator>& lhs,
-                    const map<Key, Compare, Allocator>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    /**
-     * 23.4.5, class template multimap:
-     */
-
-    template<
-        class Key, class Value,
-        class Compare = less<Key>,
-        class Alloc = allocator<pair<const Key, Value>>
-    >
-    class multimap
-    {
-        public:
-            using key_type        = Key;
-            using mapped_type     = Value;
-            using value_type      = pair<const key_type, mapped_type>;
-            using key_compare     = Compare;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using node_type = aux::rbtree_multi_node<value_type>;
-
-            class value_compare
-            {
-                friend class multimap;
-
-                protected:
-                    key_compare comp;
-
-                    value_compare(key_compare c)
-                        : comp{c}
-                    { /* DUMMY BODY */ }
-
-                public:
-                    using result_type          = bool;
-                    using first_argument_type  = value_type;
-                    using second_argument_type = value_type;
-
-                    bool operator()(const value_type& lhs, const value_type& rhs) const
-                    {
-                        return comp(lhs.first, rhs.first);
-                    }
-            };
-
-            using iterator             = aux::rbtree_iterator<
-                value_type, reference, pointer, size_type, node_type
-            >;
-            using const_iterator       = aux::rbtree_const_iterator<
-                value_type, const_reference, const_pointer, size_type, node_type
-            >;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            multimap()
-                : multimap{key_compare{}}
-            { /* DUMMY BODY */ }
-
-            explicit multimap(const key_compare& comp,
-                              const allocator_type& alloc = allocator_type{})
-                : tree_{comp}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            multimap(InputIterator first, InputIterator last,
-                     const key_compare& comp = key_compare{},
-                     const allocator_type& alloc = allocator_type{})
-                : multimap{comp, alloc}
-            {
-                insert(first, last);
-            }
-
-            multimap(const multimap& other)
-                : multimap{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            multimap(multimap&& other)
-                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit multimap(const allocator_type& alloc)
-                : tree_{}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multimap(const multimap& other, const allocator_type& alloc)
-                : tree_{other.tree_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multimap(multimap&& other, const allocator_type& alloc)
-                : tree_{move(other.tree_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multimap(initializer_list<value_type> init,
-                     const key_compare& comp = key_compare{},
-                     const allocator_type& alloc = allocator_type{})
-                : multimap{comp, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class InputIterator>
-            multimap(InputIterator first, InputIterator last,
-                     const allocator_type& alloc)
-                : multimap{first, last, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            multimap(initializer_list<value_type> init,
-                     const allocator_type& alloc)
-                : multimap{init, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~multimap()
-            { /* DUMMY BODY */ }
-
-            multimap& operator=(const multimap& other)
-            {
-                tree_ = other.tree_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            multimap& operator=(multimap&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<key_compare>::value)
-            {
-                tree_ = move(other.tree_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            multimap& operator=(initializer_list<value_type>& init)
-            {
-                tree_.clear();
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return tree_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return tree_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return tree_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return tree_.end();
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return tree_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return tree_.cend();
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return tree_.crbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return tree_.crend();
-            }
-
-            bool empty() const noexcept
-            {
-                return tree_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return tree_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return tree_.max_size(allocator_);
-            }
-
-            template<class... Args>
-            iterator emplace(Args&&... args)
-            {
-                return tree_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...);
-            }
-
-            iterator insert(const value_type& val)
-            {
-                return tree_.insert(val);
-            }
-
-            iterator insert(value_type&& val)
-            {
-                return tree_.insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            iterator insert(
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace(forward<T>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val);
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            iterator insert(
-                const_iterator hint,
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace_hint(hint, forward<T>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return tree_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return tree_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    first.node(), first.end()
-                };
-            }
-
-            void swap(multimap& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
-            {
-                tree_.swap(other.tree_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            void clear() noexcept
-            {
-                tree_.clear();
-            }
-
-            key_compare key_comp() const
-            {
-                return tree_.key_comp();
-            }
-
-            value_compare value_comp() const
-            {
-                return value_compare{tree_.key_comp()};
-            }
-
-            iterator find(const key_type& key)
-            {
-                return tree_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            const_iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return tree_.count(key);
-            }
-
-            template<class K>
-            size_type count(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.count(key);
-            }
-
-            iterator lower_bound(const key_type& key)
-            {
-                return tree_.lower_bound(key);
-            }
-
-            const_iterator lower_bound(const key_type& key) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            const_iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            iterator upper_bound(const key_type& key)
-            {
-                return tree_.upper_bound(key);
-            }
-
-            const_iterator upper_bound(const key_type& key) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            const_iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return tree_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<iterator, iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<const_iterator, const_iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.equal_range(key);
-            }
-
-        private:
-            using tree_type = aux::rbtree<
-                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
-                key_compare, allocator_type, size_type,
-                iterator, const_iterator,
-                aux::rbtree_multi_policy, node_type
-            >;
-
-            tree_type tree_;
-            allocator_type allocator_;
-
-            template<class K, class C, class A>
-            friend bool operator==(const multimap<K, C, A>&,
-                                   const multimap<K, C, A>&);
-    };
-
-    template<class Key, class Compare, class Allocator>
-    bool operator==(const multimap<Key, Compare, Allocator>& lhs,
-                    const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return lhs.tree_.is_eq_to(rhs.tree_);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<(const multimap<Key, Compare, Allocator>& lhs,
-                   const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return lexicographical_compare(
-            lhs.begin(), lhs.end(),
-            rhs.begin(), rhs.end(),
-            lhs.value_comp()
-        );
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator!=(const multimap<Key, Compare, Allocator>& lhs,
-                    const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>(const multimap<Key, Compare, Allocator>& lhs,
-                   const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>=(const multimap<Key, Compare, Allocator>& lhs,
-                    const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<=(const multimap<Key, Compare, Allocator>& lhs,
-                    const multimap<Key, Compare, Allocator>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/mutex.hpp
===================================================================
--- uspace/lib/cpp/include/impl/mutex.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,542 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_MUTEX
-#define LIBCPP_MUTEX
-
-#include <functional>
-#include <__bits/common.hpp>
-#include <__bits/thread.hpp>
-#include <thread>
-
-namespace std
-{
-    /**
-     * 20.4.1.2.1, class mutex:
-     */
-
-    class mutex
-    {
-        public:
-            constexpr mutex() noexcept
-                : mtx_{}
-            {
-                aux::threading::mutex::init(mtx_);
-            }
-
-            ~mutex() = default;
-
-            mutex(const mutex&) = delete;
-            mutex& operator=(const mutex&) = delete;
-
-            void lock();
-            bool try_lock();
-            void unlock();
-
-            using native_handle_type = aux::mutex_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::mutex_t mtx_;
-    };
-
-    /**
-     * 30.4.1.2.2, class recursive_mutex:
-     */
-
-    class recursive_mutex
-    {
-        public:
-            constexpr recursive_mutex() noexcept
-                : mtx_{}, lock_level_{}, owner_{}
-            {
-                aux::threading::mutex::init(mtx_);
-            }
-
-            ~recursive_mutex();
-
-            recursive_mutex(const recursive_mutex&) = delete;
-            recursive_mutex& operator=(const recursive_mutex&) = delete;
-
-            void lock();
-            bool try_lock() noexcept;
-            void unlock();
-
-            using native_handle_type = aux::mutex_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::mutex_t mtx_;
-            size_t lock_level_;
-            thread::id owner_;
-    };
-
-    /**
-     * 30.4.1.3.1, class timed_mutex:
-     */
-
-    class timed_mutex
-    {
-        public:
-            timed_mutex() noexcept;
-            ~timed_mutex();
-
-            timed_mutex(const timed_mutex&) = delete;
-            timed_mutex& operator=(const timed_mutex&) = delete;
-
-            void lock();
-            bool try_lock();
-            void unlock();
-
-            template<class Rep, class Period>
-            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                auto time = aux::threading::time::convert(rel_time);
-
-                return aux::threading::mutex::try_lock_for(time);
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                auto dur = (abs_time - Clock::now());
-                auto time = aux::threading::time::convert(dur);
-
-                return aux::threading::mutex::try_lock_for(time);
-            }
-
-            using native_handle_type = aux::mutex_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::mutex_t mtx_;
-    };
-
-    /**
-     * 30.4.1.3.2, class recursive_timed_mutex:
-     */
-
-    class recursive_timed_mutex
-    {
-        public:
-            recursive_timed_mutex() noexcept
-                : mtx_{}, lock_level_{}, owner_{}
-            {
-                aux::threading::mutex::init(mtx_);
-            }
-
-            ~recursive_timed_mutex();
-
-            recursive_timed_mutex(const recursive_timed_mutex&) = delete;
-            recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
-
-            void lock();
-            bool try_lock() noexcept;
-            void unlock();
-
-            template<class Rep, class Period>
-            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                if (owner_ == this_thread::get_id())
-                    return true;
-
-                auto time = aux::threading::time::convert(rel_time);
-                auto ret = aux::threading::mutex::try_lock_for(time);
-
-                if (ret)
-                    ++lock_level_;
-                return ret;
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                if (owner_ == this_thread::get_id())
-                    return true;
-
-                auto dur = (abs_time - Clock::now());
-                auto time = aux::threading::time::convert(dur);
-                auto ret = aux::threading::mutex::try_lock_for(time);
-
-                if (ret)
-                    ++lock_level_;
-                return ret;
-            }
-
-            using native_handle_type = aux::mutex_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::mutex_t mtx_;
-            size_t lock_level_;
-            thread::id owner_;
-    };
-
-    struct defer_lock_t
-    { /* DUMMY BODY */ };
-
-    struct try_to_lock_t
-    { /* DUMMY BODY */ };
-
-    struct adopt_lock_t
-    { /* DUMMY BODY */ };
-
-    constexpr defer_lock_t defer_lock
-    { /* DUMMY BODY */ };
-
-    constexpr try_to_lock_t try_to_lock
-    { /* DUMMY BODY */ };
-
-    constexpr adopt_lock_t adopt_lock
-    { /* DUMMY BODY */ };
-
-    /**
-     * 30.4.2.1, class template lock_guard:
-     */
-
-    template<class Mutex>
-    class lock_guard
-    {
-        public:
-            using mutex_type = Mutex;
-
-            explicit lock_guard(mutex_type& mtx)
-                : mtx_{mtx}
-            {
-                mtx.lock();
-            }
-
-            lock_guard(mutex_type& mtx, adopt_lock_t)
-                : mtx_{mtx}
-            { /* DUMMY BODY */ }
-
-            ~lock_guard()
-            {
-                mtx_.unlock();
-            }
-
-            lock_guard(const lock_guard&) = delete;
-            lock_guard& operator=(const lock_guard&) = delete;
-
-        private:
-            mutex_type& mtx_;
-    };
-
-    template<class Mutex>
-    class unique_lock
-    {
-        public:
-            using mutex_type = Mutex;
-
-            /**
-             * 30.4.2.2.1, construction/copy/destroy:
-             */
-
-            unique_lock() noexcept
-                : mtx_{nullptr}, owns_{false}
-            { /* DUMMY BODY */ }
-
-            explicit unique_lock(mutex_type& mtx)
-                : mtx_{&mtx}, owns_{true}
-            {
-                mtx_->lock();
-            }
-
-            unique_lock(mutex_type& mtx, defer_lock_t) noexcept
-                : mtx_{&mtx}, owns_{false}
-            { /* DUMMY BODY */ }
-
-            unique_lock(mutex_type& mtx, try_to_lock_t)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock();
-            }
-
-            unique_lock(mutex_type& mtx, adopt_lock_t)
-                : mtx_{&mtx}, owns_{true}
-            { /* DUMMY BODY */ }
-
-            template<class Clock, class Duration>
-            unique_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock_until(abs_time);
-            }
-
-            template<class Rep, class Period>
-            unique_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock_for(rel_time);
-            }
-
-            ~unique_lock()
-            {
-                if (owns_)
-                    mtx_->unlock();
-            }
-
-            unique_lock(const unique_lock&) = delete;
-            unique_lock& operator=(const unique_lock&) = delete;
-
-            unique_lock(unique_lock&& other) noexcept
-                : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
-            {
-                other.mtx_ = nullptr;
-                other.owns_ = false;
-            }
-
-            unique_lock& operator=(unique_lock&& other)
-            {
-                if (owns_)
-                    mtx_->unlock();
-
-                mtx_ = move(other.mtx_);
-                owns_ = move(other.owns_);
-
-                other.mtx_ = nullptr;
-                other.owns_ = false;
-            }
-
-            /**
-             * 30.4.2.2.2, locking:
-             */
-
-            void lock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                mtx_->lock();
-                owns_ = true;
-            }
-
-            bool try_lock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock();
-
-                return owns_;
-            }
-
-            template<class Rep, class Period>
-            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock_for(rel_time);
-
-                return owns_;
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock_until(abs_time);
-
-                return owns_;
-            }
-
-            void unlock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if owns_ == false
-                 */
-
-                mtx_->unlock();
-            }
-
-            /**
-             * 30.4.2.2.3, modifiers:
-             */
-
-            void swap(unique_lock& other) noexcept
-            {
-                std::swap(mtx_, other.mtx_);
-                std::swap(owns_, other.owns_);
-            }
-
-            mutex_type* release() noexcept
-            {
-                auto ret = mtx_;
-                mtx_ = nullptr;
-                owns_ = false;
-
-                return ret;
-            }
-
-            /**
-             * 30.4.2.2.4, observers:
-             */
-
-            bool owns_lock() const noexcept
-            {
-                return owns_;
-            }
-
-            explicit operator bool() const noexcept
-            {
-                return owns_;
-            }
-
-            mutex_type* mutex() const noexcept
-            {
-                return mtx_;
-            }
-
-        private:
-            mutex_type* mtx_;
-            bool owns_;
-    };
-
-    template<class Mutex>
-    void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) noexcept
-    {
-        lhs.swap(rhs);
-    }
-
-    namespace aux
-    {
-        template<class L>
-        int try_lock_tail(int idx, L& l)
-        {
-            if (!l.try_lock())
-                return idx;
-            else
-                return -1;
-        }
-
-        template<class L1, class... L2>
-        int try_lock_tail(int idx, L1& l1, L2&... ls)
-        {
-            if (!l1.try_lock())
-                return idx;
-
-            auto ret = try_lock_tail(idx + 1, ls...);
-            if (ret != -1)
-                l1.unlock();
-
-            return ret;
-        }
-    }
-
-    template<class L1, class L2, class... L3>
-    int try_lock(L1& l1, L2& l2, L3&... ls)
-    {
-        return aux::try_lock_tail(0, l1, l2, ls...);
-    }
-
-    namespace aux
-    {
-        template<class L>
-        bool lock_tail(L& l)
-        {
-            return l.try_lock();
-        }
-
-        template<class L1, class... L2>
-        bool lock_tail(L1& l1, L2&... ls)
-        {
-            if (l1.try_lock())
-            {
-                auto ret = lock_tail(ls...);
-                if (ret)
-                    return true;
-
-                l1.unlock();
-            }
-
-            return false;
-        }
-    }
-
-    template<class L1, class L2, class... L3>
-    void lock(L1& l1, L2& l2, L3&... ls)
-    {
-        do
-        {
-            l1.lock();
-
-            if (aux::lock_tail(l2, ls...))
-                return;
-            l1.unlock();
-        } while (true);
-    }
-
-    struct once_flag
-    {
-        constexpr once_flag() noexcept
-            : called_{false}, mtx_{}
-        { /* DUMMY BODY */ }
-
-        once_flag(const once_flag&) = delete;
-        once_flag& operator=(const once_flag&) = delete;
-
-        private:
-            bool called_;
-            mutex mtx_;
-
-            template<class Callable, class... Args>
-            friend void call_once(once_flag&, Callable&&, Args&&...);
-    };
-
-    template<class Callable, class... Args>
-    void call_once(once_flag& flag, Callable&& func, Args&&... args)
-    {
-        flag.mtx_.lock();
-        if (!flag.called_)
-        {
-            // TODO: exception handling
-
-            aux::INVOKE(forward<Callable>(func), forward<Args>(args)...);
-            flag.called_ = true;
-        }
-        flag.mtx_.unlock();
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/new.hpp
===================================================================
--- uspace/lib/cpp/include/impl/new.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,69 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_NEW
-#define LIBCPP_NEW
-
-#include <exception>
-
-namespace std
-{
-
-class bad_alloc: public std::exception
-{
-	public:
-		bad_alloc() = default;
-		bad_alloc(const bad_alloc&) = default;
-		bad_alloc& operator=(const bad_alloc&) = default;
-		virtual const char* what() const noexcept override;
-		virtual ~bad_alloc() = default;
-};
-
-struct nothrow_t {};
-extern const nothrow_t nothrow;
-
-using new_handler = void (*)();
-
-new_handler set_new_handler(new_handler);
-new_handler get_new_handler() noexcept;
-
-}
-
-void* operator new(std::size_t);
-void* operator new(std::size_t, void*);
-void* operator new(std::size_t, const std::nothrow_t&) noexcept;
-void* operator new[](std::size_t);
-void* operator new[](std::size_t, const std::nothrow_t&) noexcept;
-
-void operator delete(void*) noexcept;
-void operator delete(void*, std::size_t) noexcept;
-void operator delete[](void*) noexcept;
-void operator delete[](void*, std::size_t) noexcept;
-
-#endif
-
Index: uspace/lib/cpp/include/impl/numeric.hpp
===================================================================
--- uspace/lib/cpp/include/impl/numeric.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,182 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_NUMERIC
-#define LIBCPP_NUMERIC
-
-#include <utility>
-
-namespace std
-{
-
-    /**
-     * 26.7.2, accumulate:
-     */
-
-    template<class InputIterator, class T>
-    T accumulate(InputIterator first, InputIterator last, T init)
-    {
-        auto acc{init};
-        while (first != last)
-            acc += *first++;
-
-        return acc;
-    }
-
-    template<class InputIterator, class T, class BinaryOperation>
-    T accumulate(InputIterator first, InputIterator last, T init,
-                 BinaryOperation op)
-    {
-        auto acc{init};
-        while (first != last)
-            acc = op(acc, *first++);
-
-        return acc;
-    }
-
-    /**
-     * 26.7.3, inner product:
-     */
-
-    template<class InputIterator1, class InputIterator2, class T>
-    T inner_product(InputIterator1 first1, InputIterator1 last1,
-                    InputIterator2 first2, T init)
-    {
-        auto res{init};
-        while (first1 != last1)
-            res += (*first1++) * (*first2++);
-
-        return res;
-    }
-
-    template<class InputIterator1, class InputIterator2, class T,
-             class BinaryOperation1, class BinaryOperation2>
-    T inner_product(InputIterator1 first1, InputIterator1 last1,
-                    InputIterator2 first2, T init,
-                    BinaryOperation1 op1, BinaryOperation2 op2)
-    {
-        auto res{init};
-        while (first1 != last1)
-            res = op1(res, op2(*first1++, *first2++));
-
-        return res;
-    }
-
-    /**
-     * 26.7.4, partial sum:
-     */
-
-    template<class InputIterator, class OutputIterator>
-    OutputIterator partial_sum(InputIterator first, InputIterator last,
-                               OutputIterator result)
-    {
-        if (first == last)
-            return result;
-
-        auto acc{*first++};
-        *result++ = acc;
-
-        while (first != last)
-            *result++ = acc = acc + *first++;
-
-        return result;
-    }
-
-    template<class InputIterator, class OutputIterator, class BinaryOperation>
-    OutputIterator partial_sum(InputIterator first, InputIterator last,
-                               OutputIterator result, BinaryOperation op)
-    {
-        if (first == last)
-            return result;
-
-        auto acc{*first++};
-        *result++ = acc;
-
-        while (first != last)
-            *result++ = acc = op(acc, *first++);
-
-        return result;
-    }
-
-    /**
-     * 26.7.5, adjacent difference:
-     */
-
-    template<class InputIterator, class OutputIterator>
-    OutputIterator adjacent_difference(InputIterator first, InputIterator last,
-                                       OutputIterator result)
-    {
-        if (first == last)
-            return result;
-
-        auto acc{*first++};
-        *result++ = acc;
-
-        while (first != last)
-        {
-            auto val = *first++;
-            *result++ = val - acc;
-            acc = move(val);
-        }
-
-        return result;
-    }
-
-    template<class InputIterator, class OutputIterator, class BinaryOperation>
-    OutputIterator adjacent_difference(InputIterator first, InputIterator last,
-                                       OutputIterator result, BinaryOperation op)
-    {
-        if (first == last)
-            return result;
-
-        auto acc{*first++};
-        *result++ = acc;
-
-        while (first != last)
-        {
-            auto val = *first++;
-            *result++ = op(val, acc);
-            acc = move(val);
-        }
-
-        return result;
-    }
-
-    /**
-     * 26.7.6, iota:
-     */
-
-    template<class ForwardIterator, class T>
-    void iota(ForwardIterator first, ForwardIterator last, T value)
-    {
-        while (first != last)
-            *first++ = value++;
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/ostream.hpp
===================================================================
--- uspace/lib/cpp/include/impl/ostream.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,813 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_OSTREAM
-#define LIBCPP_OSTREAM
-
-#include <ios>
-#include <iosfwd>
-#include <locale>
-
-namespace std
-{
-    /**
-     * 27.7.3.1, class template basic_ostream:
-     */
-
-    template<class Char, class Traits>
-    class basic_ostream: virtual public basic_ios<Char, Traits>
-    {
-        public:
-            using char_type   = Char;
-            using traits_type = Traits;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            /**
-             * 27.7.3.2, constructor/destructor:
-             */
-
-            explicit basic_ostream(basic_streambuf<char_type, traits_type>* sb)
-            {
-                basic_ios<Char, Traits>::init(sb);
-            }
-
-            virtual ~basic_ostream()
-            { /* DUMMY BODY */ }
-
-            /**
-             * 27.7.3.4, prefix/suffix:
-             */
-
-            class sentry
-            {
-                public:
-                    explicit sentry(basic_ostream<Char, Traits>& os)
-                        : os_{os}, ok_{false}
-                    {
-                        if (os.good())
-                        {
-                            if (os.tie())
-                                os.tie()->flush();
-                        }
-
-                        ok_ = os.good();
-                    }
-
-                    ~sentry()
-                    {
-                        if ((os_.flags() & ios_base::unitbuf) && os_.good())
-                        {
-                            auto ret = os_.rdbuf()->pubsync();
-                            (void)ret;
-                            // TODO: if ret == -1, set badbit in rdstate
-                        }
-                    }
-
-                    explicit operator bool() const
-                    {
-                        return ok_;
-                    }
-
-                    sentry(const sentry&) = delete;
-                    sentry& operator=(const sentry&) = delete;
-
-                private:
-                    basic_ostream<Char, Traits>& os_;
-                    bool ok_;
-            };
-
-            /**
-             * 27.7.3.6, formatted output:
-             */
-
-            basic_ostream<Char, Traits>& operator<<(
-                basic_ostream<Char, Traits>& (*pf)(basic_ostream<Char, Traits>&)
-            )
-            {
-                return pf(*this);
-            }
-
-            basic_ostream<Char, Traits>& operator<<(
-                basic_ios<Char, Traits>& (*pf)(basic_ios<Char, Traits>&)
-            )
-            {
-                pf(*this);
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(
-                ios_base& (*pf)(ios_base&)
-            )
-            {
-                pf(*this);
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(bool x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(short x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    auto basefield = (this->flags() & ios_base::basefield);
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(),
-                                          (basefield == ios_base::oct || basefield == ios_base::hex)
-                                          ? static_cast<long>(static_cast<unsigned short>(x))
-                                          : static_cast<long>(x)).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(unsigned short x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(),
-                                          static_cast<unsigned long>(x)).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(int x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    auto basefield = (this->flags() & ios_base::basefield);
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(),
-                                          (basefield == ios_base::oct || basefield == ios_base::hex)
-                                          ? static_cast<long>(static_cast<unsigned int>(x))
-                                          : static_cast<long>(x)).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(unsigned int x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(),
-                                          static_cast<unsigned long>(x)).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(long x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(unsigned long x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(long long x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(unsigned long long x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(float x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), static_cast<double>(x)).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(double x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(long double x)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), x).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(const void* p)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    bool failed = use_facet<
-                        num_put<char_type, ostreambuf_iterator<char_type, traits_type>>
-                    >(this->getloc()).put(*this, *this, this->fill(), p).failed();
-
-                    if (failed)
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& operator<<(basic_streambuf<Char, Traits>* sb)
-            {
-                if (!sb)
-                    return *this;
-
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    size_t count{};
-
-                    int_type c = sb->sgetc();
-                    while (!traits_type::eq_int_type(c, traits_type::eof()))
-                    {
-                        this->put(traits_type::to_char_type(c));
-
-                        if (!(*this))
-                            break;
-
-                        ++count;
-                        sb->sbumpc();
-                        c = sb->sgetc();
-                    }
-
-                    if (count == 0)
-                        this->setstate(ios_base::failbit);
-                }
-
-                return *this;
-            }
-
-            /**
-             * 27.7.3.7, unformatted output:
-             * TODO: when we have exceptions, complete these
-             */
-
-            basic_ostream<Char, Traits>& put(char_type c)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    auto ret = this->rdbuf()->sputc(c);
-                    if (traits_type::eq_int_type(ret, traits_type::eof()))
-                        this->setstate(ios_base::badbit);
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& write(const char_type* s, streamsize n)
-            {
-                sentry sen{*this};
-
-                if (sen)
-                {
-                    for (streamsize i = 0; i < n; ++i)
-                    {
-                        auto ret = this->rdbuf()->sputc(s[i]);
-                        if (traits_type::eq_int_type(ret, traits_type::eof()))
-                        {
-                            this->setstate(ios_base::badbit);
-                            break;
-                        }
-                    }
-                }
-
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& flush()
-            {
-                if (this->rdbuf())
-                {
-                    sentry sen{*this};
-
-                    if (sen)
-                    {
-                        auto ret = this->rdbuf()->pubsync();
-                        if (ret == -1)
-                            this->setstate(ios_base::badbit);
-                    }
-                }
-
-                return *this;
-            }
-
-            /**
-             * 27.7.3.5, seeks:
-             */
-
-            pos_type tellp()
-            {
-                // TODO: implement
-                return pos_type{};
-            }
-
-            basic_ostream<Char, Traits>& seekp(pos_type pos)
-            {
-                // TODO: implement
-                return *this;
-            }
-
-            basic_ostream<Char, Traits>& seekp(off_type off, ios_base::seekdir dir)
-            {
-                // TODO: implement
-                return *this;
-            }
-
-        protected:
-            basic_ostream(const basic_ostream&) = delete;
-
-            basic_ostream(basic_ostream&& other)
-            {
-                basic_ios<Char, Traits>::move(other);
-            }
-
-            /**
-             * 27.7.3.3, assign/swap:
-             */
-
-            basic_ostream& operator=(const basic_ostream&) = delete;
-
-            basic_ostream& operator=(basic_ostream&& other)
-            {
-                swap(other);
-
-                return *this;
-            }
-
-            void swap(basic_ostream& rhs)
-            {
-                basic_ios<Char, Traits>::swap(rhs);
-            }
-    };
-
-    using ostream  = basic_ostream<char>;
-    using wostream = basic_ostream<wchar_t>;
-
-    /**
-     * 27.7.6.3.4, character inserter function templates:
-     */
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            Char c)
-    {
-        typename basic_ostream<Char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            if (os.width() > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                    os.put(c);
-                }
-                else
-                {
-                    os.put(c);
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.put(c);
-
-            os.width(0);
-        }
-
-        return os;
-    }
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            char c)
-    {
-        typename basic_ostream<Char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            if (os.width() > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                    os.put(os.widen(c));
-                }
-                else
-                {
-                    os.put(os.widen(c));
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.put(os.widen(c));
-
-            os.width(0);
-        }
-        return os;
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            char c)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            if (os.width() > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                    os.put(c);
-                }
-                else
-                {
-                    os.put(c);
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.put(c);
-
-            os.width(0);
-            }
-
-        return os;
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            signed char c)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            if (os.width() > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                    os.put(c);
-                }
-                else
-                {
-                    os.put(c);
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.put(c);
-
-            os.width(0);
-        }
-
-        return os;
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            unsigned char c)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            if (os.width() > 0)
-            {
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                    os.put(c);
-                }
-                else
-                {
-                    os.put(c);
-                    for (decltype(os.width()) i = 0; i < os.width(); ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-                os.put(c);
-
-            os.width(0);
-        }
-
-        return os;
-    }
-
-    namespace aux
-    {
-        template<class Char, class Traits>
-        basic_ostream<Char, Traits>& insert(basic_ostream<Char, Traits>& os,
-                                            const Char* str, size_t len)
-        {
-            if (os.width() > 0 && static_cast<size_t>(os.width()) > len)
-            {
-                size_t to_pad = (static_cast<size_t>(os.width()) - len);
-
-                if ((os.flags() & ios_base::adjustfield) != ios_base::left)
-                {
-                    for (size_t i = 0; i < to_pad; ++i)
-                        os.put(os.fill());
-                    for (size_t i = 0; i < len; ++i)
-                        os.put(os.widen(str[i]));
-                }
-                else
-                {
-                    for (size_t i = 0; i < len; ++i)
-                        os.put(os.widen(str[i]));
-                    for (size_t i = 0; i < to_pad; ++i)
-                        os.put(os.fill());
-                }
-            }
-            else
-            {
-                for (size_t i = 0; i < len; ++i)
-                    os.put(os.widen(str[i]));
-            }
-
-            os.width(0);
-            return os;
-        }
-    }
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const Char* str)
-    {
-        typename basic_ostream<Char, Traits>::sentry sen{os};
-
-        auto len = Traits::length(str);
-
-        return aux::insert(os, str, len);
-    }
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const char* str)
-    {
-        typename basic_ostream<Char, Traits>::sentry sen{os};
-
-        auto len = std::char_traits<char>::length(str);
-
-        return aux::insert(os, str, len);
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            const char* str)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            auto len = Traits::length(str);
-
-            return aux::insert(os, str, len);
-        }
-        else
-            return os;
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            const signed char* str)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            auto len = Traits::length(reinterpret_cast<const char*>(str));
-
-            return aux::insert(os, str, len);
-        }
-        else
-            return os;
-    }
-
-    template<class Traits>
-    basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os,
-                                            const unsigned char* str)
-    {
-        typename basic_ostream<char, Traits>::sentry sen{os};
-
-        if (sen)
-        {
-            auto len = Traits::length(reinterpret_cast<const char*>(str));
-
-            return aux::insert(os, str, len);
-        }
-        else
-            return os;
-    }
-
-    /**
-     * 27.7.3.8, standard basic_ostream manipulators:
-     */
-
-    template<class Char, class Traits = char_traits<Char>>
-    basic_ostream<Char, Traits>& endl(basic_ostream<Char, Traits>& os)
-    {
-        os.put(os.widen('\n'));
-        os.flush();
-
-        return os;
-    }
-
-    template<class Char, class Traits = char_traits<Char>>
-    basic_ostream<Char, Traits>& ends(basic_ostream<Char, Traits>& os)
-    {
-        os.put(Char{});
-
-        return os;
-    }
-
-    template<class Char, class Traits = char_traits<Char>>
-    basic_ostream<Char, Traits>& flush(basic_ostream<Char, Traits>& os)
-    {
-        os.flush();
-
-        return os;
-    }
-
-    template<class Char, class Traits = char_traits<Char>, class T>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>&& os, const T& x)
-    {
-        os << x;
-
-        return os;
-    }
-}
-
-#endif
-
Index: uspace/lib/cpp/include/impl/queue.hpp
===================================================================
--- uspace/lib/cpp/include/impl/queue.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,407 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_QUEUE
-#define LIBCPP_QUEUE
-
-#include <algorithm>
-#include <deque>
-#include <memory>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-namespace std
-{
-    /**
-     * 23.6.3, class template queue:
-     */
-
-    template<class T, class Container = deque<T>>
-    class queue
-    {
-        public:
-            using value_type      = typename Container::value_type;
-            using reference       = typename Container::reference;
-            using const_reference = typename Container::const_reference;
-            using size_type       = typename Container::size_type;
-            using container_type  = Container;
-
-        protected:
-            container_type c;
-
-        public:
-            explicit queue(const container_type& cc)
-                : c{cc}
-            { /* DUMMY BODY */ }
-
-            explicit queue(container_type&& cc = container_type{})
-                : c{move(cc)}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            explicit queue(const Alloc& alloc)
-                : c{alloc}
-            { /* DUMMY BODY */}
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            queue(const container_type& cc, const Alloc& alloc)
-                : c{cc, alloc}
-            { /* DUMMY BODY */}
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            queue(container_type&& cc, const Alloc& alloc)
-                : c{move(cc), alloc}
-            { /* DUMMY BODY */}
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            queue(const queue& other, const Alloc& alloc)
-                : c{other.c, alloc}
-            { /* DUMMY BODY */}
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            queue(queue&& other, const Alloc& alloc)
-                : c{move(other.c), alloc}
-            { /* DUMMY BODY */}
-
-            bool empty() const
-            {
-                return c.empty();
-            }
-
-            size_type size() const
-            {
-                return c.size();
-            }
-
-            reference front()
-            {
-                return c.front();
-            }
-
-            const_reference front() const
-            {
-                return c.front();
-            }
-
-            reference back()
-            {
-                return c.back();
-            }
-
-            const_reference back() const
-            {
-                return c.back();
-            }
-
-            void push(const value_type& val)
-            {
-                c.push_back(val);
-            }
-
-            void push(value_type&& val)
-            {
-                c.push_back(forward<value_type>(val));
-            }
-
-            template<class... Args>
-            void emplace(Args&&... args)
-            {
-                c.emplace_back(forward<Args>(args)...);
-            }
-
-            void pop()
-            {
-                c.pop_front();
-            }
-
-            void swap(queue& other)
-                noexcept(noexcept(swap(c, other.c)))
-            {
-                std::swap(c, other.c);
-            }
-
-        private:
-            template<class U, class C>
-            friend bool operator==(const queue<U, C>&, const queue<U, C>&);
-
-            template<class U, class C>
-            friend bool operator<(const queue<U, C>&, const queue<U, C>&);
-
-            template<class U, class C>
-            friend bool operator!=(const queue<U, C>&, const queue<U, C>&);
-
-            template<class U, class C>
-            friend bool operator>(const queue<U, C>&, const queue<U, C>&);
-
-            template<class U, class C>
-            friend bool operator>=(const queue<U, C>&, const queue<U, C>&);
-
-            template<class U, class C>
-            friend bool operator<=(const queue<U, C>&, const queue<U, C>&);
-    };
-
-    template<class T, class Container, class Alloc>
-    struct uses_allocator<queue<T, Container>, Alloc>
-        : uses_allocator<Container, Alloc>
-    { /* DUMMY BODY */ };
-
-    /**
-     * 23.6.4, class template priority_queue:
-     */
-
-    template<
-        class T, class Container = vector<T>,
-        class Compare = less<typename Container::value_type>
-    >
-    class priority_queue
-    {
-        public:
-            using value_type      = typename Container::value_type;
-            using reference       = typename Container::reference;
-            using const_reference = typename Container::const_reference;
-            using size_type       = typename Container::size_type;
-            using container_type  = Container;
-
-        protected:
-            using compare_type = Compare;
-
-            compare_type comp;
-            container_type c;
-
-        public:
-            priority_queue(const compare_type& cmp, const container_type& cc)
-                : comp{cmp}, c{cc}
-            {
-                make_heap(c.begin(), c.end(), comp);
-            }
-
-            explicit priority_queue(const compare_type& cmp = compare_type{},
-                                    container_type&& cc = container_type{})
-                : comp{cmp}, c{move(cc)}
-            {
-                make_heap(c.begin(), c.end(), comp);
-            }
-
-            template<class InputIterator>
-            priority_queue(InputIterator first, InputIterator last,
-                           const compare_type& cmp,
-                           const container_type& cc)
-                : comp{cmp}, c{cc}
-            {
-                c.insert(c.end(), first, last);
-                make_heap(c.begin(), c.end(), comp);
-            }
-
-            template<class InputIterator>
-            priority_queue(InputIterator first, InputIterator last,
-                           const compare_type& cmp = compare_type{},
-                           container_type&& cc = container_type{})
-                : comp{cmp}, c{move(cc)}
-            {
-                c.insert(c.end(), first, last);
-                make_heap(c.begin(), c.end(), comp);
-            }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            explicit priority_queue(const Alloc& alloc)
-                : comp{}, c{alloc}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            priority_queue(const compare_type& cmp, const Alloc& alloc)
-                : comp{cmp}, c{alloc}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            priority_queue(const compare_type& cmp, const container_type& cc,
-                           const Alloc& alloc)
-                : comp{cmp}, c{cc, alloc}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            priority_queue(const compare_type& cmp, container_type&& cc,
-                           const Alloc& alloc)
-                : comp{cmp}, c{move(cc), alloc}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            priority_queue(const priority_queue& other, const Alloc& alloc)
-                : comp{other.comp}, c{other.c, alloc}
-            { /* DUMMY BODY */ }
-
-            template<
-                class Alloc,
-                class = enable_if_t<uses_allocator<container_type, Alloc>::value, void>
-            >
-            priority_queue(priority_queue&& other, const Alloc& alloc)
-                : comp{move(other.comp)}, c{move(other.c), alloc}
-            { /* DUMMY BODY */ }
-
-            bool empty() const
-            {
-                return c.empty();
-            }
-
-            size_type size() const
-            {
-                return c.size();
-            }
-
-            const_reference top() const
-            {
-                return c.front();
-            }
-
-            void push(const value_type& val)
-            {
-                c.push_back(val);
-                push_heap(c.begin(), c.end(), comp);
-            }
-
-            void push(value_type&& val)
-            {
-                c.push_back(forward<value_type>(val));
-                push_heap(c.begin(), c.end(), comp);
-            }
-
-            template<class... Args>
-            void emplace(Args&&... args)
-            {
-                c.emplace_back(forward<Args>(args)...);
-                push_heap(c.begin(), c.end(), comp);
-            }
-
-            void pop()
-            {
-                pop_heap(c.begin(), c.end(), comp);
-                c.pop_back();
-            }
-
-            void swap(priority_queue& other)
-                noexcept(noexcept(swap(c, other.c)) && noexcept(swap(comp, other.comp)))
-            {
-                std::swap(c, other.c);
-                std::swap(comp, other.comp);
-            }
-    };
-
-    template<class T, class Container, class Compare, class Alloc>
-    struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
-        : uses_allocator<Container, Alloc>
-    { /* DUMMY BODY */ };
-
-    template<class T, class Container>
-    bool operator==(const queue<T, Container>& lhs,
-                    const queue<T, Container>& rhs)
-    {
-        return lhs.c == rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator<(const queue<T, Container>& lhs,
-                   const queue<T, Container>& rhs)
-    {
-        return lhs.c < rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator!=(const queue<T, Container>& lhs,
-                    const queue<T, Container>& rhs)
-    {
-        return lhs.c != rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator>(const queue<T, Container>& lhs,
-                   const queue<T, Container>& rhs)
-    {
-        return lhs.c > rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator>=(const queue<T, Container>& lhs,
-                    const queue<T, Container>& rhs)
-    {
-        return lhs.c >= rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator<=(const queue<T, Container>& lhs,
-                    const queue<T, Container>& rhs)
-    {
-        return lhs.c <= rhs.c;
-    }
-
-    template<class T, class Container>
-    void swap(queue<T, Container>& lhs, queue<T, Container>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class T, class Container, class Compare>
-    void swap(priority_queue<T, Container, Compare>& lhs,
-              priority_queue<T, Container, Compare>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/random.hpp
===================================================================
--- uspace/lib/cpp/include/impl/random.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1583 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_RANDOM
-#define LIBCPP_RANDOM
-
-#include <cstdint>
-#include <cstdlib>
-#include <ctime>
-#include <initializer_list>
-#include <__bits/builtins.hpp>
-#include <limits>
-#include <type_traits>
-#include <vector>
-
-/**
- * Note: Variables with one or two lettered
- *       names here are named after their counterparts in
- *       the standard. If one needs to understand their meaning,
- *       they should seek the mentioned standard section near
- *       the declaration of these variables.
- * Note: There will be a lot of mathematical expressions in this header.
- *       All of these are taken directly from the standard's requirements
- *       and as such won't be commented here, check the appropriate
- *       sections if you need explanation of these forumulae.
- */
-
-namespace std
-{
-    namespace aux
-    {
-        /**
-         * This is the minimum requirement imposed by the
-         * standard for a type to qualify as a seed sequence
-         * in overloading resolutions.
-         * (This is because the engines have constructors
-         * that accept sequence and seed and without this
-         * minimal requirements overload resolution would fail.)
-         */
-        template<class Sequence, class ResultType>
-        struct is_seed_sequence
-            : aux::value_is<
-            bool, !is_convertible_v<Sequence, ResultType>
-        >
-        { /* DUMMY BODY */ };
-
-        template<class T, class Engine>
-        inline constexpr bool is_seed_sequence_v = is_seed_sequence<T, Engine>::value;
-    }
-
-    /**
-     * 26.5.3.1, class template linear_congruential_engine:
-     */
-
-    template<class UIntType, UIntType a, UIntType c, UIntType m>
-    class linear_congruential_engine
-    {
-        static_assert(m == 0 || (a < m && c < m));
-
-        public:
-            using result_type = UIntType;
-
-            static constexpr result_type multiplier = a;
-            static constexpr result_type increment = c;
-            static constexpr result_type modulus = m;
-
-            static constexpr result_type min()
-            {
-                return c == 0U ? 1U : 0U;
-            }
-
-            static constexpr result_type max()
-            {
-                return m - 1U;
-            }
-
-            static constexpr result_type default_seed = 1U;
-
-            explicit linear_congruential_engine(result_type s = default_seed)
-                : state_{}
-            {
-                seed(s);
-            }
-
-            linear_congruential_engine(const linear_congruential_engine& other)
-                : state_{other.state_}
-            { /* DUMMY BODY */ }
-
-            template<class Seq>
-            explicit linear_congruential_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : state_{}
-            {
-                seed(q);
-            }
-
-            void seed(result_type s = default_seed)
-            {
-                if (c % modulus_ == 0 && s % modulus_ == 0)
-                    state_ = 1;
-                else
-                    state_ = s % modulus_;
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                auto k = static_cast<size_t>(aux::ceil(aux::log2(modulus_) / 32));
-                auto arr = new result_type[k + 3];
-
-                q.generate(arr, arr + k + 3);
-
-                result_type s{};
-                for (size_t j = 0; j < k; ++j)
-                    s += arr[j + 3] * aux::pow2(32U * j);
-                s = s % modulus_;
-
-                if (c % modulus_ == 0 && s == 0)
-                    state_ = 1;
-                else
-                    state_ = s % modulus_;
-                delete[] arr;
-            }
-
-            result_type operator()()
-            {
-                return generate_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    transition_();
-            }
-
-            bool operator==(const linear_congruential_engine& rhs) const
-            {
-                return state_ = rhs.state_;
-            }
-
-            bool operator!=(const linear_congruential_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                os << state_;
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                result_type tmp{};
-                if (is >> tmp)
-                    state_ = tmp;
-                else
-                    is.setstate(ios::failbit);
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            result_type state_;
-
-            static constexpr result_type modulus_ =
-                (m == 0) ? (numeric_limits<result_type>::max() + 1) : m;
-
-            void transition_()
-            {
-                state_ = (a * state_ + c) % modulus_;
-            }
-
-            result_type generate_()
-            {
-                transition_();
-
-                return state_;
-            }
-    };
-
-    /**
-     * 26.5.3.2, class template mersenne_twister_engine:
-     */
-
-    template<
-        class UIntType, size_t w, size_t n, size_t m, size_t r,
-        UIntType a, size_t u, UIntType d, size_t s,
-        UIntType b, size_t t, UIntType c, size_t l, UIntType f
-    >
-    class mersenne_twister_engine
-    {
-        // TODO: fix these
-        /* static_assert(0 < m && m <= n); */
-        /* static_assert(2 * u < w); */
-        /* static_assert(r <= w && u <= w && s <= w && t <= w && l <= w); */
-        /* /1* static_assert(w <= numeric_limits<UIntType>::digits); *1/ */
-        /* static_assert(a <= (1U << w) - 1U); */
-        /* static_assert(b <= (1U << w) - 1U); */
-        /* static_assert(c <= (1U << w) - 1U); */
-        /* static_assert(d <= (1U << w) - 1U); */
-        /* static_assert(f <= (1U << w) - 1U); */
-
-        public:
-            using result_type = UIntType;
-
-            static constexpr size_t word_size = w;
-            static constexpr size_t state_size = n;
-            static constexpr size_t shift_size = m;
-            static constexpr size_t mask_bits = r;
-            static constexpr UIntType xor_mask = a;
-
-            static constexpr size_t tempering_u = u;
-            static constexpr UIntType tempering_d = d;
-            static constexpr size_t tempering_s = s;
-            static constexpr UIntType tempering_b = b;
-            static constexpr size_t tempering_t = t;
-            static constexpr UIntType tempering_c = c;
-            static constexpr size_t tempering_l = l;
-
-            static constexpr UIntType initialization_multiplier = f;
-
-            static constexpr result_type min()
-            {
-                return result_type{};
-            }
-
-            static constexpr result_type max()
-            {
-                return static_cast<result_type>(aux::pow2(w)) - 1U;
-            }
-
-            static constexpr result_type default_seed = 5489U;
-
-            explicit mersenne_twister_engine(result_type value = default_seed)
-                : state_{}, i_{}
-            {
-                seed(value);
-            }
-
-            template<class Seq>
-            explicit mersenne_twister_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : state_{}, i_{}
-            {
-                seed(q);
-            }
-
-            void seed(result_type value = default_seed)
-            {
-                state_[idx_(-n)] = value % aux::pow2u(w);;
-
-                for (long long i = 1 - n; i <= -1; ++i)
-                {
-                    state_[idx_(i)] = (f * (state_[idx_(i - 1)] ^
-                                      (state_[idx_(i - 1)] >> (w - 2))) + 1 % n) % aux::pow2u(w);
-                }
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                auto k = static_cast<size_t>(w / 32);
-                auto arr = new result_type[n * k];
-                q.generate(arr, arr + n * k);
-
-                for (long long i = -n; i <= -1; ++i)
-                {
-                    state_[idx_(i)] = result_type{};
-                    for (long long j = 0; j < k; ++j)
-                        state_[idx_(i)] += arr[k * (i + n) + j] * aux::pow2(32 * j);
-                    state_[idx_(i)] %= aux::pow2(w);
-                }
-
-                delete[] arr;
-            }
-
-            result_type operator()()
-            {
-                return generate_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    transition_();
-            }
-
-            bool operator==(const mersenne_twister_engine& rhs) const
-            {
-                if (i_ != rhs.i_)
-                    return false;
-
-                for (size_t i = 0; i < n; ++i)
-                {
-                    if (state_[i] != rhs.state_[i])
-                        return false;
-                }
-
-                return true;
-            }
-
-            bool operator!=(const mersenne_twister_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                for (size_t j = n + 1; j > 1; --j)
-                {
-                    os << state_[idx_(i_ - j - 1)];
-
-                    if (j > 2)
-                        os << os.widen(' ');
-                }
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                for (size_t j = n + 1; j > 1; --j)
-                {
-                    if (!(is >> state_[idx_(i_ - j - 1)]))
-                    {
-                        is.setstate(ios::failbit);
-                        break;
-                    }
-                }
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            result_type state_[n];
-            size_t i_;
-
-            void transition_()
-            {
-                auto mask = (result_type{1} << r) - 1;
-                auto y = (state_[idx_(i_ - n)] & ~mask) | (state_[idx_(i_ + 1 - n)] & mask);
-                auto alpha = a * (y & 1);
-                state_[i_] = state_[idx_(i_ + m - n)] ^ (y >> 1) ^ alpha;
-
-                i_ = (i_ + 1) % n;
-            }
-
-            result_type generate_()
-            {
-                auto z1 = state_[i_] ^ ((state_[i_] >> u) & d);
-                auto z2 = z1 ^ (lshift_(z1, s) & b);
-                auto z3 = z2 ^ (lshift_(z2, t) & c);
-                auto z4 = z3 ^ (z3 >> l);
-
-                transition_();
-
-                return z4;
-            }
-
-            size_t idx_(size_t idx) const
-            {
-                return idx % n;
-            }
-
-            result_type lshift_(result_type val, size_t count)
-            {
-                return (val << count) % aux::pow2u(w);
-            }
-    };
-
-    /**
-     * 26.5.3.3, class template subtract_with_carry_engine:
-     */
-
-    template<class UIntType, size_t w, size_t s, size_t r>
-    class subtract_with_carry_engine
-    {
-        // TODO: fix these
-        /* static_assert(0U < s); */
-        /* static_assert(s < r); */
-        /* static_assert(0U < w); */
-        /* static_assert(w <= numeric_limits<UIntType>::digits); */
-
-        public:
-            using result_type = UIntType;
-
-            static constexpr size_t word_size = w;
-            static constexpr size_t short_lag = s;
-            static constexpr size_t long_lag = r;
-
-            static constexpr result_type min()
-            {
-                return result_type{};
-            }
-
-            static constexpr result_type max()
-            {
-                return m_ - 1;
-            }
-
-            static constexpr result_type default_seed = 19780503U;
-
-            explicit subtract_with_carry_engine(result_type value = default_seed)
-                : state_{}, i_{}, carry_{}
-            {
-                seed(value);
-            }
-
-            template<class Seq>
-            explicit subtract_with_carry_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : state_{}, i_{}, carry_{}
-            {
-                seed(q);
-            }
-
-            void seed(result_type value = default_seed)
-            {
-                linear_congruential_engine<
-                    result_type, 40014U, 0U, 2147483563U
-                > e{value == 0U ? default_seed : value};
-
-                auto n = aux::ceil(w / 32.0);
-                auto z = new result_type[n];
-
-                for (long long i = -r; i <= -1; ++i)
-                {
-                    for (size_t i = 0; i < n; ++i)
-                        z[i] = e() % aux::pow2u(32);
-
-                    state_[idx_(i)] = result_type{};
-                    for (size_t j = 0; j < n; ++j)
-                        state_[idx_(i)] += z[j] * aux::pow2u(32 * j);
-                    state_[idx_(i)] %= m_;
-                }
-
-                if (state_[idx_(-1)] == 0)
-                    carry_ = 1;
-                else
-                    carry_ = 0;
-
-                delete[] z;
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                auto k = aux::ceil(w / 32.0);
-                auto arr = new result_type[r * k];
-
-                q.generate(arr, arr + r * k);
-
-                for (long long i = -r; i <= -1; ++i)
-                {
-                    state_[idx_(i)] = result_type{};
-                    for (long long j = 0; j < k; ++j)
-                        state_[idx_(i)] += arr[k * (i + r) + j] * aux::pow2(32 * j);
-                    state_[idx_(i)] %= m_;
-                }
-
-                delete[] arr;
-
-                if (state_[idx_(-1)] == 0)
-                    carry_ = 1;
-                else
-                    carry_ = 0;
-            }
-
-            result_type operator()()
-            {
-                return generate_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    transition_();
-            }
-
-            bool operator==(const subtract_with_carry_engine& rhs) const
-            {
-                if (i_ != rhs.i_)
-                    return false;
-
-                for (size_t i = 0; i < r; ++i)
-                {
-                    if (state_[i] != rhs.state_[i])
-                        return false;
-                }
-
-                return true;
-            }
-
-            bool operator!=(const subtract_with_carry_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                for (size_t j = r + 1; j > 1; --j)
-                {
-                    os << state_[idx_(i_ - j - 1)];
-                    os << os.widen(' ');
-                }
-
-                os << carry_;
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                for (size_t j = r + 1; j > 1; --j)
-                {
-                    if (!(is >> state_[idx_(i_ - j - 1)]))
-                    {
-                        is.setstate(ios::failbit);
-                        break;
-                    }
-                }
-
-                if (!(is >> carry_))
-                    is.setstate(ios::failbit);
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            result_type state_[r];
-            size_t i_;
-            uint8_t carry_;
-
-            static constexpr result_type m_ = aux::pow2u(w);
-
-            auto transition_()
-            {
-                auto y = static_cast<int64_t>(state_[idx_(i_ - s)]) - state_[idx_(i_ - r)] - carry_;
-                state_[i_] = y % m_;
-
-                i_ = (i_ + 1) % r;
-
-                return static_cast<result_type>(y % m_);
-            }
-
-            result_type generate_()
-            {
-                return transition_();
-            }
-
-            size_t idx_(size_t idx) const
-            {
-                return idx % r;
-            }
-    };
-
-    /**
-     * 26.5.4.2, class template discard_block_engine:
-     */
-
-    template<class Engine, size_t p, size_t r>
-    class discard_block_engine
-    {
-        static_assert(0 < r);
-        static_assert(r <= p);
-
-        public:
-            using result_type = typename Engine::result_type;
-
-            static constexpr size_t block_size = p;
-            static constexpr size_t used_block = r;
-
-            static constexpr result_type min()
-            {
-                return Engine::min();
-            }
-
-            static constexpr result_type max()
-            {
-                return Engine::max();
-            }
-
-            discard_block_engine()
-                : engine_{}, n_{}
-            { /* DUMMY BODY */ }
-
-            explicit discard_block_engine(const Engine& e)
-                : engine_{e}, n_{}
-            { /* DUMMY BODY */ }
-
-            explicit discard_block_engine(Engine&& e)
-                : engine_{move(e)}, n_{}
-            { /* DUMMY BODY */ }
-
-            explicit discard_block_engine(result_type s)
-                : engine_{s}, n_{}
-            { /* DUMMY BODY */ }
-
-            template<class Seq>
-            explicit discard_block_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : engine_{q}, n_{}
-            { /* DUMMY BODY */ }
-
-            void seed()
-            {
-                engine_.seed();
-            }
-
-            void seed(result_type s)
-            {
-                engine_.seed(s);
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                engine_.seed(q);
-            }
-
-            result_type operator()()
-            {
-                if (n_ > static_cast<int>(r))
-                {
-                    auto count = p - r;
-                    for (size_t i = 0; i < count; ++i)
-                        engine_();
-                    n_ = 0;
-                }
-                ++n_;
-
-                return engine_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    operator()(); // We need to discard our (), not engine's.
-            }
-
-            const Engine& base() const noexcept
-            {
-                return engine_;
-            }
-
-            bool operator==(const discard_block_engine& rhs) const
-            {
-                return engine_ == rhs.engine_ && n_ == rhs.n_;
-            }
-
-            bool operator!=(const discard_block_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                os << n_ << os.widen(' ') << engine_;
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                if (!(is >> n_) || !(is >> engine_))
-                    is.setstate(ios::failbit);
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            Engine engine_;
-            int n_;
-    };
-
-    /**
-     * 26.5.4.3, class template independent_bits_engine:
-     */
-
-    template<class Engine, size_t w, class UIntType>
-    class independent_bits_engine
-    {
-        static_assert(0U < w);
-        /* static_assert(w <= numeric_limits<result_type>::digits); */
-
-        public:
-            using result_type = UIntType;
-
-            static constexpr result_type min()
-            {
-                return result_type{};
-            }
-
-            static constexpr result_type max()
-            {
-                return aux::pow2u(w) - 1;
-            }
-
-            independent_bits_engine()
-                : engine_{}
-            { /* DUMMY BODY */ }
-
-            explicit independent_bits_engine(const Engine& e)
-                : engine_{e}
-            { /* DUMMY BODY */ }
-
-            explicit independent_bits_engine(Engine&& e)
-                : engine_{move(e)}
-            { /* DUMMY BODY */ }
-
-            explicit independent_bits_engine(result_type s)
-                : engine_{s}
-            { /* DUMMY BODY */ }
-
-            template<class Seq>
-            explicit independent_bits_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : engine_{q}
-            { /* DUMMY BODY */ }
-
-            void seed()
-            {
-                engine_.seed();
-            }
-
-            void seed(result_type s)
-            {
-                engine_.seed(s);
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                engine_.seed(q);
-            }
-
-            result_type operator()()
-            {
-                /* auto r = engine_.max() - engine_.min() + 1; */
-                /* auto m = aux::floor(aux::log2(r)); */
-                // TODO:
-
-                return engine_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    operator()();
-            }
-
-            const Engine& base() const noexcept
-            {
-                return engine_;
-            }
-
-            bool operator==(const independent_bits_engine& rhs) const
-            {
-                return engine_ == rhs.engine_;
-            }
-
-            bool operator!=(const independent_bits_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                return os << engine_;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                return is >> engine_;
-            }
-
-        private:
-            Engine engine_;
-    };
-
-    /**
-     * 26.5.4.4, class template shiffle_order_engine:
-     */
-
-    template<class Engine, size_t k>
-    class shuffle_order_engine
-    {
-        static_assert(0U < k);
-
-        public:
-            using result_type = typename Engine::result_type;
-
-            static constexpr size_t table_size = k;
-
-            static constexpr result_type min()
-            {
-                return Engine::min();
-            }
-
-            static constexpr result_type max()
-            {
-                return Engine::max();
-            }
-
-            shuffle_order_engine()
-                : engine_{}
-            { /* DUMMY BODY */ }
-
-            explicit shuffle_order_engine(const Engine& e)
-                : engine_{e}
-            { /* DUMMY BODY */ }
-
-            explicit shuffle_order_engine(Engine&& e)
-                : engine_{move(e)}
-            { /* DUMMY BODY */ }
-
-            explicit shuffle_order_engine(result_type s)
-                : engine_{s}
-            { /* DUMMY BODY */ }
-
-            template<class Seq>
-            explicit shuffle_order_engine(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-                : engine_{q}
-            { /* DUMMY BODY */ }
-
-            void seed()
-            {
-                engine_.seed();
-            }
-
-            void seed(result_type s)
-            {
-                engine_.seed(s);
-            }
-
-            template<class Seq>
-            void seed(
-                enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
-            )
-            {
-                engine_.seed(q);
-            }
-
-            result_type operator()()
-            {
-                // TODO:
-
-                return engine_();
-            }
-
-            void discard(unsigned long long z)
-            {
-                for (unsigned long long i = 0ULL; i < z; ++i)
-                    operator()();
-            }
-
-            const Engine& base() const noexcept
-            {
-                return engine_;
-            }
-
-            bool operator==(const shuffle_order_engine& rhs) const
-            {
-                return engine_ == rhs.engine_;
-            }
-
-            bool operator!=(const shuffle_order_engine& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                return os << engine_;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                return is >> engine_;
-            }
-
-        private:
-            Engine engine_;
-            result_type y_;
-            result_type table_[k];
-    };
-
-    /**
-     * 26.5.5, engines and engine adaptors with predefined
-     * parameters:
-     * TODO: check their requirements for testing
-     */
-
-    using minstd_rand0  = linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>;
-    using minstd_rand   = linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>;
-    using mt19937       = mersenne_twister_engine<
-        uint_fast32_t, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7,
-        0x9d2c5680, 15, 0xefc60000, 18, 1812433253
-    >;
-    using mt19937_64    = mersenne_twister_engine<
-        uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9, 29,
-        0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000,
-        43, 6364136223846793005
-    >;
-    using ranlux24_base = subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;
-    using ranlux48_base = subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;
-    using ranlux24      = discard_block_engine<ranlux24_base, 223, 23>;
-    using ranlux48      = discard_block_engine<ranlux48_base, 389, 11>;
-    using knuth_b       = shuffle_order_engine<minstd_rand0, 256>;
-
-    using default_random_engine = minstd_rand0;
-
-    /**
-     * 26.5.6, class random_device:
-     */
-
-    class random_device
-    {
-        using result_type = unsigned int;
-
-        static constexpr result_type min()
-        {
-            return numeric_limits<result_type>::min();
-        }
-
-        static constexpr result_type max()
-        {
-            return numeric_limits<result_type>::max();
-        }
-
-        explicit random_device(const string& token = "")
-        {
-            /**
-             * Note: token can be used to choose between
-             *       random generators, but HelenOS only
-             *       has one :/
-             *       Also note that it is implementation
-             *       defined how this class generates
-             *       random numbers and I decided to use
-             *       time seeding with C stdlib random,
-             *       - feel free to change it if you know
-             *       something better.
-             */
-            hel::srandom(hel::time(nullptr));
-        }
-
-        result_type operator()()
-        {
-            return hel::random();
-        }
-
-        double entropy() const noexcept
-        {
-            return 0.0;
-        }
-
-        random_device(const random_device&) = delete;
-        random_device& operator=(const random_device&) = delete;
-    };
-
-    /**
-     * 26.5.7.1, class seed_seq:
-     */
-
-    class seed_seq
-    {
-        public:
-            using result_type = uint_least32_t;
-
-            seed_seq()
-                : vec_{}
-            { /* DUMMY BODY */ }
-
-            template<class T>
-            seed_seq(initializer_list<T> init)
-                : seed_seq(init.begin(), init.end())
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            seed_seq(InputIterator first, InputIterator last)
-                : vec_{}
-            {
-                while (first != last)
-                    vec_.push_back((*first++) % aux::pow2u(32));
-            }
-
-            template<class RandomAccessGenerator>
-            void generate(RandomAccessGenerator first,
-                          RandomAccessGenerator last)
-            {
-                if (first == last)
-                    return;
-
-                auto s = vec_.size();
-                size_t n = last - first;
-                result_type t = (n >= 623) ? 11 : (n >= 68) ? 7 : (n >= 39) ? 5 : (n >= 7) ? 3 : (n - 1) / 2;
-                result_type p = (n - t) / 2;
-                result_type q = p + t;
-
-                auto current = first;
-                while (current != last)
-                    *current++ = 0x8b8b8b8b;
-
-                auto m = (s + 1 > n) ? (s + 1) : n;
-                decltype(m) k{};
-                for (; k < m; ++k)
-                {
-                    auto r1 = 1664525 * t_(first[k % n] ^ first[(k + p) % n] ^ first[(k - 1) % n]);
-                    auto r2 = r1;
-
-                    if (k == 0)
-                        r2 += s;
-                    else if (k > 0 && k <= s)
-                        r2 += (k % n) + vec_[(k - 1) % n];
-                    else if (s < k)
-                        r2 += (k % n);
-
-                    first[(k + p) % n] += r1;
-                    first[(k + q) % n] += r2;
-                    first[k % n] = r2;
-                }
-
-                for (; k < m + n - 1; ++k)
-                {
-                    auto r3 = 1566083941 * t_(first[k % n] + first[(k + p) % n] + first[(k - 1) % n]);
-                    auto r4 = r3 - (k % n);
-
-                    first[(k + p) % n] ^= r3;
-                    first[(k + q) % n] ^= r4;
-                    first[k % n] = r4;
-                }
-            }
-
-            size_t size() const
-            {
-                return vec_.size();
-            }
-
-            template<class OutputIterator>
-            void param(OutputIterator dest) const
-            {
-                for (const auto& x: vec_)
-                    *dest++ = x;
-            }
-
-            seed_seq(const seed_seq&) = delete;
-            seed_seq& operator=(const seed_seq&) = delete;
-
-        private:
-            vector<result_type> vec_;
-
-            result_type t_(result_type val) const
-            {
-                return val ^ (val >> 27);
-            }
-    };
-
-    /**
-     * 26.5.7.2, function template generate_canonical:
-     */
-
-    template<class RealType, size_t bits, class URNG>
-    RealType generate_canonical(URNG& g)
-    {
-        auto b = (bits < numeric_limits<RealType>::digits) ? bits : numeric_limits<RealType>::digits;
-        RealType r = g.max() - g.min() + 1;
-        size_t tmp = aux::ceil(b / aux::log2(r));
-        size_t k = (1U < tmp) ? tmp : 1U;
-
-        RealType s{};
-        for (size_t i = 0; i < k; ++i)
-            s += (g() - g.min()) * aux::pow(r, i);
-
-        return s / aux::pow(r, k);
-    }
-
-    /**
-     * 26.5.8.2.1, class template uniform_int_distribution:
-     */
-
-    template<class IntType = int>
-    class uniform_int_distribution
-    {
-        public:
-            using result_type = IntType;
-            using param_type  = pair<result_type, result_type>;
-
-            explicit uniform_int_distribution(result_type a = 0,
-                                              result_type b = numeric_limits<result_type>::max())
-                : a_{a}, b_{b}
-            { /* DUMMY BODY */ }
-
-            explicit uniform_int_distribution(const param_type& p)
-                : a_{p.first}, b_{p.second}
-            { /* DUMMY BODY */ }
-
-            void reset()
-            { /* DUMMY BODY */ }
-
-            template<class URNG>
-            result_type operator()(URNG& g)
-            {
-                auto range = b_ - a_ + 1;
-
-                return g() % range + a_;
-            }
-
-            template<class URNG>
-            result_type operator()(URNG& g, const param_type& p)
-            {
-                auto range = p.second - p.first + 1;
-
-                return g() % range + p.first;
-            }
-
-            result_type a() const
-            {
-                return a_;
-            }
-
-            result_type b() const
-            {
-                return b_;
-            }
-
-            param_type param() const
-            {
-                return param_type{a_, b_};
-            }
-
-            void param(const param_type& p)
-            {
-                a_ = p.first;
-                b_ = p.second;
-            }
-
-            result_type min() const
-            {
-                return a_;
-            }
-
-            result_type max() const
-            {
-                return b_;
-            }
-
-            bool operator==(const uniform_int_distribution& rhs) const
-            {
-                return a_ == rhs.a_ && b_ == rhs.b_;
-            }
-
-            bool operator!=(const uniform_int_distribution& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                os << a_ << os.widen(' ') << b_;
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                if (!(is >> a_) || !(is >> b_))
-                    is.setstate(ios::failbit);
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            result_type a_;
-            result_type b_;
-    };
-
-    /**
-     * 26.5.8.2.2, class template uniform_real_distribution:
-     */
-
-    template<class RealType = double>
-    class uniform_real_distribution
-    {
-        public:
-            using result_type = RealType;
-            using param_type  = pair<result_type, result_type>;
-
-            explicit uniform_real_distribution(result_type a = 0.0,
-                                               result_type b = 1.0)
-                : a_{a}, b_{b}
-            { /* DUMMY BODY */ }
-
-            explicit uniform_real_distribution(const param_type& p)
-                : a_{p.first}, b_{p.second}
-            { /* DUMMY BODY */ }
-
-            void reset()
-            { /* DUMMY BODY */ }
-
-            template<class URNG>
-            result_type operator()(URNG& g)
-            {
-                auto range = b_ - a_ + 1;
-
-                return generate_canonical<
-                    result_type, numeric_limits<result_type>::digits
-                >(g) * range + a_;
-            }
-
-            template<class URNG>
-            result_type operator()(URNG& g, const param_type& p)
-            {
-                auto range = p.second - p.first + 1;
-
-                return generate_canonical<
-                    result_type, numeric_limits<result_type>::digits
-                >(g) * range + p.first;
-            }
-
-            result_type a() const
-            {
-                return a_;
-            }
-
-            result_type b() const
-            {
-                return b_;
-            }
-
-            param_type param() const
-            {
-                return param_type{a_, b_};
-            }
-
-            void param(const param_type& p)
-            {
-                a_ = p.first;
-                b_ = p.second;
-            }
-
-            result_type min() const
-            {
-                return a_;
-            }
-
-            result_type max() const
-            {
-                return b_;
-            }
-
-            bool operator==(const uniform_real_distribution& rhs) const
-            {
-                return a_ == rhs.a_ && b_ == rhs.b_;
-            }
-
-            bool operator!=(const uniform_real_distribution& rhs) const
-            {
-                return !(*this == rhs);
-            }
-
-            // TODO: ostream/istream operators can't be members
-            template<class Char, class Traits>
-            basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const
-            {
-                auto flags = os.flags();
-                os.flags(ios_base::dec | ios_base::left);
-
-                os << a_ << os.widen(' ') << b_;
-
-                os.flags(flags);
-                return os;
-            }
-
-            template<class Char, class Traits>
-            basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const
-            {
-                auto flags = is.flags();
-                is.flags(ios_base::dec);
-
-                if (!(is >> a_) || !(is >> b_))
-                    is.setstate(ios::failbit);
-
-                is.flags(flags);
-                return is;
-            }
-
-        private:
-            result_type a_;
-            result_type b_;
-    };
-
-    /**
-     * 26.5.8.3.1, class bernoulli_distribution:
-     */
-
-    class bernoulli_distribution
-    {
-        public:
-            using result_type = bool;
-            using param_type  = float;
-
-            explicit bernoulli_distribution(double prob = 0.5)
-                : prob_{static_cast<float>(prob)}
-            { /* DUMMY BODY */ }
-
-            explicit bernoulli_distribution(const param_type& p)
-                : prob_{p}
-            { /* DUMMY BODY */ }
-
-            void reset()
-            { /* DUMMY BODY */ }
-
-            template<class URNG>
-            result_type operator()(URNG& g)
-            {
-                uniform_real_distribution<float> dist{};
-
-                return dist(g) < prob_;
-            }
-
-            template<class URNG>
-            result_type operator()(const param_type& p)
-            {
-                uniform_real_distribution<float> dist{};
-
-                return dist(p) < prob_;
-            }
-
-            double p() const
-            {
-                return prob_;
-            }
-
-            param_type param() const
-            {
-                return prob_;
-            }
-
-            void param(const param_type& p)
-            {
-                prob_ = p;
-            }
-
-            result_type min() const
-            {
-                return false;
-            }
-
-            result_type max() const
-            {
-                return true;
-            }
-
-        private:
-            /**
-             * Note: We use float because we do not
-             *       have the macro DBL_MANT_DIGITS
-             *       for generate_cannonical.
-             */
-            float prob_;
-    };
-
-    // TODO: complete the rest of the distributions
-
-    /**
-     * 26.5.8.3.2, class template binomial_distribution:
-     */
-
-    template<class IntType = int>
-    class binomial_distribution;
-
-    /**
-     * 26.5.8.3.3, class template geometric_distribution:
-     */
-
-    template<class IntType = int>
-    class geometric_distribution;
-
-    /**
-     * 26.5.8.3.4, class template negative_binomial_distribution:
-     */
-
-    template<class IntType = int>
-    class negative_binomial_distribution;
-
-    /**
-     * 26.5.8.4.1, class template poisson_distribution:
-     */
-
-    template<class IntType = int>
-    class poisson_distribution;
-
-    /**
-     * 26.5.8.4.2, class template exponential_distribution:
-     */
-
-    template<class RealType = double>
-    class exponential_distribution;
-
-    /**
-     * 26.5.8.4.3, class template gamma_distribution:
-     */
-
-    template<class RealType = double>
-    class gamma_distribution;
-
-    /**
-     * 26.5.8.4.4, class template weibull_distribution:
-     */
-
-    template<class RealType = double>
-    class weibull_distribution;
-
-    /**
-     * 26.5.8.4.5, class template extreme_value_distribution:
-     */
-
-    template<class RealType = double>
-    class extreme_value_distribution;
-
-    /**
-     * 26.5.8.5.1, class template normal_distribution:
-     */
-
-    template<class RealType = double>
-    class normal_distribution;
-
-    /**
-     * 26.5.8.5.2, class template lognormal_distribution:
-     */
-
-    template<class RealType = double>
-    class lognormal_distribution;
-
-    /**
-     * 26.5.8.5.3, class template chi_squared_distribution:
-     */
-
-    template<class RealType = double>
-    class chi_squared_distribution;
-
-    /**
-     * 26.5.8.5.4, class template cauchy_distribution:
-     */
-
-    template<class RealType = double>
-    class cauchy_distribution;
-
-    /**
-     * 26.5.8.5.5, class template fisher_f_distribution:
-     */
-
-    template<class RealType = double>
-    class fisher_f_distribution;
-
-    /**
-     * 26.5.8.5.6, class template student_t_distribution:
-     */
-
-    template<class RealType = double>
-    class student_t_distribution;
-
-    /**
-     * 26.5.8.6.1, class template discrete_distribution:
-     */
-
-    template<class IntType = int>
-    class discrete_distribution;
-
-    /**
-     * 26.5.8.6.2, class template piecewise_constant_distribution:
-     */
-
-    template<class RealType = double>
-    class piecewise_constant_distribution;
-
-    /**
-     * 26.5.8.6.3, class template piecewise_linear_distribution:
-     */
-
-    template<class RealType = double>
-    class piecewise_linear_distribution;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/ratio.hpp
===================================================================
--- uspace/lib/cpp/include/impl/ratio.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,207 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_RATIO
-#define LIBCPP_RATIO
-
-#include <cstdint>
-#include <type_traits>
-
-namespace std
-{
-    namespace aux
-    {
-        template<intmax_t A, intmax_t B>
-        struct gcd
-        {
-            static constexpr intmax_t value = gcd<B, A % B>::value;
-        };
-
-        template<intmax_t A>
-        struct gcd<A, 0>
-        {
-            static constexpr intmax_t value = A;
-        };
-
-        template<intmax_t A, intmax_t B>
-        inline constexpr intmax_t gcd_v = gcd<A, B>::value;
-
-        template<intmax_t A>
-        struct abs
-        {
-            static constexpr intmax_t value = (A > 0 ? A : -A);
-        };
-
-        template<intmax_t A>
-        inline constexpr intmax_t abs_v = abs<A>::value;
-
-        template<intmax_t A>
-        struct sign
-        {
-            static constexpr intmax_t value = (A == 0 ? 0: (A > 0 ? 1 : -1));
-        };
-
-        template<intmax_t A>
-        inline constexpr intmax_t sign_v = sign<A>::value;
-
-        // Not used here, but in <chrono>, better to keep them together.
-        template<intmax_t A, intmax_t B>
-        struct lcm
-        {
-            static constexpr intmax_t value = abs_v<A * B> / gcd_v<A, B>;
-        };
-
-        template<intmax_t A, intmax_t B>
-        inline constexpr intmax_t lcm_v = lcm<A, B>::value;
-    }
-
-    /**
-     * 20.11.3, class template ratio:
-     */
-
-    template<intmax_t N, intmax_t D = 1>
-    class ratio
-    {
-        public:
-            static_assert(D != 0, "ratio with denominator == 0");
-
-            static constexpr intmax_t num = aux::sign_v<N> * aux::sign_v<D>
-                                            * aux::abs_v<N> / aux::gcd_v<N, D>;
-
-            static constexpr intmax_t den = aux::abs_v<D> / aux::gcd_v<N, D>;
-
-            using type = ratio<num, den>;
-    };
-
-    /**
-     * 20.11.4, ratio arithmetic:
-     */
-
-    template<class R1, class R2>
-    using ratio_add = typename ratio<
-        R1::num * R2::den + R2::num * R1::den,
-        R1::den * R2::den
-    >::type;
-
-    template<class R1, class R2>
-    using ratio_subtract = typename ratio<
-        R1::num * R2::den - R2::num * R1::den,
-        R1::den * R2::den
-    >::type;
-
-    template<class R1, class R2>
-    using ratio_multiply = typename ratio<
-        R1::num * R2::num,
-        R1::den * R2::den
-    >::type;
-
-    template<class R1, class R2>
-    using ratio_divide = typename ratio<
-        R1::num * R2::den,
-        R1::den * R2::num
-    >::type;
-
-    /**
-     * 20.11.5, ratio comparison:
-     */
-
-    template<class R1, class R2>
-    struct ratio_equal: integral_constant<
-        bool, (R1::num == R2::num) && (R1::den == R2::den)
-    >
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
-
-    template<class R1, class R2>
-    struct ratio_not_equal: integral_constant<bool, !ratio_equal<R1, R2>::value>
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
-
-    template<class R1, class R2>
-    struct ratio_less: integral_constant<
-        bool, R1::num * R2::den < R2::num * R1::den
-    >
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
-
-    template<class R1, class R2>
-    struct ratio_less_equal: integral_constant<bool, !ratio_less<R2, R1>::value>
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
-
-    template<class R1, class R2>
-    struct ratio_greater: integral_constant<bool, ratio_less<R2, R1>::value>
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
-
-    template<class R1, class R2>
-    struct ratio_greater_equal: integral_constant<bool, !ratio_less<R1, R2>::value>
-    { /* DUMMY BODY */ };
-
-    template<class R1, class R2>
-    inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
-
-    /**
-     * 20.11.6, convenience SI typedefs:
-     */
-
-    // TODO: yocto/zepto and yotta/zetta should not be defined if intmax_t is too small
-
-    /* using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; */
-    /* using zepto = ratio<1,     1'000'000'000'000'000'000'000>; */
-    using atto  = ratio<1,         1'000'000'000'000'000'000>;
-    using femto = ratio<1,             1'000'000'000'000'000>;
-    using pico  = ratio<1,                 1'000'000'000'000>;
-    using nano  = ratio<1,                     1'000'000'000>;
-    using micro = ratio<1,                         1'000'000>;
-    using milli = ratio<1,                             1'000>;
-    using centi = ratio<1,                               100>;
-    using deci  = ratio<1,                                10>;
-    using deca  = ratio<                               10, 1>;
-    using hecto = ratio<                              100, 1>;
-    using kilo  = ratio<                            1'000, 1>;
-    using mega  = ratio<                        1'000'000, 1>;
-    using giga  = ratio<                    1'000'000'000, 1>;
-    using tera  = ratio<                1'000'000'000'000, 1>;
-    using peta  = ratio<            1'000'000'000'000'000, 1>;
-    using exa   = ratio<        1'000'000'000'000'000'000, 1>;
-    /* using zetta = ratio<    1'000'000'000'000'000'000'000, 1>; */
-    /* using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; */
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/regex.hpp
===================================================================
--- uspace/lib/cpp/include/impl/regex.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_REGEX
-#define LIBCPP_REGEX
-
-#error "<regex> is not implemented"
-
-#endif
Index: uspace/lib/cpp/include/impl/scoped_allocator.hpp
===================================================================
--- uspace/lib/cpp/include/impl/scoped_allocator.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_SCOPED_ALLOCATOR
-#define LIBCPP_SCOPED_ALLOCATOR
-
-#error "<scoped_allocator> is not implemented"
-
-#endif
Index: uspace/lib/cpp/include/impl/set.hpp
===================================================================
--- uspace/lib/cpp/include/impl/set.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1003 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_SET
-#define LIBCPP_SET
-
-#include <functional>
-#include <__bits/rbtree.hpp>
-#include <iterator>
-#include <memory>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 23.4.6, class template set:
-     */
-
-    template<
-        class Key,
-        class Compare = less<Key>,
-        class Alloc = allocator<Key>
-    >
-    class set
-    {
-        public:
-            using key_type        = Key;
-            using value_type      = Key;
-            using key_compare     = Compare;
-            using value_compare   = Compare;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using node_type = aux::rbtree_single_node<value_type>;
-
-            /**
-             * Note: Both the iterator and const_iterator (and their local variants)
-             *       types are constant iterators, the standard does not require them
-             *       to be the same type, but why not? :)
-             */
-            using iterator             = aux::rbtree_const_iterator<
-                value_type, const_reference, const_pointer, size_type, node_type
-            >;
-            using const_iterator       = iterator;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            set()
-                : set{key_compare{}}
-            { /* DUMMY BODY */ }
-
-            explicit set(const key_compare& comp,
-                         const allocator_type& alloc = allocator_type{})
-                : tree_{comp}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            set(InputIterator first, InputIterator last,
-                const key_compare& comp = key_compare{},
-                const allocator_type& alloc = allocator_type{})
-                : set{comp, alloc}
-            {
-                insert(first, last);
-            }
-
-            set(const set& other)
-                : set{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            set(set&& other)
-                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit set(const allocator_type& alloc)
-                : tree_{}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            set(const set& other, const allocator_type& alloc)
-                : tree_{other.tree_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            set(set&& other, const allocator_type& alloc)
-                : tree_{move(other.tree_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            set(initializer_list<value_type> init,
-                const key_compare& comp = key_compare{},
-                const allocator_type& alloc = allocator_type{})
-                : set{comp, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class InputIterator>
-            set(InputIterator first, InputIterator last,
-                const allocator_type& alloc)
-                : set{first, last, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            set(initializer_list<value_type> init,
-                const allocator_type& alloc)
-                : set{init, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~set()
-            { /* DUMMY BODY */ }
-
-            set& operator=(const set& other)
-            {
-                tree_ = other.tree_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            set& operator=(set&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<key_compare>::value)
-            {
-                tree_ = move(other.tree_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            set& operator=(initializer_list<value_type>& init)
-            {
-                tree_.clear();
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return tree_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return tree_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return tree_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return tree_.end();
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return tree_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return tree_.cend();
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return tree_.crbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return tree_.crend();
-            }
-
-            bool empty() const noexcept
-            {
-                return tree_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return tree_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return tree_.max_size(allocator_);
-            }
-
-            template<class... Args>
-            pair<iterator, bool> emplace(Args&&... args)
-            {
-                return tree_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...).first;
-            }
-
-            pair<iterator, bool> insert(const value_type& val)
-            {
-                return tree_.insert(val);
-            }
-
-            pair<iterator, bool> insert(value_type&& val)
-            {
-                return tree_.insert(forward<value_type>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val).first;
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val)).first;
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return tree_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return tree_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    first.node(), first.end()
-                };
-            }
-
-            void swap(set& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
-            {
-                tree_.swap(other.tree_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            void clear() noexcept
-            {
-                tree_.clear();
-            }
-
-            key_compare key_comp() const
-            {
-                return tree_.key_comp();
-            }
-
-            value_compare value_comp() const
-            {
-                return tree_.value_comp();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return tree_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            const_iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return tree_.count(key);
-            }
-
-            template<class K>
-            size_type count(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.count(key);
-            }
-
-            iterator lower_bound(const key_type& key)
-            {
-                return tree_.lower_bound(key);
-            }
-
-            const_iterator lower_bound(const key_type& key) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            const_iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            iterator upper_bound(const key_type& key)
-            {
-                return tree_.upper_bound(key);
-            }
-
-            const_iterator upper_bound(const key_type& key) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            const_iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return tree_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<iterator, iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<const_iterator, const_iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.equal_range(key);
-            }
-
-        private:
-            using tree_type = aux::rbtree<
-                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
-                key_compare, allocator_type, size_type,
-                iterator, const_iterator,
-                aux::rbtree_single_policy, node_type
-            >;
-
-            tree_type tree_;
-            allocator_type allocator_;
-
-            template<class K, class C, class A>
-            friend bool operator==(const set<K, C, A>&,
-                                   const set<K, C, A>&);
-    };
-
-    template<class Key, class Compare, class Allocator>
-    bool operator==(const set<Key, Compare, Allocator>& lhs,
-                    const set<Key, Compare, Allocator>& rhs)
-    {
-        return lhs.tree_.is_eq_to(rhs.tree_);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<(const set<Key, Compare, Allocator>& lhs,
-                   const set<Key, Compare, Allocator>& rhs)
-    {
-        return lexicographical_compare(
-            lhs.begin(), lhs.end(),
-            rhs.begin(), rhs.end(),
-            lhs.key_comp()
-        );
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator!=(const set<Key, Compare, Allocator>& lhs,
-                    const set<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>(const set<Key, Compare, Allocator>& lhs,
-                   const set<Key, Compare, Allocator>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>=(const set<Key, Compare, Allocator>& lhs,
-                    const set<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<=(const set<Key, Compare, Allocator>& lhs,
-                    const set<Key, Compare, Allocator>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    /**
-     * 23.4.7, class template multiset:
-     */
-
-    template<
-        class Key,
-        class Compare = less<Key>,
-        class Alloc = allocator<Key>
-    >
-    class multiset
-    {
-        public:
-            using key_type        = Key;
-            using value_type      = Key;
-            using key_compare     = Compare;
-            using value_compare   = Compare;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using node_type = aux::rbtree_multi_node<value_type>;
-
-            /**
-             * Note: Both the iterator and const_iterator types are constant
-             *       iterators, the standard does not require them
-             *       to be the same type, but why not? :)
-             */
-            using iterator             = aux::rbtree_const_iterator<
-                value_type, const_reference, const_pointer, size_type, node_type
-            >;
-            using const_iterator       = iterator;
-
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            multiset()
-                : multiset{key_compare{}}
-            { /* DUMMY BODY */ }
-
-            explicit multiset(const key_compare& comp,
-                              const allocator_type& alloc = allocator_type{})
-                : tree_{comp}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            multiset(InputIterator first, InputIterator last,
-                     const key_compare& comp = key_compare{},
-                     const allocator_type& alloc = allocator_type{})
-                : multiset{comp, alloc}
-            {
-                insert(first, last);
-            }
-
-            multiset(const multiset& other)
-                : multiset{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            multiset(multiset&& other)
-                : tree_{move(other.tree_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit multiset(const allocator_type& alloc)
-                : tree_{}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multiset(const multiset& other, const allocator_type& alloc)
-                : tree_{other.tree_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multiset(multiset&& other, const allocator_type& alloc)
-                : tree_{move(other.tree_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            multiset(initializer_list<value_type> init,
-                     const key_compare& comp = key_compare{},
-                     const allocator_type& alloc = allocator_type{})
-                : multiset{comp, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class InputIterator>
-            multiset(InputIterator first, InputIterator last,
-                     const allocator_type& alloc)
-                : multiset{first, last, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            multiset(initializer_list<value_type> init,
-                     const allocator_type& alloc)
-                : multiset{init, key_compare{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~multiset()
-            { /* DUMMY BODY */ }
-
-            multiset& operator=(const multiset& other)
-            {
-                tree_ = other.tree_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            multiset& operator=(multiset&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<key_compare>::value)
-            {
-                tree_ = move(other.tree_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            multiset& operator=(initializer_list<value_type>& init)
-            {
-                tree_.clear();
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            iterator begin() noexcept
-            {
-                return tree_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return tree_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return tree_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return tree_.end();
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return tree_.rbegin();
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return tree_.rend();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return tree_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return tree_.cend();
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return tree_.crbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return tree_.crend();
-            }
-
-            bool empty() const noexcept
-            {
-                return tree_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return tree_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return tree_.max_size(allocator_);
-            }
-
-            template<class... Args>
-            iterator emplace(Args&&... args)
-            {
-                return tree_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...);
-            }
-
-            iterator insert(const value_type& val)
-            {
-                return tree_.insert(val);
-            }
-
-            iterator insert(value_type&& val)
-            {
-                return tree_.insert(forward<value_type>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val);
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return tree_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return tree_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    first.node(), first.end()
-                };
-            }
-
-            void swap(multiset& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<key_compare>(), declval<key_compare>())))
-            {
-                tree_.swap(other.tree_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            void clear() noexcept
-            {
-                tree_.clear();
-            }
-
-            key_compare key_comp() const
-            {
-                return tree_.key_comp();
-            }
-
-            value_compare value_comp() const
-            {
-                return tree_.value_comp();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return tree_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.find(key);
-            }
-
-            template<class K>
-            const_iterator find(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return tree_.count(key);
-            }
-
-            template<class K>
-            size_type count(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.count(key);
-            }
-
-            iterator lower_bound(const key_type& key)
-            {
-                return tree_.lower_bound(key);
-            }
-
-            const_iterator lower_bound(const key_type& key) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.lower_bound(key);
-            }
-
-            template<class K>
-            const_iterator lower_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.lower_bound(key);
-            }
-
-            iterator upper_bound(const key_type& key)
-            {
-                return tree_.upper_bound(key);
-            }
-
-            const_iterator upper_bound(const key_type& key) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.upper_bound(key);
-            }
-
-            template<class K>
-            const_iterator upper_bound(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.upper_bound(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return tree_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<iterator, iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            )
-            {
-                return tree_.equal_range(key);
-            }
-
-            template<class K>
-            pair<const_iterator, const_iterator> equal_range(
-                const K& key,
-                enable_if_t<aux::is_transparent_v<key_compare>, K>* = nullptr
-            ) const
-            {
-                return tree_.equal_range(key);
-            }
-
-        private:
-            using tree_type = aux::rbtree<
-                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
-                key_compare, allocator_type, size_type,
-                iterator, const_iterator,
-                aux::rbtree_multi_policy, node_type
-            >;
-
-            tree_type tree_;
-            allocator_type allocator_;
-
-            template<class K, class C, class A>
-            friend bool operator==(const multiset<K, C, A>&,
-                                   const multiset<K, C, A>&);
-    };
-
-    template<class Key, class Compare, class Allocator>
-    bool operator==(const multiset<Key, Compare, Allocator>& lhs,
-                    const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return lhs.tree_.is_eq_to(rhs.tree_);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<(const multiset<Key, Compare, Allocator>& lhs,
-                   const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return lexicographical_compare(
-            lhs.begin(), lhs.end(),
-            rhs.begin(), rhs.end(),
-            lhs.value_comp()
-        );
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator!=(const multiset<Key, Compare, Allocator>& lhs,
-                    const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>(const multiset<Key, Compare, Allocator>& lhs,
-                   const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator>=(const multiset<Key, Compare, Allocator>& lhs,
-                    const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class Key, class Compare, class Allocator>
-    bool operator<=(const multiset<Key, Compare, Allocator>& lhs,
-                    const multiset<Key, Compare, Allocator>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/shared_mutex.hpp
===================================================================
--- uspace/lib/cpp/include/impl/shared_mutex.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,297 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_SHARED_MUTEX
-#define LIBCPP_SHARED_MUTEX
-
-#include <__bits/thread.hpp>
-#include <chrono>
-#include <mutex>
-
-namespace std
-{
-    /**
-     * 30.4.1.4.1, class shared_timed_mutex:
-     */
-
-    class shared_timed_mutex
-    {
-        public:
-            shared_timed_mutex() noexcept;
-            ~shared_timed_mutex();
-
-            shared_timed_mutex(const shared_timed_mutex&) = delete;
-            shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
-
-            void lock();
-            bool try_lock();
-            void unlock();
-
-            template<class Rep, class Period>
-            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                auto time = aux::threading::time::convert(rel_time);
-
-                return aux::threading::shared_mutex::try_lock_for(time);
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                auto dur = (abs_time - Clock::now());
-                auto time = aux::threading::time::convert(dur);
-
-                return aux::threading::shared_mutex::try_lock_for(time);
-            }
-
-            void lock_shared();
-            bool try_lock_shared();
-            void unlock_shared();
-
-            template<class Rep, class Period>
-            bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                auto time = aux::threading::time::convert(rel_time);
-
-                return aux::threading::shared_mutex::try_lock_shared_for(time);
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                auto dur = (abs_time - Clock::now());
-                auto time = aux::threading::time::convert(dur);
-
-                return aux::threading::shared_mutex::try_lock_shared_for(time);
-            }
-
-            using native_handle_type = aux::shared_mutex_t*;
-            native_handle_type native_handle();
-
-        private:
-            aux::shared_mutex_t mtx_;
-    };
-
-    /**
-     * 30.4.2.3, class template shared_lock:
-     */
-
-    template<class Mutex>
-    class shared_lock
-    {
-        public:
-            using mutex_type = Mutex;
-
-            /**
-             * 30.4.2.2.1, construction/copy/destroy:
-             */
-
-            shared_lock() noexcept
-                : mtx_{nullptr}, owns_{false}
-            { /* DUMMY BODY */ }
-
-            explicit shared_lock(mutex_type& mtx)
-                : mtx_{&mtx}, owns_{true}
-            {
-                mtx_->lock_shared();
-            }
-
-            shared_lock(mutex_type& mtx, defer_lock_t) noexcept
-                : mtx_{&mtx}, owns_{false}
-            { /* DUMMY BODY */ }
-
-            shared_lock(mutex_type& mtx, try_to_lock_t)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock_shared();
-            }
-
-            shared_lock(mutex_type& mtx, adopt_lock_t)
-                : mtx_{&mtx}, owns_{true}
-            { /* DUMMY BODY */ }
-
-            template<class Clock, class Duration>
-            shared_lock(mutex_type& mtx, const chrono::time_point<Clock, Duration>& abs_time)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock_shared_until(abs_time);
-            }
-
-            template<class Rep, class Period>
-            shared_lock(mutex_type& mtx, const chrono::duration<Rep, Period>& rel_time)
-                : mtx_{&mtx}, owns_{}
-            {
-                owns_ = mtx_->try_lock_shared_for(rel_time);
-            }
-
-            ~shared_lock()
-            {
-                if (owns_)
-                    mtx_->unlock_shared();
-            }
-
-            shared_lock(const shared_lock&) = delete;
-            shared_lock& operator=(const shared_lock&) = delete;
-
-            shared_lock(shared_lock&& other) noexcept
-                : mtx_{move(other.mtx_)}, owns_{move(other.owns_)}
-            {
-                other.mtx_ = nullptr;
-                other.owns_ = false;
-            }
-
-            shared_lock& operator=(shared_lock&& other)
-            {
-                if (owns_)
-                    mtx_->unlock_shared();
-
-                mtx_ = move(other.mtx_);
-                owns_ = move(other.owns_);
-
-                other.mtx_ = nullptr;
-                other.owns_ = false;
-            }
-
-            /**
-             * 30.4.2.2.2, locking:
-             */
-
-            void lock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                mtx_->lock_shared();
-                owns_ = true;
-            }
-
-            bool try_lock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock_shared();
-
-                return owns_;
-            }
-
-            template<class Rep, class Period>
-            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock_shared_for(rel_time);
-
-                return owns_;
-            }
-
-            template<class Clock, class Duration>
-            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if mtx_ == nullptr
-                 * throw system_error resource_deadlock_would_occur if owns_ == true
-                 */
-
-                owns_ = mtx_->try_lock_shared_until(abs_time);
-
-                return owns_;
-            }
-
-            void unlock()
-            {
-                /**
-                 * TODO:
-                 * throw system_error operation_not_permitted if owns_ == false
-                 */
-
-                mtx_->unlock_shared();
-            }
-
-            /**
-             * 30.4.2.2.3, modifiers:
-             */
-
-            void swap(shared_lock& other) noexcept
-            {
-                std::swap(mtx_, other.mtx_);
-                std::swap(owns_, other.owns_);
-            }
-
-            mutex_type* release() noexcept
-            {
-                auto ret = mtx_;
-                mtx_ = nullptr;
-                owns_ = false;
-
-                return ret;
-            }
-
-            /**
-             * 30.4.2.2.4, observers:
-             */
-
-            bool owns_lock() const noexcept
-            {
-                return owns_;
-            }
-
-            explicit operator bool() const noexcept
-            {
-                return owns_;
-            }
-
-            mutex_type* mutex() const noexcept
-            {
-                return mtx_;
-            }
-
-        private:
-            mutex_type* mtx_;
-            bool owns_;
-    };
-
-    template<class Mutex>
-    void swap(shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs) noexcept
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/sstream.hpp
===================================================================
--- uspace/lib/cpp/include/impl/sstream.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,530 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_SSTREAM
-#define LIBCPP_SSTREAM
-
-#include <ios>
-#include <iosfwd>
-#include <iostream>
-#include <streambuf>
-#include <string>
-
-namespace std
-{
-    /**
-     * 27.8.2, class template basic_stringbuf:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    class basic_stringbuf: public basic_streambuf<Char, Traits>
-    {
-        public:
-            using char_type      = Char;
-            using traits_type    = Traits;
-            using allocator_type = Allocator;
-            using int_type       = typename traits_type::int_type;
-            using pos_type       = typename traits_type::pos_type;
-            using off_type       = typename traits_type::off_type;
-
-            /**
-             * 27.8.2.1, constructors:
-             */
-
-            explicit basic_stringbuf(ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_streambuf<char_type, traits_type>(), mode_{mode}, str_{}
-            {
-                init_();
-            }
-
-            explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type> str,
-                                     ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_streambuf<char_type, traits_type>(), mode_{mode}, str_{str}
-            {
-                init_();
-            }
-
-            basic_stringbuf(const basic_stringbuf&) = delete;
-
-            basic_stringbuf(basic_stringbuf&& other)
-                : mode_{move(other.mode_)}, str_{move(other.str_)}
-            {
-                basic_streambuf<char_type, traits_type>::swap(other);
-            }
-
-            /**
-             * 27.8.2.2, assign and swap:
-             */
-
-            basic_stringbuf& operator=(const basic_stringbuf&) = delete;
-
-            basic_stringbuf& operator=(basic_stringbuf&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_stringbuf& rhs)
-            {
-                std::swap(mode_, rhs.mode_);
-                std::swap(str_, rhs.str_);
-
-                basic_streambuf<char_type, traits_type>::swap(rhs);
-            }
-
-            /**
-             * 27.8.2.3, get and set:
-             */
-
-            basic_string<char_type, traits_type, allocator_type> str() const
-            {
-                if (mode_ & ios_base::out)
-                    return basic_string<char_type, traits_type, allocator_type>{
-                        this->output_begin_, this->output_next_ - 1, str_.get_allocator()
-                    };
-                else if (mode_ == ios_base::in)
-                    return basic_string<char_type, traits_type, allocator_type>{
-                        this->eback(), this->egptr(), str_.get_allocator()
-                    };
-                else
-                    return basic_string<char_type, traits_type, allocator_type>{};
-            }
-
-            void str(const basic_string<char_type, traits_type, allocator_type>& str)
-            {
-                str_ = str;
-                init_();
-            }
-
-        protected:
-            /**
-             * 27.8.2.4, overriden virtual functions:
-             */
-
-            int_type underflow() override
-            {
-                if (this->read_avail_())
-                    return traits_type::to_int_type(*this->gptr());
-                else
-                    return traits_type::eof();
-            }
-
-            int_type pbackfail(int_type c = traits_type::eof()) override
-            {
-                if (!traits_type::eq_int_type(c, traits_type::eof()) &&
-                    this->putback_avail_() &&
-                    traits_type::eq(traits_type::to_char_type(c), this->gptr()[-1]))
-                {
-                    --this->input_next_;
-
-                    return c;
-                }
-                else if (!traits_type::eq_int_type(c, traits_type::eof()) &&
-                         this->putback_avail_() && (mode_ & ios_base::out) != 0)
-                {
-                    *--this->input_next_ = c;
-
-                    return c;
-                }
-                else if (traits_type::eq_int_type(c, traits_type::eof()) &&
-                         this->putback_avail_())
-                {
-                    --this->input_next_;
-
-                    return traits_type::not_eof(c);
-                }
-
-                return traits_type::eof();
-            }
-
-            int_type overflow(int_type c = traits_type::eof()) override
-            {
-                if ((mode_ & ios_base::out) == 0)
-                    return traits_type::eof();
-
-                if (!traits_type::eq_int_type(c, traits_type::eof()))
-                {
-                    if (this->output_next_ < this->output_end_)
-                        return c;
-
-                    auto size = static_cast<size_t>(this->output_next_ - this->output_begin_);
-                    str_.size_ = size;
-
-                    str_.push_back(traits_type::to_char_type(c));
-                    init_();
-
-                    return c;
-                }
-                else if (traits_type::eq_int_type(c, traits_type::eof()))
-                    return traits_type::not_eof(c);
-
-                return traits_type::eof();
-            }
-
-            basic_streambuf<char_type, traits_type>* setbuf(char_type* str, streamsize n) override
-            {
-                if (!str && n == 0)
-                    return this;
-
-                str_.assign(str, str + static_cast<size_t>(n));
-
-                return this;
-            }
-
-            pos_type seekoff(off_type off, ios_base::seekdir dir,
-                             ios_base::openmode mode = ios_base::in | ios_base::out)
-            {
-                if ((mode & ios_base::in) == ios_base::in)
-                {
-                    if (!this->input_next_)
-                        return pos_type(off_type(-1));
-
-                    return seekoff_(off, this->input_begin_, this->input_next_, this->input_end_, dir);
-                }
-                else if ((mode & ios_base::out) == ios_base::out)
-                {
-                    if (!this->output_next_)
-                        return pos_type(off_type(-1));
-
-                    return seekoff_(off, this->output_begin_, this->output_next_, this->output_end_, dir);
-                }
-                else if ((mode & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out) &&
-                          (dir == ios_base::beg || dir == ios_base::end))
-                {
-                    if (!this->input_next_ || !this->output_next_)
-                        return pos_type(off_type(-1));
-
-                    seekoff_(off, this->input_begin_, this->input_next_, this->input_end_, dir);
-                    return seekoff_(off, this->output_begin_, this->output_next_, this->output_end_, dir);
-                }
-
-                return pos_type(off_type(-1));
-            }
-
-            pos_type seekpos(pos_type pos, ios_base::openmode mode = ios_base::in | ios_base::out)
-            {
-                return seekoff(off_type(pos), ios_base::beg, mode);
-            }
-
-        private:
-            ios_base::openmode mode_;
-            basic_string<char_type, traits_type, allocator_type> str_;
-
-            void init_()
-            {
-                if ((mode_ & ios_base::in) != 0)
-                {
-                    this->input_begin_ = this->input_next_ = str_.begin();
-                    this->input_end_ = str_.end();
-                }
-
-                if ((mode_ & ios_base::out) != 0)
-                {
-                    this->output_begin_ = str_.begin();
-                    this->output_next_ = str_.end();
-                    this->output_end_ = str_.begin() + str_.size() + 1;
-                }
-            }
-
-            bool ensure_free_space_(size_t n = 1)
-            {
-                str_.ensure_free_space_(n);
-                this->output_end_ = str_.begin() + str_.capacity();
-
-                return true;
-            }
-
-            pos_type seekoff_(off_type off, char_type* begin, char_type*& next, char_type* end,
-                          ios_base::seekdir dir)
-            {
-                off_type new_off{};
-
-                if (dir == ios_base::beg)
-                    new_off = 0;
-                else if (dir == ios_base::cur)
-                    new_off = static_cast<off_type>(next - begin);
-                else if (dir == ios_base::end)
-                    new_off = static_cast<off_type>(end - begin);
-
-                if (new_off + off < 0 || begin + new_off + off >= end)
-                    return pos_type(off_type(-1));
-                else
-                    next = begin + new_off + off;
-
-                return pos_type(new_off);
-            }
-    };
-
-    template<class Char, class Traits, class Allocator>
-    void swap(basic_stringbuf<Char, Traits, Allocator>& lhs,
-              basic_stringbuf<Char, Traits, Allocator>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 27.8.3, class template basic_istringstream:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    class basic_istringstream: public basic_istream<Char, Traits>
-    {
-        public:
-            using char_type      = Char;
-            using traits_type    = Traits;
-            using allocator_type = Allocator;
-            using int_type       = typename traits_type::int_type;
-            using pos_type       = typename traits_type::pos_type;
-            using off_type       = typename traits_type::off_type;
-
-            /**
-             * 27.8.3.1, constructors:
-             */
-
-            explicit basic_istringstream(ios_base::openmode mode = ios_base::in)
-                : basic_istream<char_type, traits_type>(&sb_),
-                  sb_(mode | ios_base::in)
-            { /* DUMMY BODY */ }
-
-            explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type> str,
-                                         ios_base::openmode mode = ios_base::in)
-                : basic_istream<char_type, traits_type>{&sb_},
-                  sb_(str, mode | ios_base::in)
-            { /* DUMMY BODY */ }
-
-            basic_istringstream(const basic_istringstream&) = delete;
-
-            basic_istringstream(basic_istringstream&& other)
-                : basic_istream<char_type, traits_type>{move(other)},
-                  sb_{move(other.sb_)}
-            {
-                basic_istream<char_type, traits_type>::set_rdbuf(&sb_);
-            }
-
-            /**
-             * 27.8.3.2, assign and swap:
-             */
-
-            basic_istringstream& operator=(const basic_istringstream&) = delete;
-
-            basic_istringstream& operator=(basic_istringstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_istringstream& rhs)
-            {
-                basic_istream<char_type, traits_type>::swap(rhs);
-                sb_.swap(rhs.sb_);
-            }
-
-            /**
-             * 27.8.3.3, members:
-             */
-
-            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
-            {
-                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
-            }
-
-            basic_string<char_type, traits_type, allocator_type> str() const
-            {
-                return sb_.str();
-            }
-
-            void str(const basic_string<char_type, traits_type, allocator_type>& str)
-            {
-                sb_.str(str);
-            }
-
-        private:
-            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
-    };
-
-    template<class Char, class Traits, class Allocator>
-    void swap(basic_istringstream<Char, Traits, Allocator>& lhs,
-              basic_istringstream<Char, Traits, Allocator>& rhs)
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class Char, class Traits, class Allocator>
-    class basic_ostringstream: public basic_ostream<Char, Traits>
-    {
-        public:
-            using char_type      = Char;
-            using traits_type    = Traits;
-            using allocator_type = Allocator;
-            using int_type       = typename traits_type::int_type;
-            using pos_type       = typename traits_type::pos_type;
-            using off_type       = typename traits_type::off_type;
-
-            /**
-             * 27.8.4.1, constructors:
-             */
-
-            explicit basic_ostringstream(ios_base::openmode mode = ios_base::out)
-                : basic_ostream<char_type, traits_type>(&sb_),
-                  sb_(mode | ios_base::out)
-            { /* DUMMY BODY */ }
-
-            explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type> str,
-                                         ios_base::openmode mode = ios_base::out)
-                : basic_ostream<char_type, traits_type>{&sb_},
-                  sb_(str, mode | ios_base::out)
-            { /* DUMMY BODY */ }
-
-            basic_ostringstream(const basic_ostringstream&) = delete;
-
-            basic_ostringstream(basic_ostringstream&& other)
-                : basic_ostream<char_type, traits_type>{move(other)},
-                  sb_{move(other.sb_)}
-            {
-                basic_ostream<char_type, traits_type>::set_rdbuf(&sb_);
-            }
-
-            /**
-             * 27.8.4.2, assign and swap:
-             */
-
-            basic_ostringstream& operator=(const basic_ostringstream&) = delete;
-
-            basic_ostringstream& operator=(basic_ostringstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_ostringstream& rhs)
-            {
-                basic_ostream<char_type, traits_type>::swap(rhs);
-                sb_.swap(rhs.sb_);
-            }
-
-            /**
-             * 27.8.3.3, members:
-             */
-
-            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
-            {
-                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
-            }
-
-            basic_string<char_type, traits_type, allocator_type> str() const
-            {
-                return sb_.str();
-            }
-
-            void str(const basic_string<char_type, traits_type, allocator_type>& str)
-            {
-                sb_.str(str);
-            }
-
-        private:
-            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
-    };
-
-    /**
-     * 27.8.5, class template basic_stringstream:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    class basic_stringstream: public basic_iostream<Char, Traits>
-    {
-        public:
-            using char_type      = Char;
-            using traits_type    = Traits;
-            using allocator_type = Allocator;
-            using int_type       = typename traits_type::int_type;
-            using pos_type       = typename traits_type::pos_type;
-            using off_type       = typename traits_type::off_type;
-
-            /**
-             * 27.8.5.1, constructors:
-             */
-
-            explicit basic_stringstream(ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_iostream<char_type, traits_type>(&sb_),
-                  sb_(mode | ios_base::out)
-            { /* DUMMY BODY */ }
-
-            explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type> str,
-                                         ios_base::openmode mode = ios_base::in | ios_base::out)
-                : basic_iostream<char_type, traits_type>{&sb_},
-                  sb_(str, mode | ios_base::out)
-            { /* DUMMY BODY */ }
-
-            basic_stringstream(const basic_stringstream&) = delete;
-
-            basic_stringstream(basic_stringstream&& other)
-                : basic_iostream<char_type, traits_type>{move(other)},
-                  sb_{move(other.sb_)}
-            {
-                basic_iostream<char_type, traits_type>::set_rdbuf(&sb_);
-            }
-
-            /**
-             * 27.8.5.2, assign and swap:
-             */
-
-            basic_stringstream& operator=(const basic_stringstream&) = delete;
-
-            basic_stringstream& operator=(basic_stringstream&& other)
-            {
-                swap(other);
-            }
-
-            void swap(basic_stringstream& rhs)
-            {
-                basic_iostream<char_type, traits_type>::swap(rhs);
-                sb_.swap(rhs.sb_);
-            }
-
-            /**
-             * 27.8.5.3, members:
-             */
-
-            basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const
-            {
-                return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&sb_);
-            }
-
-            basic_string<char_type, traits_type, allocator_type> str() const
-            {
-                return sb_.str();
-            }
-
-            void str(const basic_string<char_type, traits_type, allocator_type>& str)
-            {
-                sb_.str(str);
-            }
-
-        private:
-            basic_stringbuf<char_type, traits_type, allocator_type> sb_;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/stack.hpp
===================================================================
--- uspace/lib/cpp/include/impl/stack.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,200 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_STACK
-#define LIBCPP_STACK
-
-#include <deque>
-#include <initializer_list>
-#include <utility>
-
-namespace std
-{
-
-    /**
-     * 23.5.6.2, stack:
-     */
-
-    template<class T, class Container = deque<T>>
-    class stack
-    {
-        public:
-            using container_type  = Container;
-            using value_type      = typename container_type::value_type;
-            using reference       = typename container_type::reference;
-            using const_reference = typename container_type::const_reference;
-            using size_type       = typename container_type::size_type;
-
-            explicit stack(container_type& cont)
-                : c{cont}
-            { /* DUMMY BODY */ }
-
-            explicit stack(container_type&& cont = container_type{})
-                : c{move(cont)}
-            { /* DUMMY BODY */ }
-
-            /**
-             * TODO: The allocator constructor should use enable_if
-             *       as a last parameter that checks if uses_allocator
-             *       from <memory> holds.
-             */
-            template<class Alloc>
-            explicit stack(Alloc& alloc)
-                : c{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class Alloc>
-            stack(const container_type& cont, const Alloc& alloc)
-                : c{cont, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class Alloc>
-            stack(container_type&& cont, const Alloc& alloc)
-                : c{move(cont), alloc}
-            { /* DUMMY BODY */ }
-
-            template<class Alloc>
-            stack(const stack& other, const Alloc& alloc)
-                : c{other.c, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class Alloc>
-            stack(stack&& other, const Alloc& alloc)
-                : c{move(other.c), alloc}
-            { /* DUMMY BODY */ }
-
-            bool empty()
-            {
-                return c.empty();
-            }
-
-            size_type size()
-            {
-                return c.size();
-            }
-
-            reference top()
-            {
-                return c.back();
-            }
-
-            const_reference top() const
-            {
-                return c.back();
-            }
-
-            void push(const value_type& val)
-            {
-                c.push_back(val);
-            }
-
-            void push(value_type&& val)
-            {
-                c.push_back(move(val));
-            }
-
-            template<class... Args>
-            void emplace(Args&&... args)
-            {
-                c.emplace_back(forward<Args>(args)...);
-            }
-
-            void pop()
-            {
-                c.pop_back();
-            }
-
-            void swap(stack& other) // We cannot use c in the noexcept :/
-                noexcept(noexcept(declval<container_type>().swap(declval<container_type&>())))
-            {
-                std::swap(c, other.c);
-            }
-
-        protected:
-            container_type c;
-    };
-
-    /**
-     * 23.6.5.5, stack operators:
-     */
-
-    template<class T, class Container>
-    bool operator==(const stack<T, Container>& lhs,
-                    const stack<T, Container>& rhs)
-    {
-        return lhs.c == rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator!=(const stack<T, Container>& lhs,
-                    const stack<T, Container>& rhs)
-    {
-        return lhs.c != rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator<(const stack<T, Container>& lhs,
-                   const stack<T, Container>& rhs)
-    {
-        return lhs.c < rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator<=(const stack<T, Container>& lhs,
-                    const stack<T, Container>& rhs)
-    {
-        return lhs.c <= rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator>(const stack<T, Container>& lhs,
-                   const stack<T, Container>& rhs)
-    {
-        return lhs.c > rhs.c;
-    }
-
-    template<class T, class Container>
-    bool operator>=(const stack<T, Container>& lhs,
-                    const stack<T, Container>& rhs)
-    {
-        return lhs.c >= rhs.c;
-    }
-
-    /**
-     * 23.6.5.6, stack specialized algorithms:
-     */
-
-    template<class T, class Container>
-    void swap(stack<T, Container>& lhs, stack<T, Container>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/stdexcept.hpp
===================================================================
--- uspace/lib/cpp/include/impl/stdexcept.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,125 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_STDEXCEPT
-#define LIBCPP_STDEXCEPT
-
-#include <exception>
-#include <iosfwd>
-#include <__bits/stringfwd.hpp>
-
-namespace std
-{
-    class logic_error: public exception
-    {
-        public:
-            explicit logic_error(const string&);
-            explicit logic_error(const char*);
-            logic_error(const logic_error&) noexcept;
-            logic_error& operator=(const logic_error&);
-            ~logic_error() override;
-
-            const char* what() const noexcept override;
-
-        protected:
-            const char* what_;
-    };
-
-    class domain_error: public logic_error
-    {
-        public:
-            explicit domain_error(const string&);
-            explicit domain_error(const char*);
-            domain_error(const domain_error&) noexcept;
-    };
-
-    class invalid_argument: public logic_error
-    {
-        public:
-            explicit invalid_argument(const string&);
-            explicit invalid_argument(const char*);
-            invalid_argument(const invalid_argument&) noexcept;
-    };
-
-    class length_error: public logic_error
-    {
-        public:
-            explicit length_error(const string&);
-            explicit length_error(const char*);
-            length_error(const length_error&) noexcept;
-    };
-
-    class out_of_range: public logic_error
-    {
-        public:
-            explicit out_of_range(const string&);
-            explicit out_of_range(const char*);
-            out_of_range(const out_of_range&) noexcept;
-    };
-
-    class runtime_error: public exception
-    {
-        public:
-            explicit runtime_error(const string&);
-            explicit runtime_error(const char*);
-            runtime_error(const runtime_error&) noexcept;
-            runtime_error& operator=(const runtime_error&);
-            ~runtime_error() override;
-
-            const char* what() const noexcept override;
-
-        protected:
-            const char* what_;
-    };
-
-    class range_error: public runtime_error
-    {
-        public:
-            explicit range_error(const string&);
-            explicit range_error(const char*);
-            range_error(const range_error&) noexcept;
-    };
-
-    class overflow_error: public runtime_error
-    {
-        public:
-            explicit overflow_error(const string&);
-            explicit overflow_error(const char*);
-            overflow_error(const overflow_error&) noexcept;
-    };
-
-    class underflow_error: public runtime_error
-    {
-        public:
-            explicit underflow_error(const string&);
-            explicit underflow_error(const char*);
-            underflow_error(const underflow_error&) noexcept;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/streambuf.hpp
===================================================================
--- uspace/lib/cpp/include/impl/streambuf.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,431 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_STREAMBUF
-#define LIBCPP_STREAMBUF
-
-#include <ios>
-#include <iosfwd>
-#include <locale>
-
-namespace std
-{
-
-    /**
-     * 27.6.3, class template basic_streambuf:
-     */
-
-    template<class Char, class Traits>
-    class basic_streambuf
-    {
-        public:
-            using traits_type = Traits;
-            using char_type   = Char;
-            using int_type    = typename traits_type::int_type;
-            using pos_type    = typename traits_type::pos_type;
-            using off_type    = typename traits_type::off_type;
-
-            virtual ~basic_streambuf()
-            { /* DUMMY BODY */ }
-
-            /**
-             * 27.6.3.2.1, locales:
-             */
-
-            locale pubimbue(const locale& loc)
-            {
-                imbue(loc);
-
-                return locale_;
-            }
-
-            locale& getloc() const
-            {
-                return locale_;
-            }
-
-            /**
-             * 27.6.3.2.2, buffer and positioning:
-             */
-
-            basic_streambuf<Char, Traits>* pubsetbuf(char_type* s, streamsize n)
-            {
-                return setbuf(s, n);
-            }
-
-            pos_type pubseekoff(off_type off, ios_base::seekdir way,
-                                ios_base::openmode which = ios_base::in | ios_base::out)
-            {
-                return seekoff(off, way, which);
-            }
-
-            pos_type pubseekpos(pos_type pos, ios_base::openmode which =
-                                ios_base::in | ios_base::out)
-            {
-                return seekpos(pos, which);
-            }
-
-            int pubsync()
-            {
-                return sync();
-            }
-
-            /**
-             * 27.6.3.2.3, get area:
-             */
-
-            streamsize in_avail()
-            {
-                if (read_avail_())
-                    return egptr() - gptr();
-                else
-                    return showmanyc();
-            }
-
-            int_type snextc()
-            {
-                if (traits_type::eq(sbumpc(), traits_type::eof()))
-                    return traits_type::eof();
-                else
-                    return sgetc();
-            }
-
-            int_type sbumpc()
-            {
-                if (read_avail_())
-                    return traits_type::to_int_type(*input_next_++);
-                else
-                    return uflow();
-            }
-
-            int_type sgetc()
-            {
-                if (read_avail_())
-                    return traits_type::to_int_type(*input_next_);
-                else
-                    return underflow();
-            }
-
-            streamsize sgetn(char_type* s, streamsize n)
-            {
-                return xsgetn(s, n);
-            }
-
-            /**
-             * 27.6.2.4, putback:
-             */
-
-            int_type sputbackc(char_type c)
-            {
-                if (!putback_avail_() || traits_type::eq(c, gptr()[-1]))
-                    return pbackfail(traits_type::to_int_type(c));
-                else
-                    return traits_type::to_int_type(*(--input_next_));
-            }
-
-            int_type sungetc()
-            {
-                if (!putback_avail_())
-                    return pbackfail();
-                else
-                    return traits_type::to_int_type(*(--input_next_));
-            }
-
-            /**
-             * 27.6.2.5, put area:
-             */
-
-            int_type sputc(char_type c)
-            {
-                if (!write_avail_())
-                    return overflow(traits_type::to_int_type(c));
-                else
-                {
-                    traits_type::assign(*output_next_++, c);
-
-                    return traits_type::to_int_type(c);
-                }
-            }
-
-            streamsize sputn(const char_type* s, streamsize n)
-            {
-                return xsputn(s, n);
-            }
-
-        protected:
-            basic_streambuf()
-                : input_begin_{}, input_next_{}, input_end_{},
-                  output_begin_{}, output_next_{}, output_end_{},
-                  locale_{locale()}
-            { /* DUMMY BODY */ }
-
-            basic_streambuf(const basic_streambuf& rhs)
-            {
-                input_begin_ = rhs.input_begin_;
-                input_next_ = rhs.input_next_;
-                input_end_ = rhs.input_end_;
-
-                output_begin_ = rhs.output_begin_;
-                output_next_ = rhs.output_next_;
-                output_end_ = rhs.output_end_;
-
-                locale_ = rhs.locale_;
-            }
-
-            basic_streambuf& operator=(const basic_streambuf& rhs)
-            {
-                input_begin_ = rhs.input_begin_;
-                input_next_  = rhs.input_next_;
-                input_end_   = rhs.input_end_;
-
-                output_begin_ = rhs.output_begin_;
-                output_next_  = rhs.output_next_;
-                output_end_   = rhs.output_end_;
-
-                locale_ = rhs.locale_;
-
-                return *this;
-            }
-
-            void swap(basic_streambuf& rhs)
-            {
-                swap(input_begin_, rhs.input_begin_);
-                swap(input_next_, rhs.input_next_);
-                swap(input_end_, rhs.input_end_);
-
-                swap(output_begin_, rhs.output_begin_);
-                swap(output_next_, rhs.output_next_);
-                swap(output_end_, rhs.output_end_);
-
-                swap(locale_, rhs.locale_);
-            }
-
-            /**
-             * 27.6.3.3.2, get area:
-             */
-
-            char_type* eback() const
-            {
-                return input_begin_;
-            }
-
-            char_type* gptr() const
-            {
-                return input_next_;
-            }
-
-            char_type* egptr() const
-            {
-                return input_end_;
-            }
-
-            void gbump(int n)
-            {
-                input_next_ += n;
-            }
-
-            void setg(char_type* gbeg, char_type* gnext, char_type* gend)
-            {
-                input_begin_ = gbeg;
-                input_next_  = gnext;
-                input_end_   = gend;
-            }
-
-            /**
-             * 27.6.3.3.3, put area:
-             */
-
-            char_type* pbase() const
-            {
-                return output_begin_;
-            }
-
-            char_type* pptr() const
-            {
-                return output_next_;
-            }
-
-            char_type* epptr() const
-            {
-                return output_end_;
-            }
-
-            void pbump(int n)
-            {
-                output_next_ += n;
-            }
-
-            void setp(char_type* pbeg, char_type* pend)
-            {
-                output_begin_ = pbeg;
-                output_next_  = pbeg;
-                output_end_   = pend;
-            }
-
-            /**
-             * 27.6.3.4.1, locales:
-             */
-
-            virtual void imbue(const locale& loc)
-            { /* DUMMY BODY */ }
-
-            /**
-             * 27.6.3.4.2, buffer management and positioning:
-             */
-
-            virtual basic_streambuf<Char, Traits>*
-            setbuf(char_type* s, streamsize n)
-            {
-                return this;
-            }
-
-            virtual pos_type seekoff(off_type off, ios_base::seekdir way,
-                                     ios_base::openmode which = ios_base::in | ios_base::out)
-            {
-                return pos_type(off_type(-1));
-            }
-
-            virtual pos_type seekpos(pos_type pos, ios_base::openmode which =
-                                     ios_base::in | ios_base::out)
-            {
-                return pos_type(off_type(-1));
-            }
-
-            virtual int sync()
-            {
-                return 0;
-            }
-
-            /**
-             * 27.6.3.4.3, get area:
-             */
-
-            virtual streamsize showmanyc()
-            {
-                return 0;
-            }
-
-            virtual streamsize xsgetn(char_type* s, streamsize n)
-            {
-                if (!s || n == 0)
-                    return 0;
-
-                streamsize i{0};
-                auto eof = traits_type::eof();
-                for (; i <= n; ++i)
-                {
-                    if (!read_avail_() && traits_type::eq_int_type(uflow(), eof))
-                        break;
-
-                    *s++ = *input_next_++;
-                }
-
-                return i;
-            }
-
-            virtual int_type underflow()
-            {
-                return traits_type::eof();
-            }
-
-            virtual int_type uflow()
-            {
-                auto res = underflow();
-                if (traits_type::eq_int_type(res, traits_type::eof()))
-                    return traits_type::eof();
-                else
-                    return traits_type::to_int_type(*input_next_++);
-            }
-
-            /**
-             * 27.6.3.4.4, putback:
-             */
-
-            virtual int_type pbackfail(int_type c = traits_type::eof())
-            {
-                return traits_type::eof();
-            }
-
-            /**
-             * 27.6.3.4.5, put area:
-             */
-
-            virtual streamsize xsputn(const char_type* s, streamsize n)
-            {
-                if (!s || n == 0)
-                    return 0;
-
-                streamsize i{0};
-                for (; i <= n; ++i)
-                {
-                    if (!write_avail_() && traits_type::eq_int_type(overflow(), traits_type::eof()))
-                        break;
-
-                    *output_next_++ = *s++;
-                }
-
-                return i;
-            }
-
-            virtual int_type overflow(int_type c = traits_type::eof())
-            {
-                return traits_type::eof();
-            }
-
-        protected:
-            char_type* input_begin_;
-            char_type* input_next_;
-            char_type* input_end_;
-
-            char_type* output_begin_;
-            char_type* output_next_;
-            char_type* output_end_;
-
-            locale locale_;
-
-            bool write_avail_() const
-            {
-                return output_next_ && output_next_ < output_end_;
-            }
-
-            bool putback_avail_() const
-            {
-                return input_next_ && input_begin_ < input_next_;
-            }
-
-            bool read_avail_() const
-            {
-                return input_next_ && input_next_ < input_end_;
-            }
-    };
-
-    using streambuf  = basic_streambuf<char>;
-    using wstreambuf = basic_streambuf<wchar_t>;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/string.hpp
===================================================================
--- uspace/lib/cpp/include/impl/string.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1978 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_STRING
-#define LIBCPP_STRING
-
-#include <algorithm>
-#include <iosfwd>
-#include <iterator>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cwchar>
-#include <memory>
-#include <__bits/stringfwd.hpp>
-#include <utility>
-
-#include <initializer_list>
-
-namespace std
-{
-    /**
-     * 21.2, char_traits:
-     */
-
-    template<class Char>
-    struct char_traits;
-
-    /**
-     * 21.2.3, char_traits specializations:
-     */
-
-    template<>
-    struct char_traits<char>
-    {
-        using char_type  = char;
-        using int_type   = int;
-        using off_type   = streamoff;
-        using pos_type   = streampos;
-        /* using state_type = mbstate_t; */
-
-        static void assign(char_type& c1, const char_type& c2) noexcept
-        {
-            c1 = c2;
-        }
-
-        static constexpr bool eq(char_type c1, char_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr bool lt(char_type c1, char_type c2) noexcept
-        {
-            return c1 < c2;
-        }
-
-        static int compare(const char_type* s1, const char_type* s2, size_t n)
-        {
-            return hel::str_lcmp(s1, s2, n);
-        }
-
-        static size_t length(const char_type* s)
-        {
-            return hel::str_size(s);
-        }
-
-        static const char_type* find(const char_type* s, size_t n, const char_type& c)
-        {
-            size_t i{};
-            while (i++ < n)
-            {
-                if (s[i] == c)
-                    return s + i;
-            }
-
-            return nullptr;
-        }
-
-        static char_type* move(char_type* s1, const char_type* s2, size_t n)
-        {
-            return static_cast<char_type*>(memmove(s1, s2, n));
-        }
-
-        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
-        {
-            return static_cast<char_type*>(memcpy(s1, s2, n));
-        }
-
-        static char_type* assign(char_type* s, size_t n, char_type c)
-        {
-            /**
-             * Note: Even though memset accepts int as its second argument,
-             *       the actual implementation assigns that int to a dereferenced
-             *       char pointer.
-             */
-            return static_cast<char_type*>(memset(s, static_cast<int>(c), n));
-        }
-
-        static constexpr int_type not_eof(int_type c) noexcept
-        {
-            if (!eq_int_type(c, eof()))
-                return c;
-            else
-                return to_int_type('a'); // We just need something that is not eof.
-        }
-
-        static constexpr char_type to_char_type(int_type c) noexcept
-        {
-            return static_cast<char_type>(c);
-        }
-
-        static constexpr int_type to_int_type(char_type c) noexcept
-        {
-            return static_cast<int_type>(c);
-        }
-
-        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr int_type eof() noexcept
-        {
-            return static_cast<int_type>(EOF);
-        }
-    };
-
-    template<>
-    struct char_traits<char16_t>
-    {
-        // TODO: implement
-        using char_type  = char16_t;
-        using int_type   = int16_t;
-        using off_type   = streamoff;
-        using pos_type   = streampos;
-        /* using state_type = mbstate_t; */
-
-        static void assign(char_type& c1, const char_type& c2) noexcept
-        {
-            c1 = c2;
-        }
-
-        static constexpr bool eq(char_type c1, char_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr bool lt(char_type c1, char_type c2) noexcept
-        {
-            return c1 < c2;
-        }
-
-        static int compare(const char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return 0;
-        }
-
-        static size_t length(const char_type* s)
-        {
-            // TODO: implement
-            return 0;
-        }
-
-        static const char_type* find(const char_type* s, size_t n, const char_type& c)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* move(char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* assign(char_type* s, size_t n, char_type c)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static constexpr int_type not_eof(int_type c) noexcept
-        {
-            // TODO: implement
-            return int_type{};
-        }
-
-        static constexpr char_type to_char_type(int_type c) noexcept
-        {
-            return static_cast<char_type>(c);
-        }
-
-        static constexpr int_type to_int_type(char_type c) noexcept
-        {
-            return static_cast<int_type>(c);
-        }
-
-        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr int_type eof() noexcept
-        {
-            return static_cast<int_type>(EOF);
-        }
-    };
-
-    template<>
-    struct char_traits<char32_t>
-    {
-        // TODO: implement
-        using char_type  = char32_t;
-        using int_type   = int32_t;
-        using off_type   = streamoff;
-        using pos_type   = streampos;
-        /* using state_type = mbstate_t; */
-
-        static void assign(char_type& c1, const char_type& c2) noexcept
-        {
-            c1 = c2;
-        }
-
-        static constexpr bool eq(char_type c1, char_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr bool lt(char_type c1, char_type c2) noexcept
-        {
-            return c1 < c2;
-        }
-
-        static int compare(const char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return 0;
-        }
-
-        static size_t length(const char_type* s)
-        {
-            // TODO: implement
-            return 0;
-        }
-
-        static const char_type* find(const char_type* s, size_t n, const char_type& c)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* move(char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static char_type* assign(char_type* s, size_t n, char_type c)
-        {
-            // TODO: implement
-            return nullptr;
-        }
-
-        static constexpr int_type not_eof(int_type c) noexcept
-        {
-            // TODO: implement
-            return int_type{};
-        }
-
-        static constexpr char_type to_char_type(int_type c) noexcept
-        {
-            return static_cast<char_type>(c);
-        }
-
-        static constexpr int_type to_int_type(char_type c) noexcept
-        {
-            return static_cast<int_type>(c);
-        }
-
-        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr int_type eof() noexcept
-        {
-            return static_cast<int_type>(EOF);
-        }
-    };
-
-    template<>
-    struct char_traits<wchar_t>
-    {
-        using char_type  = wchar_t;
-        using int_type   = wint_t;
-        using off_type   = streamoff;
-        using pos_type   = wstreampos;
-        /* using state_type = mbstate_t; */
-
-        static void assign(char_type& c1, const char_type& c2) noexcept
-        {
-            c1 = c2;
-        }
-
-        static constexpr bool eq(char_type c1, char_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr bool lt(char_type c1, char_type c2) noexcept
-        {
-            return c1 < c2;
-        }
-
-        static int compare(const char_type* s1, const char_type* s2, size_t n)
-        {
-            // TODO: This function does not exits...
-            //return hel::wstr_lcmp(s1, s2, n);
-            return 0;
-        }
-
-        static size_t length(const char_type* s)
-        {
-            return hel::wstr_size(s);
-        }
-
-        static const char_type* find(const char_type* s, size_t n, const char_type& c)
-        {
-            size_t i{};
-            while (i++ < n)
-            {
-                if (s[i] == c)
-                    return s + i;
-            }
-
-            return nullptr;
-        }
-
-        static char_type* move(char_type* s1, const char_type* s2, size_t n)
-        {
-            return static_cast<char_type*>(memmove(s1, s2, n * sizeof(wchar_t)));
-        }
-
-        static char_type* copy(char_type* s1, const char_type* s2, size_t n)
-        {
-            return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(wchar_t)));
-        }
-
-        static char_type* assign(char_type* s, size_t n, char_type c)
-        {
-            return static_cast<char_type*>(memset(s, static_cast<int>(c), n * sizeof(wchar_t)));
-        }
-
-        static constexpr int_type not_eof(int_type c) noexcept
-        {
-            if (!eq_int_type(c, eof()))
-                return c;
-            else
-                return to_int_type(L'a'); // We just need something that is not eof.
-        }
-
-        static constexpr char_type to_char_type(int_type c) noexcept
-        {
-            return static_cast<char_type>(c);
-        }
-
-        static constexpr int_type to_int_type(char_type c) noexcept
-        {
-            return static_cast<int_type>(c);
-        }
-
-        static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
-        {
-            return c1 == c2;
-        }
-
-        static constexpr int_type eof() noexcept
-        {
-            return static_cast<int_type>(EOF);
-        }
-    };
-
-    /**
-     * 21.4, class template basic_string:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    class basic_string
-    {
-        public:
-            using traits_type     = Traits;
-            using value_type      = typename traits_type::char_type;
-            using allocator_type  = Allocator;
-            using size_type       = typename allocator_traits<allocator_type>::size_type;
-            using difference_type = typename allocator_traits<allocator_type>::difference_type;
-
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-
-            using iterator               = pointer;
-            using const_iterator         = const_pointer;
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            static constexpr size_type npos = -1;
-
-            /**
-             * 21.4.2, construct/copy/destroy:
-             * TODO: tagged constructor that moves the char*
-             *       and use that with asprintf in to_string
-             */
-
-            basic_string() noexcept
-                : basic_string(allocator_type{})
-            { /* DUMMY BODY */ }
-
-            explicit basic_string(const allocator_type& alloc)
-                : data_{}, size_{}, capacity_{}, allocator_{alloc}
-            {
-                /**
-                 * Postconditions:
-                 *  data() = non-null copyable value that can have 0 added to it.
-                 *  size() = 0
-                 *  capacity() = unspecified
-                 */
-                data_ = allocator_.allocate(default_capacity_);
-                capacity_ = default_capacity_;
-            }
-
-            basic_string(const basic_string& other)
-                : data_{}, size_{other.size_}, capacity_{other.capacity_},
-                  allocator_{other.allocator_}
-            {
-                init_(other.data(), size_);
-            }
-
-            basic_string(basic_string&& other)
-                : data_{other.data_}, size_{other.size_},
-                  capacity_{other.capacity_}, allocator_{move(other.allocator_)}
-            {
-                other.data_ = nullptr;
-                other.size_ = 0;
-                other.capacity_ = 0;
-            }
-
-            basic_string(const basic_string& other, size_type pos, size_type n = npos,
-                         const allocator_type& alloc = allocator_type{})
-                : data_{}, size_{}, capacity_{}, allocator_{alloc}
-            {
-                // TODO: if pos < other.size() throw out_of_range.
-                auto len = min(n, other.size() - pos);
-                init_(other.data() + pos, len);
-            }
-
-            basic_string(const value_type* str, size_type n, const allocator_type& alloc = allocator_type{})
-                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
-            {
-                init_(str, size_);
-            }
-
-            basic_string(const value_type* str, const allocator_type& alloc = allocator_type{})
-                : data_{}, size_{}, capacity_{}, allocator_{alloc}
-            {
-                init_(str, traits_type::length(str));
-            }
-
-            basic_string(size_type n, value_type c, const allocator_type& alloc = allocator_type{})
-                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
-            {
-                data_ = allocator_.allocate(capacity_);
-                for (size_type i = 0; i < size_; ++i)
-                    traits_type::assign(data_[i], c);
-                ensure_null_terminator_();
-            }
-
-            template<class InputIterator>
-            basic_string(InputIterator first, InputIterator last,
-                         const allocator_type& alloc = allocator_type{})
-                : data_{}, size_{}, capacity_{}, allocator_{alloc}
-            {
-                if constexpr (is_integral<InputIterator>::value)
-                { // Required by the standard.
-                    size_ = static_cast<size_type>(first);
-                    capacity_ = size_;
-                    data_ = allocator_.allocate(capacity_);
-
-                    for (size_type i = 0; i < size_; ++i)
-                        traits_type::assign(data_[i], static_cast<value_type>(last));
-                    ensure_null_terminator_();
-                }
-                else
-                {
-                    auto len = static_cast<size_type>(last - first);
-                    init_(first, len);
-                }
-            }
-
-            basic_string(initializer_list<value_type> init, const allocator_type& alloc = allocator_type{})
-                : basic_string{init.begin(), init.size(), alloc}
-            { /* DUMMY BODY */ }
-
-            basic_string(const basic_string& other, const allocator_type& alloc)
-                : data_{}, size_{other.size_}, capacity_{other.capacity_}, allocator_{alloc}
-            {
-                init_(other.data(), size_);
-            }
-
-            basic_string(basic_string&& other, const allocator_type& alloc)
-                : data_{other.data_}, size_{other.size_}, capacity_{other.capacity_}, allocator_{alloc}
-            {
-                other.data_ = nullptr;
-                other.size_ = 0;
-                other.capacity_ = 0;
-            }
-
-            ~basic_string()
-            {
-                allocator_.deallocate(data_, capacity_);
-            }
-
-            basic_string& operator=(const basic_string& other)
-            {
-                if (this != &other)
-                {
-                    basic_string tmp{other};
-                    swap(tmp);
-                }
-
-                return *this;
-            }
-
-            basic_string& operator=(basic_string&& other)
-                noexcept(allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
-                         allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                if (this != &other)
-                    swap(other);
-
-                return *this;
-            }
-
-            basic_string& operator=(const value_type* other)
-            {
-                *this = basic_string{other};
-
-                return *this;
-            }
-
-            basic_string& operator=(value_type c)
-            {
-                *this = basic_string{1, c};
-
-                return *this;
-            }
-
-            basic_string& operator=(initializer_list<value_type> init)
-            {
-                *this = basic_string{init};
-
-                return *this;
-            }
-
-            /**
-             * 21.4.3, iterators:
-             */
-
-            iterator begin() noexcept
-            {
-                return &data_[0];
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return &data_[0];
-            }
-
-            iterator end() noexcept
-            {
-                return begin() + size_;
-            }
-
-            const_iterator end() const noexcept
-            {
-                return begin() + size_;
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return make_reverse_iterator(end());
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return make_reverse_iterator(begin());
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return &data_[0];
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return cbegin() + size_;
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return rbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return rend();
-            }
-
-            /**
-             * 21.4.4, capacity:
-             */
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type length() const noexcept
-            {
-                return size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return 0x7FFF; // TODO: just temporary
-                /* return allocator_traits<allocator_type>::max_size(allocator_); */
-            }
-
-            void resize(size_type new_size, value_type c)
-            {
-                // TODO: if new_size > max_size() throw length_error.
-                if (new_size > size_)
-                {
-                    ensure_free_space_(new_size - size_ + 1);
-                    for (size_type i = size_; i < new_size; ++i)
-                        traits_type::assign(data_[i], i);
-                }
-
-                size_ = new_size;
-                ensure_null_terminator_();
-            }
-
-            void resize(size_type new_size)
-            {
-                resize(new_size, value_type{});
-            }
-
-            size_type capacity() const noexcept
-            {
-                return capacity_;
-            }
-
-            void reserve(size_type new_capacity = 0)
-            {
-                // TODO: if new_capacity > max_size() throw
-                //       length_error (this function shall have no
-                //       effect in such case)
-                if (new_capacity > capacity_)
-                    resize_with_copy_(size_, new_capacity);
-                else if (new_capacity < capacity_)
-                    shrink_to_fit(); // Non-binding request, but why not.
-            }
-
-            void shrink_to_fit()
-            {
-                if (size_ != capacity_)
-                    resize_with_copy_(size_, capacity_);
-            }
-
-            void clear() noexcept
-            {
-                size_ = 0;
-            }
-
-            bool empty() const noexcept
-            {
-                return size_ == 0;
-            }
-
-            /**
-             * 21.4.5, element access:
-             */
-
-            const_reference operator[](size_type idx) const
-            {
-                return data_[idx];
-            }
-
-            reference operator[](size_type idx)
-            {
-                return data_[idx];
-            }
-
-            const_reference at(size_type idx) const
-            {
-                // TODO: bounds checking
-                return data_[idx];
-            }
-
-            reference at(size_type idx)
-            {
-                // TODO: bounds checking
-                return data_[idx];
-            }
-
-            const_reference front() const
-            {
-                return at(0);
-            }
-
-            reference front()
-            {
-                return at(0);
-            }
-
-            const_reference back() const
-            {
-                return at(size_ - 1);
-            }
-
-            reference back()
-            {
-                return at(size_ - 1);
-            }
-
-            /**
-             * 21.4.6, modifiers:
-             */
-
-            basic_string& operator+=(const basic_string& str)
-            {
-                return append(str);
-            }
-
-            basic_string& operator+=(const value_type* str)
-            {
-                return append(str);
-            }
-
-            basic_string& operator+=(value_type c)
-            {
-                push_back(c);
-                return *this;
-            }
-
-            basic_string& operator+=(initializer_list<value_type> init)
-            {
-                return append(init.begin(), init.size());
-            }
-
-            basic_string& append(const basic_string& str)
-            {
-                return append(str.data(), str.size());
-            }
-
-            basic_string& append(const basic_string& str, size_type pos,
-                                 size_type n = npos)
-            {
-                if (pos < str.size())
-                {
-                    auto len = min(n, str.size() - pos);
-
-                    return append(str.data() + pos, len);
-                }
-                // TODO: Else throw out_of_range.
-            }
-
-            basic_string& append(const value_type* str, size_type n)
-            {
-                // TODO: if (size_ + n > max_size()) throw length_error
-                ensure_free_space_(n);
-                traits_type::copy(data_ + size(), str, n);
-                size_ += n;
-                ensure_null_terminator_();
-
-                return *this;
-            }
-
-            basic_string& append(const value_type* str)
-            {
-                return append(str, traits_type::length(str));
-            }
-
-            basic_string& append(size_type n, value_type c)
-            {
-                return append(basic_string(n, c));
-            }
-
-            template<class InputIterator>
-            basic_string& append(InputIterator first, InputIterator last)
-            {
-                return append(basic_string(first, last));
-            }
-
-            basic_string& append(initializer_list<value_type> init)
-            {
-                return append(init.begin(), init.size());
-            }
-
-            void push_back(value_type c)
-            {
-                ensure_free_space_(1);
-                traits_type::assign(data_[size_++], c);
-                ensure_null_terminator_();
-            }
-
-            basic_string& assign(const basic_string& str)
-            {
-                return assign(str, 0, npos);
-            }
-
-            basic_string& assign(basic_string&& str)
-            {
-                swap(str);
-
-                return *this;
-            }
-
-            basic_string& assign(const basic_string& str, size_type pos,
-                                 size_type n = npos)
-            {
-                if (pos < str.size())
-                {
-                    auto len = min(n, str.size() - pos);
-                    ensure_free_space_(len);
-
-                    return assign(str.data() + pos, len);
-                }
-                // TODO: Else throw out_of_range.
-
-                return *this;
-            }
-
-            basic_string& assign(const value_type* str, size_type n)
-            {
-                // TODO: if (n > max_size()) throw length_error.
-                resize_without_copy_(n);
-                traits_type::copy(begin(), str, n);
-                size_ = n;
-                ensure_null_terminator_();
-
-                return *this;
-            }
-
-            basic_string& assign(const value_type* str)
-            {
-                return assign(str, traits_type::length(str));
-            }
-
-            basic_string& assign(size_type n, value_type c)
-            {
-                return assign(basic_string(n, c));
-            }
-
-            template<class InputIterator>
-            basic_string& assign(InputIterator first, InputIterator last)
-            {
-                return assign(basic_string(first, last));
-            }
-
-            basic_string& assign(initializer_list<value_type> init)
-            {
-                return assign(init.begin(), init.size());
-            }
-
-            basic_string& insert(size_type pos, const basic_string& str)
-            {
-                // TODO: if (pos > str.size()) throw out_of_range.
-                return insert(pos, str.data(), str.size());
-            }
-
-            basic_string& insert(size_type pos1, const basic_string& str,
-                                 size_type pos2, size_type n = npos)
-            {
-                // TODO: if (pos1 > size() or pos2 > str.size()) throw
-                //       out_of_range.
-                auto len = min(n, str.size() - pos2);
-
-                return insert(pos1, str.data() + pos2, len);
-            }
-
-            basic_string& insert(size_type pos, const value_type* str, size_type n)
-            {
-                // TODO: throw out_of_range if pos > size()
-                // TODO: throw length_error if size() + n > max_size()
-                ensure_free_space_(n);
-
-                copy_backward_(begin() + pos, end(), end() + n);
-                copy_(str, str + n, begin() + pos);
-                size_ += n;
-
-                ensure_null_terminator_();
-                return *this;
-            }
-
-            basic_string& insert(size_type pos, const value_type* str)
-            {
-                return insert(pos, str, traits_type::length(str));
-            }
-
-            basic_string& insert(size_type pos, size_type n, value_type c)
-            {
-                return insert(pos, basic_string(n, c));
-            }
-
-            iterator insert(const_iterator pos, value_type c)
-            {
-                auto idx = static_cast<size_type>(pos - begin());
-
-                ensure_free_space_(1);
-                copy_backward_(begin() + idx, end(), end() + 1);
-                traits_type::assign(data_[idx], c);
-
-                ++size_;
-                ensure_null_terminator_();
-
-                return begin() + idx;
-            }
-
-            iterator insert(const_iterator pos, size_type n, value_type c)
-            {
-                if (n == 0)
-                    return const_cast<iterator>(pos);
-
-                auto idx = static_cast<size_type>(pos - begin());
-
-                ensure_free_space_(n);
-                copy_backward_(begin() + idx, end(), end() + n);
-
-                auto it = begin() + idx;
-                for (size_type i = 0; i < n; ++i)
-                    traits_type::assign(*it++, c);
-                size_ += n;
-                ensure_null_terminator_();
-
-                return begin() + idx;
-            }
-
-            template<class InputIterator>
-            iterator insert(const_iterator pos, InputIterator first,
-                            InputIterator last)
-            {
-                if (first == last)
-                    return const_cast<iterator>(pos);
-
-                auto idx = static_cast<size_type>(pos - begin());
-                auto str = basic_string{first, last};
-                insert(idx, str);
-
-                return begin() + idx;
-            }
-
-            iterator insert(const_iterator pos, initializer_list<value_type> init)
-            {
-                return insert(pos, init.begin(), init.end());
-            }
-
-            basic_string& erase(size_type pos = 0, size_type n = npos)
-            {
-                auto len = min(n, size_ - pos);
-                copy_(begin() + pos + n, end(), begin() + pos);
-                size_ -= len;
-                ensure_null_terminator_();
-
-                return *this;
-            }
-
-            iterator erase(const_iterator pos)
-            {
-                auto idx = static_cast<size_type>(pos - cbegin());
-                erase(idx, 1);
-
-                return begin() + idx;
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                auto idx = static_cast<size_type>(first - cbegin());
-                auto count = static_cast<size_type>(last - first);
-                erase(idx, count);
-
-                return begin() + idx;
-            }
-
-            void pop_back()
-            {
-                --size_;
-                ensure_null_terminator_();
-            }
-
-            basic_string& replace(size_type pos, size_type n, const basic_string& str)
-            {
-                // TODO: throw out_of_range if pos > size()
-                return replace(pos, n, str.data(), str.size());
-            }
-
-            basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
-                                  size_type pos2, size_type n2 = npos)
-            {
-                // TODO: throw out_of_range if pos1 > size() or pos2 > str.size()
-                auto len = min(n2, str.size() - pos2);
-                return replace(pos1, n1, str.data() + pos2, len);
-            }
-
-            basic_string& replace(size_type pos, size_type n1, const value_type* str,
-                                  size_type n2)
-            {
-                // TODO: throw out_of_range if pos > size()
-                // TODO: if size() - len > max_size() - n2 throw length_error
-                auto len = min(n1, size_ - pos);
-
-                basic_string tmp{};
-                tmp.resize_without_copy_(size_ - len + n2);
-
-                // Prefix.
-                copy_(begin(), begin() + pos, tmp.begin());
-
-                // Substitution.
-                traits_type::copy(tmp.begin() + pos, str, n2);
-
-                // Suffix.
-                copy_(begin() + pos + len, end(), tmp.begin() + pos + n2);
-
-                tmp.size_ = size_ - len + n2;
-                swap(tmp);
-                return *this;
-            }
-
-            basic_string& replace(size_type pos, size_type n, const value_type* str)
-            {
-                return replace(pos, n, str, traits_type::length(str));
-            }
-
-            basic_string& replace(size_type pos, size_type n1, size_type n2,
-                                  value_type c)
-            {
-                return replace(pos, n1, basic_string(n2, c));
-            }
-
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  const basic_string& str)
-            {
-                return replace(i1 - begin(), i2 - i1, str);
-            }
-
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  const value_type* str, size_type n)
-            {
-                return replace(i1 - begin(), i2 - i1, str, n);
-            }
-
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  const value_type* str)
-            {
-                return replace(i1 - begin(), i2 - i1, str, traits_type::length(str));
-            }
-
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  size_type n, value_type c)
-            {
-                return replace(i1 - begin(), i2 - i1, basic_string(n, c));
-            }
-
-            template<class InputIterator>
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  InputIterator j1, InputIterator j2)
-            {
-                return replace(i1 - begin(), i2 - i1, basic_string(j1, j2));
-            }
-
-            basic_string& replace(const_iterator i1, const_iterator i2,
-                                  initializer_list<value_type> init)
-            {
-                return replace(i1 - begin(), i2 - i1, init.begin(), init.size());
-            }
-
-            size_type copy(value_type* str, size_type n, size_type pos = 0) const
-            {
-                auto len = min(n , size_ - pos);
-                for (size_type i = 0; i < len; ++i)
-                    traits_type::assign(str[i], data_[pos + i]);
-
-                return len;
-            }
-
-            void swap(basic_string& other)
-                noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
-                         allocator_traits<allocator_type>::is_always_equal::value)
-            {
-                std::swap(data_, other.data_);
-                std::swap(size_, other.size_);
-                std::swap(capacity_, other.capacity_);
-            }
-
-            /**
-             * 21.4.7, string operations:
-             */
-
-            const value_type* c_str() const noexcept
-            {
-                return data_;
-            }
-
-            const value_type* data() const noexcept
-            {
-                return data_;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_type{allocator_};
-            }
-
-            /**
-             * Note: The following find functions have 4 versions each:
-             *       (1) takes basic_string
-             *       (2) takes c string and length
-             *       (3) takes c string
-             *       (4) takes value_type
-             *       According to the C++14 standard, only (1) is marked as
-             *       noexcept and the other three return the first one with
-             *       a newly allocated strings (and thus cannot be noexcept).
-             *       However, allocating a new string results in memory
-             *       allocation and copying of the source and thus we have
-             *       decided to follow C++17 signatures of these functions
-             *       (i.e. all of them being marked as noexcept) and use
-             *       (2) for the actual implementation (and avoiding any
-             *       allocations or copying in the process and also providing
-             *       stronger guarantees to the user).
-             */
-
-            size_type find(const basic_string& str, size_type pos = 0) const noexcept
-            {
-                return find(str.c_str(), pos, str.size());
-            }
-
-            size_type find(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty() || len == 0 || len + pos > size())
-                    return npos;
-
-                size_type idx{pos};
-
-                while (idx + len < size_)
-                {
-                    if (substr_starts_at_(idx, str, len))
-                        return idx;
-                    ++idx;
-                }
-
-                return npos;
-            }
-
-            size_type find(const value_type* str, size_type pos = 0) const noexcept
-            {
-                return find(str, pos, traits_type::length(str));
-            }
-
-            size_type find(value_type c, size_type pos = 0) const noexcept
-            {
-                if (empty())
-                    return npos;
-
-                for (size_type i = pos; i < size_; ++i)
-                {
-                    if (traits_type::eq(c, data_[i]))
-                        return i;
-                }
-
-                return npos;
-            }
-
-            size_type rfind(const basic_string& str, size_type pos = npos) const noexcept
-            {
-                return rfind(str.c_str(), pos, str.size());
-            }
-
-            size_type rfind(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty() || len == 0 || len + pos > size())
-                    return npos;
-
-                size_type idx{min(pos, size_ - 1) + 1};
-
-                while (idx > 0)
-                {
-                    if (substr_starts_at_(idx - 1, str, len))
-                        return idx - 1;
-                    --idx;
-                }
-
-                return npos;
-            }
-
-            size_type rfind(const value_type* str, size_type pos = npos) const noexcept
-            {
-                return rfind(str, pos, traits_type::length(str));
-            }
-
-            size_type rfind(value_type c, size_type pos = npos) const noexcept
-            {
-                if (empty())
-                    return npos;
-
-                for (size_type i = min(pos + 1, size_ - 1) + 1; i > 0; --i)
-                {
-                    if (traits_type::eq(c, data_[i - 1]))
-                        return i - 1;
-                }
-
-                return npos;
-            }
-
-            size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept
-            {
-                return find_first_of(str.c_str(), pos, str.size());
-            }
-
-            size_type find_first_of(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty() || len == 0 || pos >= size())
-                    return npos;
-
-                size_type idx{pos};
-
-                while (idx < size_)
-                {
-                    if (is_any_of_(idx, str, len))
-                        return idx;
-                    ++idx;
-                }
-
-                return npos;
-            }
-
-            size_type find_first_of(const value_type* str, size_type pos = 0) const noexcept
-            {
-                return find_first_of(str, pos, traits_type::length(str));
-            }
-
-            size_type find_first_of(value_type c, size_type pos = 0) const noexcept
-            {
-                return find(c, pos);
-            }
-
-            size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept
-            {
-                return find_last_of(str.c_str(), pos, str.size());
-            }
-
-            size_type find_last_of(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty() || len == 0)
-                    return npos;
-
-                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
-                {
-                    if (is_any_of_(i - 1, str, len))
-                        return i - 1;
-                }
-
-                return npos;
-            }
-
-            size_type find_last_of(const value_type* str, size_type pos = npos) const noexcept
-            {
-                return find_last_of(str, pos, traits_type::length(str));
-            }
-
-            size_type find_last_of(value_type c, size_type pos = npos) const noexcept
-            {
-                return rfind(c, pos);
-            }
-
-            size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept
-            {
-                return find_first_not_of(str.c_str(), pos, str.size());
-            }
-
-            size_type find_first_not_of(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty() || pos >= size())
-                    return npos;
-
-                size_type idx{pos};
-
-                while (idx < size_)
-                {
-                    if (!is_any_of_(idx, str, len))
-                        return idx;
-                    ++idx;
-                }
-
-                return npos;
-            }
-
-            size_type find_first_not_of(const value_type* str, size_type pos = 0) const noexcept
-            {
-                return find_first_not_of(str, pos, traits_type::length(str));
-            }
-
-            size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept
-            {
-                if (empty())
-                    return npos;
-
-                for (size_type i = pos; i < size_; ++i)
-                {
-                    if (!traits_type::eq(c, data_[i]))
-                        return i;
-                }
-
-                return npos;
-            }
-
-            size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept
-            {
-                return find_last_not_of(str.c_str(), pos, str.size());
-            }
-
-            size_type find_last_not_of(const value_type* str, size_type pos, size_type len) const noexcept
-            {
-                if (empty())
-                    return npos;
-
-                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
-                {
-                    if (!is_any_of_(i - 1, str, len))
-                        return i - 1;
-                }
-
-                return npos;
-            }
-
-            size_type find_last_not_of(const value_type* str, size_type pos = npos) const noexcept
-            {
-                return find_last_not_of(str, pos, traits_type::length(str));
-            }
-
-            size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept
-            {
-                if (empty())
-                    return npos;
-
-                pos = min(pos, size_ - 1);
-
-                for (size_type i = min(pos, size_ - 1) + 1; i > 1; --i)
-                {
-                    if (!traits_type::eq(c, data_[i - 1]))
-                        return i - 1;
-                }
-
-                return npos;
-            }
-
-            basic_string substr(size_type pos = 0, size_type n = npos) const
-            {
-                // TODO: throw out_of_range if pos > size().
-                auto len = min(n, size_ - pos);
-                return basic_string{data() + pos, len};
-            }
-
-            int compare(const basic_string& other) const noexcept
-            {
-                auto len = min(size(), other.size());
-                auto comp = traits_type::compare(data_, other.data(), len);
-
-                if (comp != 0)
-                    return comp;
-                else if (size() == other.size())
-                    return 0;
-                else if (size() > other.size())
-                    return 1;
-                else
-                    return -1;
-            }
-
-            int compare(size_type pos, size_type n, const basic_string& other) const
-            {
-                return basic_string{*this, pos, n}.compare(other);
-            }
-
-            int compare(size_type pos1, size_type n1, const basic_string& other,
-                        size_type pos2, size_type n2 = npos) const
-            {
-                return basic_string{*this, pos1, n1}.compare(basic_string{other, pos2, n2});
-            }
-
-            int compare(const value_type* other) const
-            {
-                return compare(basic_string(other));
-            }
-
-            int compare(size_type pos, size_type n, const value_type* other) const
-            {
-                return basic_string{*this, pos, n}.compare(basic_string{other});
-            }
-
-            int compare(size_type pos, size_type n1,
-                        const value_type* other, size_type n2) const
-            {
-                return basic_string{*this, pos, n1}.compare(basic_string{other, n2});
-            }
-
-        private:
-            value_type* data_;
-            size_type size_;
-            size_type capacity_;
-            allocator_type allocator_;
-
-            template<class C, class T, class A>
-            friend class basic_stringbuf;
-
-            /**
-             * Arbitrary value, standard just requires
-             * data() to have some capacity.
-             * (Well, we could've done data_ = &data_ and
-             * set capacity to 0, but that would be too cryptic.)
-             */
-            static constexpr size_type default_capacity_{4};
-
-            void init_(const value_type* str, size_type size)
-            {
-                if (data_)
-                    allocator_.deallocate(data_, capacity_);
-
-                size_ = size;
-                capacity_ = size + 1;
-
-                data_ = allocator_.allocate(capacity_);
-                traits_type::copy(data_, str, size);
-                ensure_null_terminator_();
-            }
-
-            size_type next_capacity_(size_type hint = 0) const noexcept
-            {
-                if (hint != 0)
-                    return max(capacity_ * 2, hint);
-                else
-                    return max(capacity_ * 2, 2ul);
-            }
-
-            void ensure_free_space_(size_type n)
-            {
-                /**
-                 * Note: We cannot use reserve like we
-                 *       did in vector, because in string
-                 *       reserve can cause shrinking.
-                 */
-                if (size_ + 1 + n > capacity_)
-                    resize_with_copy_(size_, max(size_ + 1 + n, next_capacity_()));
-            }
-
-            void resize_without_copy_(size_type capacity)
-            {
-                if (data_)
-                    allocator_.deallocate(data_, capacity_);
-
-                data_ = allocator_.allocate(capacity);
-                size_ = 0;
-                capacity_ = capacity;
-                ensure_null_terminator_();
-            }
-
-            void resize_with_copy_(size_type size, size_type capacity)
-            {
-                if(capacity_ == 0 || capacity_ < capacity)
-                {
-                    auto new_data = allocator_.allocate(capacity);
-
-                    auto to_copy = min(size, size_);
-                    traits_type::move(new_data, data_, to_copy);
-
-                    std::swap(data_, new_data);
-
-                    allocator_.deallocate(new_data, capacity_);
-                }
-
-                capacity_ = capacity;
-                size_ = size;
-                ensure_null_terminator_();
-            }
-
-            template<class Iterator1, class Iterator2>
-            Iterator2 copy_(Iterator1 first, Iterator1 last,
-                            Iterator2 result)
-            {
-                while (first != last)
-                    traits_type::assign(*result++, *first++);
-
-                return result;
-            }
-
-            template<class Iterator1, class Iterator2>
-            Iterator2 copy_backward_(Iterator1 first, Iterator1 last,
-                                     Iterator2 result)
-            {
-                while (last != first)
-                    traits_type::assign(*--result, *--last);
-
-                return result;
-            }
-
-            void ensure_null_terminator_()
-            {
-                value_type c{};
-                traits_type::assign(data_[size_], c);
-            }
-
-            bool is_any_of_(size_type idx, const value_type* str, size_type len) const
-            {
-                for (size_type i = 0; i < len; ++i)
-                {
-                    if (traits_type::eq(data_[idx], str[i]))
-                        return true;
-                }
-
-                return false;
-            }
-
-            bool substr_starts_at_(size_type idx, const value_type* str, size_type len) const
-            {
-                size_type i{};
-                for (i = 0; i < len; ++i)
-                {
-                    if (!traits_type::eq(data_[idx + i], str[i]))
-                        break;
-                }
-
-                return i == len;
-            }
-    };
-
-    using string    = basic_string<char>;
-    using u16string = basic_string<char16_t>;
-    using u32string = basic_string<char32_t>;
-    using wstring   = basic_string<wchar_t>;
-
-    /**
-     * 21.4.8, basic_string non-member functions:
-     */
-
-    /**
-     * 21.4.8.1, operator+:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const basic_string<Char, Traits, Allocator>& lhs,
-              const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return basic_string<Char, Traits, Allocator>{lhs}.append(rhs);
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(basic_string<Char, Traits, Allocator>&& lhs,
-              const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return move(lhs.append(rhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const basic_string<Char, Traits, Allocator>& lhs,
-              basic_string<Char, Traits, Allocator>&& rhs)
-    {
-        return move(rhs.insert(0, lhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(basic_string<Char, Traits, Allocator>&& lhs,
-              basic_string<Char, Traits, Allocator>&& rhs)
-    {
-        return move(lhs.append(rhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const Char* lhs,
-              const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return basic_string<Char, Traits, Allocator>{lhs} + rhs;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const Char* lhs,
-              basic_string<Char, Traits, Allocator>&& rhs)
-    {
-        return move(rhs.insert(0, lhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(Char lhs,
-              const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return basic_string<Char, Traits, Allocator>{1, lhs}.append(rhs);
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(Char lhs,
-              basic_string<Char, Traits, Allocator>&& rhs)
-    {
-        return move(rhs.insert(0, 1, lhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const basic_string<Char, Traits, Allocator>& lhs,
-              const Char* rhs)
-    {
-        return lhs + basic_string<Char, Traits, Allocator>{rhs};
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(basic_string<Char, Traits, Allocator>&& lhs,
-              const Char* rhs)
-    {
-        return move(lhs.append(rhs));
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(const basic_string<Char, Traits, Allocator>& lhs,
-              Char rhs)
-    {
-        return lhs + basic_string<Char, Traits, Allocator>{1, rhs};
-    }
-
-    template<class Char, class Traits, class Allocator>
-    basic_string<Char, Traits, Allocator>
-    operator+(basic_string<Char, Traits, Allocator>&& lhs,
-              Char rhs)
-    {
-        return move(lhs.append(1, rhs));
-    }
-
-    /**
-     * 21.4.8.2, operator==:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator==(const basic_string<Char, Traits, Allocator>& lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return lhs.compare(rhs) == 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator==(const Char* lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs == lhs;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator==(const basic_string<Char, Traits, Allocator>& lhs,
-                    const Char* rhs)
-    {
-        return lhs.compare(rhs) == 0;
-    }
-
-    /**
-     * 21.4.8.3, operator!=:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator!=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator!=(const Char* lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs != lhs;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator!=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const Char* rhs)
-    {
-        return lhs.compare(rhs) != 0;
-    }
-
-    /**
-     * 21.4.8.4, operator<:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<(const basic_string<Char, Traits, Allocator>& lhs,
-                   const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return lhs.compare(rhs) < 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<(const Char* lhs,
-                   const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs.compare(lhs) > 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<(const basic_string<Char, Traits, Allocator>& lhs,
-                   const Char* rhs)
-    {
-        return lhs.compare(rhs) < 0;
-    }
-
-    /**
-     * 21.4.8.5, operator>:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>(const basic_string<Char, Traits, Allocator>& lhs,
-                   const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return lhs.compare(rhs) > 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>(const Char* lhs,
-                   const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs.compare(lhs) < 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>(const basic_string<Char, Traits, Allocator>& lhs,
-                   const Char* rhs)
-    {
-        return lhs.compare(rhs) > 0;
-    }
-
-    /**
-     * 21.4.8.6, operator<=:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return lhs.compare(rhs) <= 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<=(const Char* lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs.compare(lhs) >= 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator<=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const Char* rhs)
-    {
-        return lhs.compare(rhs) <= 0;
-    }
-
-    /**
-     * 21.4.8.7, operator>=:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs) noexcept
-    {
-        return lhs.compare(rhs) >= 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>=(const Char* lhs,
-                    const basic_string<Char, Traits, Allocator>& rhs)
-    {
-        return rhs.compare(lhs) <= 0;
-    }
-
-    template<class Char, class Traits, class Allocator>
-    bool operator>=(const basic_string<Char, Traits, Allocator>& lhs,
-                    const Char* rhs)
-    {
-        return lhs.compare(rhs) >= 0;
-    }
-
-    /**
-     * 21.4.8.8, swap:
-     */
-
-    template<class Char, class Traits, class Allocator>
-    void swap(basic_string<Char, Traits, Allocator>& lhs,
-              basic_string<Char, Traits, Allocator>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 21.5, numeric conversions:
-     */
-
-    int stoi(const string& str, size_t* idx = nullptr, int base = 10);
-    long stol(const string& str, size_t* idx = nullptr, int base = 10);
-    unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10);
-    long long stoll(const string& str, size_t* idx = nullptr, int base = 10);
-    unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
-
-    float stof(const string& str, size_t* idx = nullptr);
-    double stod(const string& str, size_t* idx = nullptr);
-    long double stold(const string& str, size_t* idx = nullptr);
-
-    string to_string(int val);
-    string to_string(unsigned val);
-    string to_string(long val);
-    string to_string(unsigned long val);
-    string to_string(long long val);
-    string to_string(unsigned long long val);
-    string to_string(float val);
-    string to_string(double val);
-    string to_string(long double val);
-
-    int stoi(const wstring& str, size_t* idx = nullptr, int base = 10);
-    long stol(const wstring& str, size_t* idx = nullptr, int base = 10);
-    unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10);
-    long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10);
-    unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
-
-    float stof(const wstring& str, size_t* idx = nullptr);
-    double stod(const wstring& str, size_t* idx = nullptr);
-    long double stold(const wstring& str, size_t* idx = nullptr);
-
-    wstring to_wstring(int val);
-    wstring to_wstring(unsigned val);
-    wstring to_wstring(long val);
-    wstring to_wstring(unsigned long val);
-    wstring to_wstring(long long val);
-    wstring to_wstring(unsigned long long val);
-    wstring to_wstring(float val);
-    wstring to_wstring(double val);
-    wstring to_wstring(long double val);
-
-    /**
-     * 21.6, hash support:
-     */
-
-    template<class>
-    struct hash;
-
-    template<>
-    struct hash<string>
-    {
-        size_t operator()(const string& str) const noexcept
-        {
-            size_t res{};
-
-            /**
-             * Note: No need for fancy algorithms here,
-             *       std::hash is used for indexing, not
-             *       cryptography.
-             */
-            for (const auto& c: str)
-                res = res * 5 + (res >> 3) + static_cast<size_t>(c);
-
-            return res;
-        }
-
-        using argument_type = string;
-        using result_type   = size_t;
-    };
-
-    template<>
-    struct hash<wstring>
-    {
-        size_t operator()(const wstring& str) const noexcept
-        {
-            // TODO: implement
-            return size_t{};
-        }
-
-        using argument_type = wstring;
-        using result_type   = size_t;
-    };
-
-    // TODO: add those other 2 string types
-
-    /**
-     * 21.7, suffix for basic_string literals:
-     */
-
-    /**
-     * Note: According to the standard, literal suffixes that do not
-     *       start with an underscore are reserved for future standardization,
-     *       but since we are implementing the standard, we're going to ignore it.
-     *       This should work (according to their documentation) work for clang,
-     *       but that should be tested.
-     */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wliteral-suffix"
-inline namespace literals {
-inline namespace string_literals
-{
-    string operator "" s(const char* str, size_t len);
-    u16string operator "" s(const char16_t* str, size_t len);
-    u32string operator "" s(const char32_t* str, size_t len);
-
-    /* Problem: wchar_t == int in HelenOS, but standard forbids it.
-    wstring operator "" s(const wchar_t* str, size_t len);
-    */
-}}
-#pragma GCC diagnostic pop
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/system_error.hpp
===================================================================
--- uspace/lib/cpp/include/impl/system_error.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,367 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_SYSTEM_ERROR
-#define LIBCPP_SYSTEM_ERROR
-
-#include <__bits/aux.hpp>
-#include <__bits/stringfwd.hpp>
-#include <stdexcept>
-
-namespace std
-{
-    class error_condition;
-    class error_code;
-
-    enum class errc
-    { // TODO: add matching values
-        address_family_not_supported,
-        address_in_use,
-        address_not_available,
-        already_connected,
-        argument_list_too_long,
-        argument_out_of_domain,
-        bad_address,
-        bad_file_descriptor,
-        bad_message,
-        broken_pipe,
-        connection_aborted,
-        connection_already_in_progress,
-        connection_refused,
-        connection_reset,
-        cross_device_link,
-        destination_address_required,
-        device_or_resource_busy,
-        directory_not_empty,
-        executable_format_error,
-        file_exists,
-        file_too_large,
-        filename_too_long,
-        function_not_supported,
-        host_unreachable,
-        identifier_removed,
-        illegal_byte_sequence,
-        inappropriate_io_control_operation,
-        interrupted,
-        invalid_argument,
-        invalid_seek,
-        io_error,
-        is_a_directory,
-        message_size,
-        network_down,
-        network_reset,
-        network_unreachable,
-        no_buffer_space,
-        no_child_process,
-        no_link,
-        no_lock_available,
-        no_message_available,
-        no_message,
-        no_protocol_option,
-        no_space_on_device,
-        no_stream_resources,
-        no_such_device_or_address,
-        no_such_device,
-        no_such_file_or_directory,
-        no_such_process,
-        not_a_directory,
-        not_a_socket,
-        not_a_stream,
-        not_connected,
-        not_enough_memory,
-        not_supported,
-        operation_canceled,
-        operation_in_progress,
-        operation_not_permitted,
-        operation_not_supported,
-        operation_would_block,
-        owner_dead,
-        permission_denied,
-        protocol_error,
-        protocol_not_supported,
-        read_only_file_system,
-        resource_deadlock_would_occur,
-        resource_unavailable_try_again,
-        result_out_of_range,
-        state_not_recoverable,
-        stream_timeout,
-        text_file_busy,
-        timed_out,
-        too_many_files_open_in_system,
-        too_many_files_open,
-        too_many_links,
-        too_many_symbolic_link_levels,
-        value_too_large,
-        wrong_protocol_type
-    };
-
-    template<class>
-    struct is_error_code_enum: false_type
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct is_error_code_enum<errc>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
-
-    template<class>
-    struct is_error_condition_enum: false_type
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct is_error_condition_enum<errc>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value;
-
-    /**
-     * 19.5.1, class error_category:
-     */
-
-    class error_category
-    {
-        public:
-            constexpr error_category() noexcept = default;
-            virtual ~error_category();
-
-            error_category(const error_category&) = delete;
-            error_category& operator=(const error_category&) = delete;
-
-            virtual const char* name() const noexcept = 0;
-            virtual error_condition default_error_condition(int) const noexcept;
-            virtual bool equivalent(int, const error_condition&) const noexcept;
-            virtual bool equivalent(const error_code&, int) const noexcept;
-            virtual string message(int) const = 0;
-
-            bool operator==(const error_category&) const noexcept;
-            bool operator!=(const error_category&) const noexcept;
-            bool operator<(const error_category&) const noexcept;
-    };
-
-    const error_category& generic_category() noexcept;
-    const error_category& system_category() noexcept;
-
-    /**
-     * 19.5.2, class error_code:
-     */
-
-    class error_code
-    {
-        public:
-            /**
-             * 19.5.2.2, constructors:
-             */
-
-            error_code() noexcept;
-            error_code(int, const error_category&) noexcept;
-
-            template<class ErrorCodeEnum>
-            error_code(
-                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
-            ) noexcept
-            {
-                val_ = static_cast<int>(e);
-                cat_ = &generic_category();
-            }
-
-            /**
-             * 19.5.2.3, modifiers:
-             */
-
-            void assign(int, const error_category&) noexcept;
-
-            template<class ErrorCodeEnum>
-            error_code& operator=(
-                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
-            ) noexcept
-            {
-                val_ = static_cast<int>(e);
-                cat_ = &generic_category();
-
-                return *this;
-            }
-
-            void clear() noexcept;
-
-            /**
-             * 19.5.2.4, observers:
-             */
-
-            int value() const noexcept;
-            const error_category& category() const noexcept;
-            error_condition default_error_condition() const noexcept;
-            string message() const;
-
-            explicit operator bool() const noexcept
-            {
-                return val_ != 0;
-            }
-
-        private:
-            int val_;
-            const error_category* cat_;
-    };
-
-    /**
-     * 19.5.2.5, non-member functions:
-     */
-
-    error_code make_error_code(errc e) noexcept;
-    bool operator<(const error_code&, const error_code&) noexcept;
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const error_code& ec)
-    {
-        return os << ec.category().name() << ": " << ec.value();
-    }
-
-    /**
-     * 19.5.3, class error_condition:
-     */
-
-    class error_condition
-    {
-        public:
-            /**
-             * 19.5.3.2, constructors:
-             */
-
-            error_condition() noexcept;
-            error_condition(int, const error_category&) noexcept;
-
-            template<class ErrorCodeEnum>
-            error_condition(
-                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
-            ) noexcept
-            {
-                val_ = static_cast<int>(e);
-                cat_ = &generic_category();
-            }
-
-            /**
-             * 19.5.3.3, modifiers:
-             */
-
-            void assign(int, const error_category&) noexcept;
-
-            template<class ErrorCodeEnum>
-            error_condition& operator=(
-                enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
-            ) noexcept
-            {
-                val_ = static_cast<int>(e);
-                cat_ = &generic_category();
-
-                return *this;
-            }
-
-            void clear() noexcept;
-
-            /**
-             * 19.5.3.4, observers:
-             */
-
-            int value() const noexcept;
-            const error_category& category() const noexcept;
-            string message() const;
-
-            explicit operator bool() const noexcept
-            {
-                return val_ != 0;
-            }
-
-        private:
-            int val_;
-            const error_category* cat_;
-    };
-
-    /**
-     * 19.5.3.4, non-member functions:
-     */
-
-    error_condition make_error_condition(errc e) noexcept;
-    bool operator<(const error_condition&, const error_condition&) noexcept;
-
-    /**
-     * 19.5.4, comparison operators:
-     */
-
-    bool operator==(const error_code&, const error_code&) noexcept;
-    bool operator==(const error_code&, const error_condition&) noexcept;
-    bool operator==(const error_condition&, const error_code&) noexcept;
-    bool operator==(const error_condition&, const error_condition&) noexcept;
-    bool operator!=(const error_code&, const error_code&) noexcept;
-    bool operator!=(const error_code&, const error_condition&) noexcept;
-    bool operator!=(const error_condition&, const error_code&) noexcept;
-    bool operator!=(const error_condition&, const error_condition&) noexcept;
-
-    /**
-     * 19.5.6, class system_error:
-     */
-
-    class system_error: public runtime_error
-    {
-        public:
-            system_error(error_code, const string&);
-            system_error(error_code, const char*);
-            system_error(error_code);
-            system_error(int, const error_category&, const string&);
-            system_error(int, const error_category&, const char*);
-            system_error(int, const error_category&);
-
-            const error_code& code() const noexcept;
-
-        private:
-            error_code code_;
-    };
-
-    /**
-     * 19.5.5, hash support:
-     */
-
-    template<class>
-    struct hash;
-
-    template<>
-    struct hash<error_code>
-    {
-        size_t operator()(const error_code& ec) const noexcept
-        {
-            return static_cast<size_t>(ec.value());
-        }
-
-        using result_type   = size_t;
-        using argument_type = error_code;
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/thread.hpp
===================================================================
--- uspace/lib/cpp/include/impl/thread.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,294 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_THREAD
-#define LIBCPP_THREAD
-
-#include <chrono>
-#include <__bits/common.hpp>
-#include <__bits/thread.hpp>
-#include <ostream>
-
-namespace std
-{
-    namespace aux
-    {
-        template<class Callable>
-        int thread_main(void*);
-
-        /**
-         * Fibrils in HelenOS are not joinable. They were
-         * in the past, but that functionality was removed from them
-         * so we created a workaround using a conditional variable that
-         * comprises the following two wrapper classes.
-         */
-        class joinable_wrapper
-        {
-            public:
-                joinable_wrapper()
-                    : join_mtx_{}, join_cv_{},
-                      finished_{false}, detached_{false}
-                {
-                    aux::threading::mutex::init(join_mtx_);
-                    aux::threading::condvar::init(join_cv_);
-                }
-
-                void join()
-                {
-                    aux::threading::mutex::lock(join_mtx_);
-                    while (!finished_)
-                        aux::threading::condvar::wait(join_cv_, join_mtx_);
-                    aux::threading::mutex::unlock(join_mtx_);
-                }
-
-                bool finished() const
-                {
-                    return finished_;
-                }
-
-                void detach()
-                {
-                    detached_ = true;
-                }
-
-                bool detached() const
-                {
-                    return detached_;
-                }
-
-            protected:
-                aux::mutex_t join_mtx_;
-                aux::condvar_t join_cv_;
-                bool finished_;
-                bool detached_;
-        };
-
-        template<class Callable>
-        class callable_wrapper: public joinable_wrapper
-        {
-            public:
-                callable_wrapper(Callable&& clbl)
-                    : joinable_wrapper{}, callable_{forward<Callable>(clbl)}
-                { /* DUMMY BODY */ }
-
-                void operator()()
-                {
-                    callable_();
-
-                    aux::threading::mutex::lock(join_mtx_);
-                    finished_ = true;
-                    aux::threading::mutex::unlock(join_mtx_);
-
-                    aux::threading::condvar::broadcast(join_cv_);
-                }
-
-            private:
-                Callable callable_;
-        };
-    }
-
-    /**
-     * 30.3.1, class thread:
-     */
-
-    class thread
-    {
-        public:
-            class id;
-
-            using native_handle_type = aux::thread_t*;
-
-            /**
-             * 30.3.1.2, thread constructors:
-             * 30.3.1.3, thread destructor:
-             * 30.3.1.4, thread assignment:
-             */
-
-            thread() noexcept;
-
-            ~thread();
-
-            // TODO: check the remark in the standard
-            template<class F, class... Args>
-            explicit thread(F&& f, Args&&... args)
-                : id_{}
-            {
-                auto callable = [=](){
-                    return f(forward<Args>(args)...);
-                };
-
-                auto callable_wrapper = new aux::callable_wrapper<decltype(callable)>{move(callable)};
-                joinable_wrapper_ = static_cast<aux::joinable_wrapper*>(callable_wrapper);
-
-                id_ = aux::threading::thread::create(
-                    aux::thread_main<decltype(callable_wrapper)>,
-                    *callable_wrapper
-                );
-
-                aux::threading::thread::start(id_);
-                // TODO: fibrils are weird here, 2 returns with same thread ids
-            }
-
-            thread(const thread&) = delete;
-            thread& operator=(const thread&) = delete;
-
-            thread(thread&& other) noexcept;
-            thread& operator=(thread&& other) noexcept;
-
-            /**
-             * 30.3.1.5, thread members:
-             */
-
-            void swap(thread& other) noexcept;
-
-            bool joinable() const noexcept;
-
-            void join();
-
-            void detach();
-
-            id get_id() const noexcept;
-
-            native_handle_type native_handle();
-
-            static unsigned hardware_concurrency() noexcept;
-
-        private:
-            aux::thread_t id_;
-            aux::joinable_wrapper* joinable_wrapper_{nullptr};
-
-            template<class Callable>
-            friend int aux::thread_main(void*);
-    };
-
-    namespace aux
-    {
-        template<class CallablePtr>
-        int thread_main(void* clbl)
-        {
-            if (!clbl)
-                return 1;
-
-            auto callable = static_cast<CallablePtr>(clbl);
-            (*callable)();
-
-            if (callable->detached())
-                delete callable;
-
-            return 0;
-        }
-    }
-
-    void swap(thread& x, thread& y) noexcept;
-
-    /**
-     * 30.3.2, namespace this_thread:
-     */
-
-    namespace this_thread
-    {
-        thread::id get_id() noexcept;
-
-        void yield() noexcept;
-
-        template<class Clock, class Duration>
-        void sleep_until(const chrono::time_point<Clock, Duration>& abs_time)
-        {
-            auto now = Clock::now();
-
-            auto time = aux::threading::time::convert(abs_time - now);
-            aux::threading::time::sleep(time);
-        }
-
-        template<class Rep, class Period>
-        void sleep_for(const chrono::duration<Rep, Period>& rel_time)
-        {
-            if (rel_time <= chrono::duration<Rep, Period>::zero())
-                return;
-
-            // TODO: timeouts?
-            auto time = aux::threading::time::convert(rel_time);
-            aux::threading::time::sleep(time);
-        }
-    }
-
-    template<class T>
-    struct hash;
-
-    class thread::id
-    {
-        public:
-            constexpr id() noexcept
-                : id_{}
-            { /* DUMMY BODY */ }
-
-        private:
-            aux::thread_t id_;
-
-            id(aux::thread_t id)
-                : id_{id}
-            { /* DUMMY BODY */ }
-
-            friend class thread;
-
-            friend bool operator==(thread::id, thread::id) noexcept;
-            friend bool operator!=(thread::id, thread::id) noexcept;
-            friend bool operator<(thread::id, thread::id) noexcept;
-            friend bool operator<=(thread::id, thread::id) noexcept;
-            friend bool operator>(thread::id, thread::id) noexcept;
-            friend bool operator>=(thread::id, thread::id) noexcept;
-
-            template<class Char, class Traits>
-            friend basic_ostream<Char, Traits>& operator<<(
-                basic_ostream<Char, Traits>&, thread::id);
-
-            friend struct hash<id>;
-
-            friend id this_thread::get_id() noexcept;
-    };
-
-    bool operator==(thread::id lhs, thread::id rhs) noexcept;
-    bool operator!=(thread::id lhs, thread::id rhs) noexcept;
-    bool operator<(thread::id lhs, thread::id rhs) noexcept;
-    bool operator<=(thread::id lhs, thread::id rhs) noexcept;
-    bool operator>(thread::id lhs, thread::id rhs) noexcept;
-    bool operator>=(thread::id lhs, thread::id rhs) noexcept;
-
-    template<class Char, class Traits>
-    basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& out, thread::id id)
-    {
-        out << id.id_;
-
-        return out;
-    }
-
-    template<> // TODO: implement
-    struct hash<thread::id>;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/tuple.hpp
===================================================================
--- uspace/lib/cpp/include/impl/tuple.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,501 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_TUPLE
-#define LIBCPP_TUPLE
-
-#include <__bits/aux.hpp>
-#include <__bits/tuple/tuple_cat.hpp>
-#include <__bits/tuple/tuple_ops.hpp>
-#include <__bits/type_transformation.hpp>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-namespace std
-{
-    template<class... Ts>
-    class tuple;
-
-    /**
-     * 20.4.2.4, tuple creation functions:
-     */
-
-    namespace aux
-    {
-        struct ignore_t
-        {
-            template<class T>
-            const ignore_t& operator=(const T&) const
-            {
-                return *this;
-            }
-        };
-    }
-
-    inline constexpr aux::ignore_t ignore;
-
-    template<class... Ts> // TODO: test the reference_wrapper version once we got reference_wrapper
-    constexpr auto make_tuple(Ts&&... ts)
-    {
-        return tuple<aux::transform_tuple_types_t<Ts>...>(forward<Ts>(ts)...);
-    }
-
-    template<class... Ts>
-    constexpr tuple<Ts&&...> forward_as_tuple(Ts&&... ts) noexcept
-    {
-        return tuple<Ts&&...>(forward<Ts>(ts)...);
-    }
-
-    template<class... Ts>
-    constexpr tuple<Ts&...> tie(Ts&... ts) noexcept
-    {
-        return tuple<Ts&...>(ts...);
-    }
-
-    template<class... Tuples>
-    constexpr aux::tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls)
-    { // TODO: currently does not work because of index mismatch
-        return aux::tuple_cat(
-            forward<Tuples>(tpls)...,
-            make_index_sequence<sizeof...(Tuples)>{},
-            aux::generate_indices_t<Tuples...>{}
-        );
-    }
-
-    /**
-     * 20.4.2.5, tuple helper classes:
-     */
-
-    template<class T>
-    class tuple_size; // undefined
-
-    template<class T>
-    class tuple_size<const T>
-        : public integral_constant<size_t, tuple_size<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    class tuple_size<volatile T>
-        : public integral_constant<size_t, tuple_size<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    class tuple_size<const volatile T>
-        : public integral_constant<size_t, tuple_size<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    class tuple_size<tuple<Ts...>>
-        : public integral_constant<size_t, sizeof...(Ts)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr size_t tuple_size_v = tuple_size<T>::value;
-
-    template<size_t I, class T>
-    class tuple_element; // undefined
-
-    template<size_t I, class T>
-    class tuple_element<I, const T>
-    {
-        using type = add_const_t<typename tuple_element<I, T>::type>;
-    };
-
-    template<size_t I, class T>
-    class tuple_element<I, volatile T>
-    {
-        using type = add_volatile_t<typename tuple_element<I, T>::type>;
-    };
-
-    template<size_t I, class T>
-    class tuple_element<I, const volatile T>
-    {
-        using type = add_cv_t<typename tuple_element<I, T>::type>;
-    };
-
-    namespace aux
-    {
-        template<size_t I, class T, class... Ts>
-        struct type_at: type_at<I - 1, Ts...>
-        { /* DUMMY BODY */ };
-
-        template<class T, class... Ts>
-        struct type_at<0, T, Ts...>
-        {
-            using type = T;
-        };
-
-        template<size_t I, class... Ts>
-        using type_at_t = typename type_at<I, Ts...>::type;
-    }
-
-    template<size_t I, class... Ts>
-    class tuple_element<I, tuple<Ts...>>
-    {
-        public:
-            using type = aux::type_at_t<I, Ts...>;
-    };
-
-    template<size_t I, class T>
-    using tuple_element_t = typename tuple_element<I, T>::type;
-
-    namespace aux
-    {
-        template<size_t I, class T>
-        struct tuple_element_wrapper
-        {
-            constexpr tuple_element_wrapper() = default;
-
-            constexpr explicit tuple_element_wrapper(T&& val)
-                : value{forward<T>(val)}
-            { /* DUMMY BODY */ }
-
-            template<
-                class U,
-                class = enable_if_t<
-                    is_convertible_v<U, T> && !is_same_v<U, T>,
-                    void
-                >
-            >
-            constexpr explicit tuple_element_wrapper(U&& val)
-                : value(forward<U>(val))
-            { /* DUMMY BODY */ }
-
-            T value;
-        };
-
-        template<class, class...>
-        class tuple_impl; // undefined
-
-        template<size_t... Is, class... Ts>
-        class tuple_impl<index_sequence<Is...>, Ts...>: public tuple_element_wrapper<Is, Ts>...
-        {
-            public:
-                constexpr tuple_impl()
-                    : tuple_element_wrapper<Is, Ts>{}...
-                { /* DUMMY BODY */ }
-
-                template<class... Us>
-                constexpr explicit tuple_impl(Us&&... us)
-                    : tuple_element_wrapper<Is, Ts>(forward<Us>(us))...
-                { /* DUMMY BODY */ }
-
-                template<class... Us>
-                constexpr tuple_impl(const tuple<Us...>& tpl)
-                    : tuple_impl{tpl, make_index_sequence<sizeof...(Us)>{}}
-                { /* DUMMY BODY */ }
-
-                template<class... Us>
-                constexpr tuple_impl(tuple<Us...>&& tpl)
-                    : tuple_impl{move<tuple<Us...>>(tpl), make_index_sequence<sizeof...(Us)>{}}
-                { /* DUMMY BODY */ }
-
-                template<class... Us, size_t... Iss>
-                constexpr tuple_impl(const tuple<Us...>& tpl, index_sequence<Iss...>)
-                    : tuple_impl{get<Iss>(tpl)...}
-                { /* DUMMY BODY */ }
-
-                template<class... Us, size_t... Iss>
-                constexpr tuple_impl(tuple<Us...>&& tpl, index_sequence<Iss...>)
-                    : tuple_impl{get<Iss>(move(tpl))...}
-                { /* DUMMY BODY */ }
-        };
-
-        template<class T, class... Ts>
-        struct tuple_noexcept_swap
-        {
-            static constexpr bool value = noexcept(std::swap(declval<T&>(), declval<T&>()))
-                && tuple_noexcept_swap<Ts...>::value;
-        };
-
-        template<class T>
-        struct tuple_noexcept_swap<T>
-        {
-            static constexpr bool value = noexcept(std::swap(declval<T&>(), declval<T&>()));
-        };
-
-        template<class T, class... Ts>
-        struct tuple_noexcept_assignment
-        {
-            static constexpr bool value = is_nothrow_move_assignable<T>::value
-                && tuple_noexcept_assignment<Ts...>::value;
-        };
-
-        template<class T>
-        struct tuple_noexcept_assignment<T>
-        {
-            static constexpr bool value = is_nothrow_move_assignable<T>::value;
-        };
-    }
-
-    /**
-     * 20.4.2.6, element access:
-     */
-
-    template<size_t I, class... Ts>
-    constexpr tuple_element_t<I, tuple<Ts...>>& get(tuple<Ts...>& tpl) noexcept
-    {
-        aux::tuple_element_wrapper<I, tuple_element_t<I, tuple<Ts...>>>& wrapper = tpl;
-
-        return wrapper.value;
-    }
-
-    template<size_t I, class... Ts>
-    constexpr tuple_element_t<I, tuple<Ts...>>&& get(tuple<Ts...>&& tpl) noexcept
-    {
-        return forward<typename tuple_element<I, tuple<Ts...>>::type&&>(get<I>(tpl));
-    }
-
-    template<size_t I, class... Ts>
-    constexpr const tuple_element_t<I, tuple<Ts...>>& get(const tuple<Ts...>& tpl) noexcept
-    {
-        const aux::tuple_element_wrapper<I, tuple_element_t<I, tuple<Ts...>>>& wrapper = tpl;
-
-        return wrapper.value;
-    }
-
-    namespace aux
-    {
-        template<size_t I, class U, class T, class... Ts>
-        struct index_of_type: index_of_type<I + 1, U, Ts...>
-        { /* DUMMY BODY */ };
-
-        template<size_t I, class T, class... Ts>
-        struct index_of_type<I, T, T, Ts...>: std::integral_constant<std::size_t, I>
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T, class... Ts>
-    constexpr T& get(tuple<Ts...>& tpl) noexcept
-    {
-        return get<aux::index_of_type<0, T, Ts...>::value>(tpl);
-    }
-
-    template<class T, class... Ts>
-    constexpr T&& get(tuple<Ts...>&& tpl) noexcept
-    {
-        return get<aux::index_of_type<0, T, Ts...>::value>(forward<tuple<Ts...>>(tpl));
-    }
-
-    template<class T, class... Ts>
-    constexpr const T& get(const tuple<Ts...>& tpl) noexcept
-    {
-        return get<aux::index_of_type<0, T, Ts...>::value>(tpl);
-    }
-
-    /**
-     * 20.4.2, class template tuple:
-     */
-
-    template<class... Ts>
-    class tuple: public aux::tuple_impl<make_index_sequence<sizeof...(Ts)>, Ts...>
-    {
-        using base_t = aux::tuple_impl<make_index_sequence<sizeof...(Ts)>, Ts...>;
-
-        public:
-
-            /**
-             * 20.4.2.1, tuple construction:
-             */
-
-            constexpr tuple()
-                : base_t{}
-            { /* DUMMY BODY */ }
-
-            constexpr explicit tuple(
-                const Ts&... ts, enable_if_t<sizeof...(Ts) != 0>* = nullptr)
-                : base_t(ts...)
-            { /* DUMMY BODY */ }
-
-            template<class... Us> // TODO: is_convertible == true for all Us to all Ts
-            constexpr explicit tuple(Us&&... us, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
-                : base_t(forward<Us>(us)...)
-            { /* DUMMY BODY */ }
-
-            tuple(const tuple&) = default;
-            tuple(tuple&&) = default;
-
-            template<class... Us>
-            constexpr tuple(const tuple<Us...>& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
-                : base_t(tpl)
-            { /* DUMMY BODY */ }
-
-            template<class... Us>
-            constexpr tuple(tuple<Us...>&& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
-                : base_t(move(tpl))
-            { /* DUMMY BODY */ }
-
-            // TODO: pair related construction and assignment needs convertibility, not size
-            template<class U1, class U2>
-            constexpr tuple(const pair<U1, U2>& p)
-                : base_t{}
-            {
-                get<0>(*this) = p.first;
-                get<1>(*this) = p.second;
-            }
-
-            template<class U1, class U2>
-            constexpr tuple(pair<U1, U2>&& p)
-                : base_t{}
-            {
-                get<0>(*this) = forward<U1>(p.first);
-                get<1>(*this) = forward<U2>(p.second);
-            }
-
-            // TODO: allocator-extended constructors
-
-            /**
-             * 20.4.2.2, tuple assignment:
-             */
-
-            tuple& operator=(const tuple& other)
-            {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
-
-                return *this;
-            }
-
-            tuple& operator=(tuple&& other) noexcept(aux::tuple_noexcept_assignment<Ts...>::value)
-            {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
-
-                return *this;
-            }
-
-            template<class... Us>
-            tuple& operator=(const tuple<Us...>& other)
-            {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
-
-                return *this;
-            }
-
-            template<class... Us>
-            tuple& operator=(tuple<Us...>&& other)
-            {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
-
-                return *this;
-            }
-
-            template<class U1, class U2>
-            tuple& operator=(const pair<U1, U2>& p)
-            {
-                get<0>(*this) = p.first;
-                get<1>(*this) = p.second;
-
-                return *this;
-            }
-
-            template<class U1, class U2>
-            tuple& operator=(pair<U1, U2>&& p)
-            {
-                get<0>(*this) = forward<U1>(p.first);
-                get<1>(*this) = forward<U2>(p.second);
-
-                return *this;
-            }
-
-            /**
-             * 20.4.2.3, tuple swap:
-             */
-
-            void swap(tuple& other) noexcept(aux::tuple_noexcept_swap<Ts...>::value)
-            {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::swap(*this, other);
-            }
-    };
-
-    /**
-     * 20.4.2.7, relational operators:
-     */
-
-    template<class... Ts, class... Us>
-    constexpr bool operator==(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        if constexpr (sizeof...(Ts) == 0)
-            return true;
-        else
-            return aux::tuple_ops<0, sizeof...(Ts) - 1>::eq(lhs, rhs);
-    }
-
-    template<class... Ts, class... Us>
-    constexpr bool operator<(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        if constexpr (sizeof...(Ts) == 0)
-            return false;
-        else
-            return aux::tuple_ops<0, sizeof...(Ts) - 1>::lt(lhs, rhs);
-    }
-
-    template<class... Ts, class... Us>
-    constexpr bool operator!=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class... Ts, class... Us>
-    constexpr bool operator>(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class... Ts, class... Us>
-    constexpr bool operator<=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class... Ts, class... Us>
-    constexpr bool operator>=(const tuple<Ts...>& lhs, const tuple<Us...> rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    /**
-     * 20.4.2.8, allocator-related traits:
-     */
-
-    template<class... Ts, class Alloc>
-    struct uses_allocator<tuple<Ts...>, Alloc>: true_type
-    { /* DUMMY BODY */ };
-
-    /**
-     * 20.4.2.9, specialized algorithms:
-     */
-
-    template<class... Ts>
-    void swap(tuple<Ts...>& lhs, tuple<Ts...>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/type_traits.hpp
===================================================================
--- uspace/lib/cpp/include/impl/type_traits.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1222 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_TYPE_TRAITS
-#define LIBCPP_TYPE_TRAITS
-
-#include <cstdlib>
-#include <cstddef>
-#include <cstdint>
-#include <__bits/aux.hpp>
-#include <__bits/type_traits/references.hpp>
-
-namespace std
-{
-    template<class T>
-    struct add_rvalue_reference;
-
-    template<class T>
-    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
-
-    template<class T>
-    add_rvalue_reference_t<T> declval() noexcept;
-
-    template<class...>
-    using void_t = void;
-
-    template<class>
-    struct remove_cv;
-
-    template<class T>
-    using remove_cv_t = typename remove_cv<T>::type;
-
-    namespace aux
-    {
-        template<class T, class U>
-        struct is_same: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T>
-        struct is_same<T, T>: true_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class... Ts>
-        struct is_one_of;
-
-        template<class T>
-        struct is_one_of<T>: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class... Ts>
-        struct is_one_of<T, T, Ts...>: true_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class U, class... Ts>
-        struct is_one_of<T, U, Ts...>: is_one_of<T, Ts...>
-        { /* DUMMY BODY */ };
-    }
-
-    /**
-     * 20.10.4.1, primary type categories:
-     */
-
-    template<class T>
-    struct is_void: aux::is_same<remove_cv_t<T>, void>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_void_v = is_void<T>::value;
-
-    template<class T>
-    struct is_null_pointer: aux::is_same<remove_cv_t<T>, nullptr_t>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
-
-    template<class T>
-    struct is_integral: aux::is_one_of<remove_cv_t<T>,
-            bool, char, unsigned char, signed char,
-            long, unsigned long, int, unsigned int, short,
-            unsigned short, long long, unsigned long long,
-            char16_t, char32_t, wchar_t>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_floating_point
-        : aux::is_one_of<remove_cv_t<T>, float, double, long double>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
-
-    template<class>
-    struct is_array: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_array<T[]>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_array_v = is_array<T>::value;
-
-    namespace aux
-    {
-        template<class>
-        struct is_pointer: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T>
-        struct is_pointer<T*>: true_type
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T>
-    struct is_pointer: aux::is_pointer<remove_cv_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_pointer_v = is_pointer<T>::value;
-
-    template<class T>
-    struct is_lvalue_reference: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_lvalue_reference<T&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
-
-    template<class T>
-    struct is_rvalue_reference: false_type
-    { /* DUMMY BODY*/ };
-
-    template<class T>
-    struct is_rvalue_reference<T&&>: true_type
-    { /* DUMMY BODY*/ };
-
-    template<class T>
-    inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
-
-    template<class>
-    struct is_member_pointer;
-
-    template<class>
-    struct is_member_function_pointer;
-
-    template<class T>
-    struct is_member_object_pointer
-        : integral_constant<bool, is_member_pointer<T>::value &&
-                            !is_member_function_pointer<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<T>::value;
-
-    template<class>
-    struct is_function;
-
-    namespace aux
-    {
-        template<class T>
-        struct is_member_function_pointer: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class U>
-        struct is_member_function_pointer<T U::*>: is_function<T>
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T>
-    struct is_member_function_pointer: aux::is_member_function_pointer<remove_cv_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<T>::value;
-
-    template<class T>
-    struct is_enum: aux::value_is<bool, __is_enum(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_enum_v = is_enum<T>::value;
-
-    template<class T>
-    struct is_union: aux::value_is<bool, __is_union(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_union_v = is_union<T>::value;
-
-    template<class T>
-    struct is_class: aux::value_is<bool, __is_class(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_class_v = is_class<T>::value;
-
-    /**
-     * Note: is_function taken from possile implementation on cppreference.com
-     */
-    template<class>
-    struct is_function: false_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...)>: true_type
-    { /* DUMMY BODY */ };
-
-    // Note: That hexadot covers variadic functions like printf.
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......)>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile &>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile &&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile & noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) volatile && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args...) const volatile && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) volatile && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class Ret, class... Args>
-    struct is_function<Ret(Args......) const volatile && noexcept>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_function_v = is_function<T>::value;
-
-    /**
-     * 20.10.4.2, composite type categories:
-     */
-
-    template<class T>
-    struct is_reference: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_reference<T&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_reference<T&&>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_reference_v = is_reference<T>::value;
-
-    template<class T>
-    struct is_arithmetic: aux::value_is<
-        bool,
-        is_integral<T>::value || is_floating_point<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
-
-    template<class T>
-    struct is_fundamental;
-
-    template<class T>
-    struct is_object;
-
-    template<class T>
-    struct is_scalar;
-
-    template<class T>
-    struct is_compound;
-
-    namespace aux
-    {
-        template<class T>
-        struct is_member_pointer: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class U>
-        struct is_member_pointer<T U::*>: true_type
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T>
-    struct is_member_pointer: aux::is_member_pointer<remove_cv_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
-
-    /**
-     * 20.10.4.3, type properties:
-     */
-
-    template<class T>
-    struct is_const: false_type
-    { /* DUMMY BODY */};
-
-    template<class T>
-    struct is_const<T const>: true_type
-    { /* DUMMY BODY */};
-
-    template<class T>
-    inline constexpr bool is_const_v = is_const<T>::value;
-
-    template<class T>
-    struct is_volatile: false_type
-    { /* DUMMY BODY */};
-
-    template<class T>
-    struct is_volatile<T volatile>: true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_volatile_v = is_volatile<T>::value;
-
-    /**
-     * 2 forward declarations.
-     */
-
-    template<class T>
-    struct is_trivially_copyable;
-
-    template<class T>
-    struct is_trivially_default_constructible;
-
-    template<class T>
-    struct is_trivial: aux::value_is<
-        bool,
-        is_trivially_copyable<T>::value &&
-        is_trivially_default_constructible<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_trivial_v = is_trivial<T>::value;
-
-    template<class T>
-    struct is_trivially_copyable: aux::value_is<bool, __has_trivial_copy(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
-
-    template<class T>
-    struct is_standard_layout: aux::value_is<bool, __is_standard_layout(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_pod: aux::value_is<bool, __is_pod(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_pod_v = is_pod<T>::value;
-
-    template<class T>
-    struct is_literal_type: aux::value_is<bool, __is_literal_type(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_literal_type_v = is_literal_type<T>::value;
-
-    template<class T>
-    struct is_empty: aux::value_is<bool, __is_empty(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_empty_v = is_empty<T>::value;
-
-    template<class T>
-    struct is_polymorphic: aux::value_is<bool, __is_polymorphic(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_polymorphic_v = is_polymorphic<T>::value;
-
-    template<class T>
-    struct is_abstract: aux::value_is<bool, __is_abstract(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_abstract_v = is_abstract<T>::value;
-
-    template<class T>
-    struct is_final: aux::value_is<bool, __is_final(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_final_v = is_final<T>::value;
-
-    namespace aux
-    {
-        /**
-         * Note: We cannot simply use !is_signed to define
-         *       is_unsigned because non-arithmetic types
-         *       are neither signer nor unsigned.
-         */
-        template<class T, bool = is_arithmetic<T>::value>
-        struct is_signed: value_is<bool, T(-1) < T(0)>
-        { /* DUMMY BODY */ };
-
-        template<class T>
-        struct is_signed<T, false>: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T, bool = is_arithmetic<T>::value>
-        struct is_unsigned: value_is<bool, T(0) < T(-1)>
-        { /* DUMMY BODY */ };
-
-        template<class T>
-        struct is_unsigned<T, false>: false_type
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T>
-    struct is_signed: aux::is_signed<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_signed_v = is_signed<T>::value;
-
-    template<class T>
-    struct is_unsigned: aux::is_unsigned<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
-
-    namespace aux
-    {
-        template<class, class T, class... Args>
-        struct is_constructible: false_type
-        { /* DUMMY BODY */ };
-
-        template<class T, class... Args>
-        struct is_constructible<
-            void_t<decltype(T(declval<Args>()...))>,
-            T, Args...
-        >
-            : true_type
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T, class... Args>
-    struct is_constructible: aux::is_constructible<void_t<>, T, Args...>
-    { /* DUMMY BODY */ };
-
-    template<class T, class... Args>
-    inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value;
-
-    template<class T>
-    struct is_default_constructible
-        : is_constructible<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_copy_constructible
-        : is_constructible<T, add_lvalue_reference<const T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_move_constructible
-        : is_constructible<T, add_rvalue_reference<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U, class = void>
-    struct is_assignable: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    struct is_assignable<T, U, void_t<decltype(declval<T>() = declval<U>())>>
-        : true_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_copy_assignable
-        : is_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_move_assignable
-        : is_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class, class = void>
-    struct is_destructible: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_destructible<T, void_t<decltype(declval<T&>().~T())>>
-        : true_type
-    { /* DUMMY BODY */ };
-
-    template<class T, class... Args>
-    struct is_trivially_constructible: aux::value_is<bool, __has_trivial_constructor(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<T>::value;
-
-    template<class T>
-    struct is_trivially_default_constructible
-        : is_trivially_constructible<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_trivially_copy_constructible: aux::value_is<bool, __has_trivial_copy(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value;
-
-    template<class T>
-    struct is_trivially_move_constructible
-        : is_trivially_constructible<T, add_rvalue_reference_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    struct is_trivially_assignable: aux::value_is<bool, __has_trivial_assign(T) && is_assignable<T, U>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
-
-    template<class T>
-    struct is_trivially_copy_assignable
-        : is_trivially_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_trivially_move_assignable
-        : is_trivially_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_trivially_destructible: aux::value_is<bool, __has_trivial_destructor(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
-
-    template<class T, class... Args>
-    struct is_nothrow_constructible: aux::value_is<bool, __has_nothrow_constructor(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T>::value;
-
-    template<class T>
-    struct is_nothrow_default_constructible
-        : is_nothrow_constructible<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_nothrow_copy_constructible: aux::value_is<bool, __has_nothrow_copy(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value;
-
-    template<class T>
-    struct is_nothrow_move_constructible
-        : is_nothrow_constructible<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    struct is_nothrow_assignable: aux::value_is<bool, __has_nothrow_assign(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
-
-    template<class T>
-    struct is_nothrow_copy_assignable
-        : is_nothrow_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_nothrow_move_assignable
-        : is_nothrow_assignable<add_lvalue_reference_t<T>, add_rvalue_reference_t<T>>
-    { /* DUMMY BODY */ };
-
-    template<class, class = void>
-    struct is_nothrow_destructible: false_type
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct is_nothrow_destructible<T, void_t<decltype(declval<T&>().~T())>>
-        : aux::value_is<bool, noexcept(declval<T&>().~T())>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct has_virtual_destructor: aux::value_is<bool, __has_virtual_destructor(T)>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
-
-    /**
-     * 20.10.5, type property queries:
-     */
-
-    template<class T>
-    struct alignment_of: aux::value_is<std::size_t, alignof(T)>
-    { /* DUMMY BODY */ };
-
-    template<class>
-    struct rank : aux::value_is<size_t, 0u>
-    { /* DUMMY BODY */ };
-
-    template<class T, size_t N>
-    struct rank<T[N]>: aux::value_is<size_t, 1u + rank<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct rank<T[]>: aux::value_is<size_t, 1u + rank<T>::value>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr size_t rank_v = rank<T>::value;
-
-    template<class T, unsigned I = 0U>
-    struct extent: aux::value_is<size_t, 0U>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct extent<T[], 0U>: aux::value_is<size_t, 0U>
-    { /* DUMMY BODY */ };
-
-    template<class T, unsigned I>
-    struct extent<T[], I>: extent<T, I - 1>
-    { /* DUMMY BODY */ };
-
-    template<class T, size_t N>
-    struct extent<T[N], 0U>: aux::value_is<size_t, 0U>
-    { /* DUMMY BODY */ };
-
-    template<class T, unsigned I, size_t N>
-    struct extent<T[N], I>: extent<T, I - 1>
-    { /* DUMMY BODY */ };
-
-    /**
-     * 20.10.6, type relations:
-     */
-
-    template<class T, class U>
-    struct is_same: aux::is_same<T, U>
-    { /* DUMMY BODY */ };
-
-    template<class T, class U>
-    inline constexpr bool is_same_v = is_same<T, U>::value;
-
-    template<class Base, class Derived>
-    struct is_base_of: aux::value_is<bool, __is_base_of(Base, Derived)>
-    { /* DUMMY BODY */ };
-
-    template<class Base, class Derived>
-    inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
-
-    template<class From, class To, class = void>
-    struct is_convertible: false_type
-    { /* DUMMY BODY */ };
-
-    template<class From, class To>
-    struct is_convertible<From, To, void_t<decltype((To)declval<From>())>>
-        : true_type
-    { /* DUMMY BODY */ };
-
-    template<class From, class To>
-    inline constexpr bool is_convertible_v = is_convertible<From, To>::value;
-
-    /**
-     * 20.10.7.1, const-volatile modifications:
-     */
-
-    template<class T>
-    struct remove_const: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_const<T const>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_volatile: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_volatile<T volatile>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_cv: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_cv<T const>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_cv<T volatile>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_cv<T const volatile>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct add_const: aux::type_is<T const>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct add_volatile: aux::type_is<T volatile>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct add_cv: aux::type_is<T const volatile>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    using remove_const_t = typename remove_const<T>::type;
-
-    template<class T>
-    using remove_volatile_t = typename remove_volatile<T>::type;
-
-    template<class T>
-    using remove_cv_t = typename remove_cv<T>::type;
-
-    template<class T>
-    using add_const_t = typename add_const<T>::type;
-
-    template<class T>
-    using add_volatile_t = typename add_volatile<T>::type;
-
-    template<class T>
-    using add_cv_t = typename add_cv<T>::type;
-
-    /**
-     * 20.10.7.3, sign modifications:
-     * Note: These are fairly naive implementations that
-     *       are meant to keep our code going (i.e. they work
-     *       for the most common types, but I'm not sure
-     *       if there are any intricacies required by
-     *       the standard).
-     */
-
-    template<class T>
-    struct make_signed: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<char>: aux::type_is<signed char>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<unsigned char>: aux::type_is<signed char>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<unsigned short>: aux::type_is<short>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<unsigned int>: aux::type_is<int>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<unsigned long>: aux::type_is<long>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_signed<unsigned long long>: aux::type_is<long long>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct make_unsigned: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<char>: aux::type_is<unsigned char>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<signed char>: aux::type_is<unsigned char>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<short>: aux::type_is<unsigned short>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<int>: aux::type_is<unsigned int>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<long>: aux::type_is<unsigned long>
-    { /* DUMMY BODY */ };
-
-    template<>
-    struct make_unsigned<long long>: aux::type_is<unsigned long long>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    using make_signed_t = typename make_signed<T>::type;
-
-    template<class T>
-    using make_unsigned_t = typename make_signed<T>::type;
-
-    /**
-     * 20.10.7.4, array modifications:
-     */
-
-    template<class T>
-    struct remove_extent: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_extent<T[]>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T, size_t N>
-    struct remove_extent<T[N]>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_all_extents: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_all_extents<T[]>: remove_all_extents<T>
-    { /* DUMMY BODY */ };
-
-    template<class T, size_t N>
-    struct remove_all_extents<T[N]>: remove_all_extents<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    using remove_extent_t = typename remove_extent<T>::type;
-
-    template<class T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    /**
-     * 20.10.7.5, pointer modifications:
-     */
-
-    template<class T>
-    struct remove_pointer: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_pointer<T*>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_pointer<T* const>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_pointer<T* volatile>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_pointer<T* const volatile>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    namespace aux
-    {
-        template<class T>
-        struct add_pointer_to_function: type_is<T>
-        { /* DUMMY BODY */ };
-
-        template<class T, class... Args>
-        struct add_pointer_to_function<T(Args...)>
-            : type_is<T(*)(Args...)>
-        { /* DUMMY BODY */ };
-
-        template<class T, bool = false>
-        struct add_pointer_cond: aux::type_is<remove_reference_t<T>*>
-        { /* DUMMY BODY */ };
-
-        template<class T>
-        struct add_pointer_cond<T, true>
-            : aux::add_pointer_to_function<T>
-        { /* DUMMY BODY */ };
-    }
-
-    template<class T>
-    struct add_pointer: aux::add_pointer_cond<T, is_function_v<T>>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    using remove_pointer_t = typename remove_pointer<T>::type;
-
-    template<class T>
-    using add_pointer_t = typename add_pointer<T>::type;
-
-    /**
-     * 20.10.7.6, other transformations:
-     */
-
-    namespace aux
-    {
-        template<size_t Len, size_t Align>
-        struct aligned_t
-        {
-            alignas(Align) uint8_t storage[Len];
-        };
-
-        template<class T>
-        constexpr T max_of_cont(T cont)
-        {
-            if (cont.size() == 0U)
-                return T{};
-
-            auto it = cont.begin();
-            auto res = *it;
-
-            while (++it != cont.end())
-            {
-                if (*it > res)
-                    res = *it;
-            }
-
-            return res;
-        }
-    }
-
-    // TODO: consult standard on the default value of align
-    template<std::size_t Len, std::size_t Align = 0>
-    struct aligned_storage: aux::type_is<aux::aligned_t<Len, Align>>
-    { /* DUMMY BODY */ };
-
-    template<std::size_t Len, class... Types>
-    struct aligned_union: aux::type_is<
-        aux::aligned_t<
-            aux::max_of_cont({Len, alignof(Types)...}),
-            aux::max_of_cont({alignof(Types)...})
-        >
-    >
-    { /* DUMMY BODY */ };
-
-	// TODO: this is very basic implementation for chrono, fix!
-    /* template<class T> */
-    /* struct decay: aux::type_is<remove_cv_t<remove_reference_t<T>>> */
-	/* { /1* DUMMY BODY *1/ }; */
-
-    template<bool, class, class>
-    struct conditional;
-
-    template<class T>
-    struct decay: aux::type_is<
-        typename conditional<
-            is_array_v<remove_reference_t<T>>,
-            remove_extent_t<remove_reference_t<T>>*,
-            typename conditional<
-                is_function_v<remove_reference_t<T>>,
-                add_pointer_t<remove_reference_t<T>>,
-                remove_cv_t<remove_reference_t<T>>
-            >::type
-        >::type
-    >
-    { /* DUMMY BODY */ };
-
-	template<class T>
-    using decay_t = typename decay<T>::type;
-
-    template<bool, class T = void>
-    struct enable_if
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct enable_if<true, T>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<bool, class T, class F>
-    struct conditional: aux::type_is<F>
-    { /* DUMMY BODY */ };
-
-    template<class T, class F>
-    struct conditional<true, T, F>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class... T>
-    struct common_type
-    { /* DUMMY BODY */ };
-
-    template<class... T>
-    using common_type_t = typename common_type<T...>::type;
-
-    template<class T>
-    struct common_type<T>: common_type<T, T>
-    { /* DUMMY BODY */ };
-
-    // To avoid circular dependency with <utility>.
-    template<class T>
-    add_rvalue_reference_t<T> declval() noexcept;
-
-    template<class T1, class T2>
-    struct common_type<T1, T2>: aux::type_is<decay_t<decltype(false ? declval<T1>() : declval<T2>())>>
-    { /* DUMMY BODY */ };
-
-    template<class T1, class T2, class... Ts>
-    struct common_type<T1, T2, Ts...>
-        : aux::type_is<common_type_t<common_type_t<T1, T2>, Ts...>>
-    { /* DUMMY BODY */ };
-
-    template<class... T>
-    struct underlying_type;
-
-    template<std::size_t Len, std::size_t Align = 0>
-    using aligned_storage_t = typename aligned_storage<Len, Align>::type;
-
-    template<std::size_t Len, class... Types>
-    using aligned_union_t = typename aligned_union<Len, Types...>::type;
-
-    template<bool b, class T = void>
-    using enable_if_t = typename enable_if<b, T>::type;
-
-    template<bool b, class T, class F>
-    using conditional_t = typename conditional<b, T, F>::type;
-
-    template<class T>
-    using underlying_type_t = typename underlying_type<T>::type;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/typeindex.hpp
===================================================================
--- uspace/lib/cpp/include/impl/typeindex.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,75 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_TYPE_INDEX
-#define LIBCPP_TYPE_INDEX
-
-#include <cstdlib>
-#include <typeinfo>
-
-namespace std
-{
-
-    /**
-     * 20.14.2, type_index:
-     */
-
-    class type_index
-    {
-        public:
-            type_index(const type_info& rhs) noexcept;
-
-            bool operator==(const type_index& rhs) const noexcept;
-
-            bool operator!=(const type_index& rhs) const noexcept;
-
-            bool operator<(const type_index& rhs) const noexcept;
-
-            bool operator<=(const type_index& rhs) const noexcept;
-
-            bool operator>(const type_index& rhs) const noexcept;
-
-            bool operator>=(const type_index& rhs) const noexcept;
-
-            size_t hash_code() const noexcept;
-
-            const char* name() const noexcept;
-
-        private:
-            const type_info* target_;
-    };
-
-    template<class T>
-    struct hash;
-
-    // TODO: implement
-    template<>
-    struct hash<type_index>;
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/typeinfo.hpp
===================================================================
--- uspace/lib/cpp/include/impl/typeinfo.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2017 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_TYPE_INFO
-#define LIBCPP_TYPE_INFO
-
-#include <cstdlib>
-
-namespace std
-{
-
-class type_info
-{
-    public:
-        virtual ~type_info();
-
-        bool operator==(const type_info&) const noexcept;
-        bool operator!=(const type_info&) const noexcept;
-
-        bool before(const type_info&) const noexcept;
-
-        size_t hash_code() const noexcept;
-
-        const char* name() const noexcept;
-
-        type_info(const type_info&) = delete;
-        type_info& operator=(const type_info&) = delete;
-
-    private:
-        const char* __name;
-};
-
-    // TODO: class bad_cast, bad_typeid
-}
-
-#endif
-
Index: uspace/lib/cpp/include/impl/unordered_map.hpp
===================================================================
--- uspace/lib/cpp/include/impl/unordered_map.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,1193 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_UNORDERED_MAP
-#define LIBCPP_UNORDERED_MAP
-
-#include <initializer_list>
-#include <__bits/hash_table.hpp>
-#include <functional>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 23.5.4, class template unordered_map:
-     */
-
-    template<
-        class Key, class Value,
-        class Hash = hash<Key>,
-        class Pred = equal_to<Key>,
-        class Alloc = allocator<pair<const Key, Value>>
-    >
-    class unordered_map
-    {
-        public:
-            using key_type        = Key;
-            using mapped_type     = Value;
-            using value_type      = pair<const key_type, mapped_type>;
-            using hasher          = Hash;
-            using key_equal       = Pred;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using iterator             = aux::hash_table_iterator<
-                value_type, reference, pointer, size_type
-            >;
-            using const_iterator       = aux::hash_table_const_iterator<
-                value_type, const_reference, const_pointer, size_type
-            >;
-            using local_iterator       = aux::hash_table_local_iterator<
-                value_type, reference, pointer
-            >;
-            using const_local_iterator = aux::hash_table_const_local_iterator<
-                value_type, const_reference, const_pointer
-            >;
-
-            unordered_map()
-                : unordered_map{default_bucket_count_}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_map(size_type bucket_count,
-                                   const hasher& hf = hasher{},
-                                   const key_equal& eql = key_equal{},
-                                   const allocator_type& alloc = allocator_type{})
-                : table_{bucket_count, hf, eql}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_map(InputIterator first, InputIterator last,
-                          size_type bucket_count = default_bucket_count_,
-                          const hasher& hf = hasher{},
-                          const key_equal& eql = key_equal{},
-                          const allocator_type& alloc = allocator_type{})
-                : unordered_map{bucket_count, hf, eql, alloc}
-            {
-                insert(first, last);
-            }
-
-            unordered_map(const unordered_map& other)
-                : unordered_map{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            unordered_map(unordered_map&& other)
-                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_map(const allocator_type& alloc)
-                : table_{default_bucket_count_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(const unordered_map& other, const allocator_type& alloc)
-                : table_{other.table_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(unordered_map&& other, const allocator_type& alloc)
-                : table_{move(other.table_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(initializer_list<value_type> init,
-                          size_type bucket_count = default_bucket_count_,
-                          const hasher& hf = hasher{},
-                          const key_equal& eql = key_equal{},
-                          const allocator_type& alloc = allocator_type{})
-                : unordered_map{bucket_count, hf, eql, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            unordered_map(size_type bucket_count, const allocator_type& alloc)
-                : unordered_map{bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_map{bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_map(InputIterator first, InputIterator last,
-                          size_type bucket_count, const allocator_type& alloc)
-                : unordered_map{first, last, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_map(InputIterator first, InputIterator last,
-                          size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_map{first, last, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(initializer_list<value_type> init, size_type bucket_count,
-                          const allocator_type& alloc)
-                : unordered_map{init, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_map(initializer_list<value_type> init, size_type bucket_count,
-                          const hasher& hf, const allocator_type& alloc)
-                : unordered_map{init, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~unordered_map()
-            { /* DUMMY BODY */ }
-
-            unordered_map& operator=(const unordered_map& other)
-            {
-                table_ = other.table_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            unordered_map& operator=(unordered_map&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<hasher>::value &&
-                         is_nothrow_move_assignable<key_equal>::value)
-            {
-                table_ = move(other.table_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            unordered_map& operator=(initializer_list<value_type>& init)
-            {
-                table_.clear();
-                table_.reserve(init.size());
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            bool empty() const noexcept
-            {
-                return table_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return table_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return table_.max_size(allocator_);
-            }
-
-            iterator begin() noexcept
-            {
-                return table_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return table_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return table_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return table_.cend();
-            }
-
-            template<class... Args>
-            pair<iterator, bool> emplace(Args&&... args)
-            {
-                return table_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...).first;
-            }
-
-            pair<iterator, bool> insert(const value_type& val)
-            {
-                return table_.insert(val);
-            }
-
-            pair<iterator, bool> insert(value_type&& val)
-            {
-                return table_.insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            pair<iterator, bool> insert(
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace(forward<T>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val).first;
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val)).first;
-            }
-
-            template<class T>
-            iterator insert(
-                const_iterator hint,
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace_hint(hint, forward<T>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            template<class... Args>
-            pair<iterator, bool> try_emplace(const key_type& key, Args&&... args)
-            {
-                /**
-                 * Note: If anyone (like me) wonders what is the difference between
-                 *       emplace and try_emplace, the former always constructs the value
-                 *       (in order to get the key) and the latter does it only if
-                 *       an insertion takes place.
-                 */
-
-                table_.increment_size();
-
-                auto [bucket, target, idx] = table_.find_insertion_spot(key);
-
-                if (!bucket)
-                    return make_pair(end(), false);
-
-                if (target && table_.keys_equal(key, target->value))
-                {
-                    table_.decrement_size();
-
-                    return make_pair(
-                        iterator{
-                            table_.table(), idx, table_.bucket_count(),
-                            target
-                        },
-                        false
-                    );
-                }
-                else
-                {
-                    auto node = new node_type{key, forward<Args>(args)...};
-                    bucket->append(node);
-
-                    return make_pair(iterator{
-                        table_.table(), idx,
-                        table_.bucket_count(),
-                        node
-                    }, true);
-                }
-            }
-
-            template<class... Args>
-            pair<iterator, bool> try_emplace(key_type&& key, Args&&... args)
-            {
-                table_.increment_size();
-
-                auto [bucket, target, idx] = table_.find_insertion_spot(key);
-
-                if (!bucket)
-                    return make_pair(end(), false);
-
-                if (target && table_.keys_equal(key, target->value))
-                {
-                    table_.decrement_size();
-
-                    return make_pair(
-                        iterator{
-                            table_.table(), idx, table_.bucket_count(),
-                            target
-                        },
-                        false
-                    );
-                }
-                else
-                {
-                    auto node = new node_type{move(key), forward<Args>(args)...};
-                    bucket->append(node);
-
-                    return make_pair(iterator{
-                        table_.table(), idx,
-                        table_.bucket_count(),
-                        node
-                    }, true);
-                }
-            }
-
-            template<class... Args>
-            iterator try_emplace(const_iterator, const key_type& key, Args&&... args)
-            {
-                return try_emplace(key, forward<Args>(args)...).first;
-            }
-
-            template<class... Args>
-            iterator try_emplace(const_iterator, key_type&& key, Args&&... args)
-            {
-                return try_emplace(move(key), forward<Args>(args)...).first;
-            }
-
-            template<class T>
-            pair<iterator, bool> insert_or_assign(const key_type& key, T&& val)
-            {
-                table_.increment_size();
-
-                auto [bucket, target, idx] = table_.find_insertion_spot(key);
-
-                if (!bucket)
-                    return make_pair(end(), false);
-
-                if (target && table_.keys_equal(key, target->value))
-                {
-                    table_.decrement_size();
-                    target->value.second = forward<T>(val);
-
-                    return make_pair(
-                        iterator{
-                            table_.table(), idx, table_.bucket_count(),
-                            target
-                        },
-                        false
-                    );
-                }
-                else
-                {
-                    auto node = new node_type{key, forward<T>(val)};
-                    bucket->append(node);
-
-                    return make_pair(iterator{
-                        table_.table(), idx,
-                        table_.bucket_count(),
-                        node
-                    }, true);
-                }
-            }
-
-            template<class T>
-            pair<iterator, bool> insert_or_assign(key_type&& key, T&& val)
-            {
-                table_.increment_size();
-
-                auto [bucket, target, idx] = table_.find_insertion_spot(key);
-
-                if (!bucket)
-                    return make_pair(end(), false);
-
-                if (target && table_.keys_equal(key, target->value))
-                {
-                    table_.decrement_size();
-                    target->value.second = forward<T>(val);
-
-                    return make_pair(
-                        iterator{
-                            table_.table(), idx, table_.bucket_count(),
-                            target
-                        },
-                        false
-                    );
-                }
-                else
-                {
-                    auto node = new node_type{move(key), forward<T>(val)};
-                    bucket->append(node);
-
-                    return make_pair(iterator{
-                        table_.table(), idx,
-                        table_.bucket_count(),
-                        node
-                    }, true);
-                }
-            }
-
-            template<class T>
-            iterator insert_or_assign(const_iterator, const key_type& key, T&& val)
-            {
-                return insert_or_assign(key, forward<T>(val)).first;
-            }
-
-            template<class T>
-            iterator insert_or_assign(const_iterator, key_type&& key, T&& val)
-            {
-                return insert_or_assign(move(key), forward<T>(val)).first;
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return table_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return table_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    table_.table(), first.idx(),
-                    table_.bucket_count(), table_.head(first.idx())
-                };
-            }
-
-            void clear() noexcept
-            {
-                table_.clear();
-            }
-
-            void swap(unordered_map& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
-                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
-            {
-                table_.swap(other.table_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            hasher hash_function() const
-            {
-                return table_.hash_function();
-            }
-
-            key_equal key_eq() const
-            {
-                return table_.key_eq();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return table_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return table_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return table_.count(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return table_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return table_.equal_range(key);
-            }
-
-            mapped_type& operator[](const key_type& key)
-            {
-                auto spot = table_.find_insertion_spot(key);
-                auto bucket = get<0>(spot);
-
-                if (bucket->head)
-                {
-                    auto head = bucket->head;
-                    auto current = bucket->head;
-
-                    do
-                    {
-                        if (table_.keys_equal(key, current->value))
-                            return current->value.second;
-                        else
-                            current = current->next;
-                    }
-                    while (current != head);
-                }
-
-                auto node = new node_type{key, mapped_type{}};
-                bucket->append(node);
-
-                table_.increment_size();
-                table_.rehash_if_needed();
-                return node->value.second;
-            }
-
-            mapped_type& operator[](key_type&& key)
-            {
-                auto spot = table_.find_insertion_spot(key);
-                auto bucket = get<0>(spot);
-
-                if (bucket->head)
-                {
-                    auto head = bucket->head;
-                    auto current = bucket->head;
-
-                    do
-                    {
-                        if (table_.keys_equal(key, current->value))
-                            return current->value.second;
-                        else
-                            current = current->next;
-                    }
-                    while (current != head);
-                }
-
-                auto node = new node_type{move(key), mapped_type{}};
-                bucket->append(node);
-
-                table_.increment_size();
-                table_.rehash_if_needed();
-                return node->value.second;
-            }
-
-            mapped_type& at(const key_type& key)
-            {
-                auto it = find(key);
-
-                // TODO: throw out_of_range if it == end()
-                return it->second;
-            }
-
-            const mapped_type& at(const key_type& key) const
-            {
-                auto it = find(key);
-
-                // TODO: throw out_of_range if it == end()
-                return it->second;
-            }
-
-            size_type bucket_count() const noexcept
-            {
-                return table_.bucket_count();
-            }
-
-            size_type max_bucket_count() const noexcept
-            {
-                return table_.max_bucket_count();
-            }
-
-            size_type bucket_size(size_type idx) const
-            {
-                return table_.bucket_size(idx);
-            }
-
-            size_type bucket(const key_type& key) const
-            {
-                return table_.bucket(key);
-            }
-
-            local_iterator begin(size_type idx)
-            {
-                return table_.begin(idx);
-            }
-
-            const_local_iterator begin(size_type idx) const
-            {
-                return table_.begin(idx);
-            }
-
-            local_iterator end(size_type idx)
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator end(size_type idx) const
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator cbegin(size_type idx) const
-            {
-                return table_.cbegin(idx);
-            }
-
-            const_local_iterator cend(size_type idx) const
-            {
-                return table_.cend(idx);
-            }
-
-            float load_factor() const noexcept
-            {
-                return table_.load_factor();
-            }
-
-            float max_load_factor() const noexcept
-            {
-                return table_.max_load_factor();
-            }
-
-            void max_load_factor(float factor)
-            {
-                table_.max_load_factor(factor);
-            }
-
-            void rehash(size_type bucket_count)
-            {
-                table_.rehash(bucket_count);
-            }
-
-            void reserve(size_type count)
-            {
-                table_.reserve(count);
-            }
-
-        private:
-            using table_type = aux::hash_table<
-                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
-                hasher, key_equal, allocator_type, size_type,
-                iterator, const_iterator, local_iterator, const_local_iterator,
-                aux::hash_single_policy
-            >;
-            using node_type = typename table_type::node_type;
-
-            table_type table_;
-            allocator_type allocator_;
-
-            static constexpr size_type default_bucket_count_{16};
-
-            template<class K, class V, class H, class P, class A>
-            friend bool operator==(unordered_map<K, V, H, P, A>&,
-                                   unordered_map<K, V, H, P, A>&);
-    };
-
-    /**
-     * 23.5.5, class template unordered_multimap:
-     */
-
-    template<
-        class Key, class Value,
-        class Hash = hash<Key>,
-        class Pred = equal_to<Key>,
-        class Alloc = allocator<pair<const Key, Value>>
-    >
-    class unordered_multimap
-    {
-        public:
-            using key_type        = Key;
-            using mapped_type     = Value;
-            using value_type      = pair<const key_type, mapped_type>;
-            using hasher          = Hash;
-            using key_equal       = Pred;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            using iterator             = aux::hash_table_iterator<
-                value_type, reference, pointer, size_type
-            >;
-            using const_iterator       = aux::hash_table_const_iterator<
-                value_type, const_reference, const_pointer, size_type
-            >;
-            using local_iterator       = aux::hash_table_local_iterator<
-                value_type, reference, pointer
-            >;
-            using const_local_iterator = aux::hash_table_const_local_iterator<
-                value_type, const_reference, const_pointer
-            >;
-
-            unordered_multimap()
-                : unordered_multimap{default_bucket_count_}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_multimap(size_type bucket_count,
-                                        const hasher& hf = hasher{},
-                                        const key_equal& eql = key_equal{},
-                                        const allocator_type& alloc = allocator_type{})
-                : table_{bucket_count, hf, eql}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multimap(InputIterator first, InputIterator last,
-                               size_type bucket_count = default_bucket_count_,
-                               const hasher& hf = hasher{},
-                               const key_equal& eql = key_equal{},
-                               const allocator_type& alloc = allocator_type{})
-                : unordered_multimap{bucket_count, hf, eql, alloc}
-            {
-                insert(first, last);
-            }
-
-            unordered_multimap(const unordered_multimap& other)
-                : unordered_multimap{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(unordered_multimap&& other)
-                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_multimap(const allocator_type& alloc)
-                : table_{default_bucket_count_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(const unordered_multimap& other, const allocator_type& alloc)
-                : table_{other.table_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(unordered_multimap&& other, const allocator_type& alloc)
-                : table_{move(other.table_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(initializer_list<value_type> init,
-                               size_type bucket_count = default_bucket_count_,
-                               const hasher& hf = hasher{},
-                               const key_equal& eql = key_equal{},
-                               const allocator_type& alloc = allocator_type{})
-                : unordered_multimap{bucket_count, hf, eql, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            unordered_multimap(size_type bucket_count, const allocator_type& alloc)
-                : unordered_multimap{bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(size_type bucket_count, const hasher& hf,
-                               const allocator_type& alloc)
-                : unordered_multimap{bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multimap(InputIterator first, InputIterator last,
-                               size_type bucket_count, const allocator_type& alloc)
-                : unordered_multimap{first, last, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multimap(InputIterator first, InputIterator last,
-                               size_type bucket_count, const hasher& hf,
-                               const allocator_type& alloc)
-                : unordered_multimap{first, last, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(initializer_list<value_type> init, size_type bucket_count,
-                               const allocator_type& alloc)
-                : unordered_multimap{init, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multimap(initializer_list<value_type> init, size_type bucket_count,
-                               const hasher& hf, const allocator_type& alloc)
-                : unordered_multimap{init, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~unordered_multimap()
-            { /* DUMMY BODY */ }
-
-            unordered_multimap& operator=(const unordered_multimap& other)
-            {
-                table_ = other.table_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            unordered_multimap& operator=(unordered_multimap&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<hasher>::value &&
-                         is_nothrow_move_assignable<key_equal>::value)
-            {
-                table_ = move(other.table_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            unordered_multimap& operator=(initializer_list<value_type>& init)
-            {
-                table_.clear();
-                table_.reserve(init.size());
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            bool empty() const noexcept
-            {
-                return table_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return table_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return table_.max_size(allocator_);
-            }
-
-            iterator begin() noexcept
-            {
-                return table_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return table_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return table_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return table_.cend();
-            }
-
-            template<class... Args>
-            iterator emplace(Args&&... args)
-            {
-                return table_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...);
-            }
-
-            iterator insert(const value_type& val)
-            {
-                return table_.insert(val);
-            }
-
-            iterator insert(value_type&& val)
-            {
-                return table_.insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            iterator insert(
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace(forward<T>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val);
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val));
-            }
-
-            template<class T>
-            iterator insert(
-                const_iterator hint,
-                T&& val,
-                enable_if_t<is_constructible_v<value_type, T&&>>* = nullptr
-            )
-            {
-                return emplace_hint(hint, forward<T>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return table_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return table_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    table_.table(), first.idx(),
-                    table_.bucket_count(), table_.head(first.idx())
-                };
-            }
-
-            void clear() noexcept
-            {
-                table_.clear();
-            }
-
-            void swap(unordered_multimap& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
-                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
-            {
-                table_.swap(other.table_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            hasher hash_function() const
-            {
-                return table_.hash_function();
-            }
-
-            key_equal key_eq() const
-            {
-                return table_.key_eq();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return table_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return table_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return table_.count(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return table_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return table_.equal_range(key);
-            }
-
-            size_type bucket_count() const noexcept
-            {
-                return table_.bucket_count();
-            }
-
-            size_type max_bucket_count() const noexcept
-            {
-                return table_.max_bucket_count();
-            }
-
-            size_type bucket_size(size_type idx) const
-            {
-                return table_.bucket_size(idx);
-            }
-
-            size_type bucket(const key_type& key) const
-            {
-                return table_.bucket(key);
-            }
-
-            local_iterator begin(size_type idx)
-            {
-                return table_.begin(idx);
-            }
-
-            const_local_iterator begin(size_type idx) const
-            {
-                return table_.begin(idx);
-            }
-
-            local_iterator end(size_type idx)
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator end(size_type idx) const
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator cbegin(size_type idx) const
-            {
-                return table_.cbegin(idx);
-            }
-
-            const_local_iterator cend(size_type idx) const
-            {
-                return table_.cend(idx);
-            }
-
-            float load_factor() const noexcept
-            {
-                return table_.load_factor();
-            }
-
-            float max_load_factor() const noexcept
-            {
-                return table_.max_load_factor();
-            }
-
-            void max_load_factor(float factor)
-            {
-                table_.max_load_factor(factor);
-            }
-
-            void rehash(size_type bucket_count)
-            {
-                table_.rehash(bucket_count);
-            }
-
-            void reserve(size_type count)
-            {
-                table_.reserve(count);
-            }
-
-        private:
-            using table_type = aux::hash_table<
-                value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>,
-                hasher, key_equal, allocator_type, size_type,
-                iterator, const_iterator, local_iterator, const_local_iterator,
-                aux::hash_multi_policy
-            >;
-
-            table_type table_;
-            allocator_type allocator_;
-
-            static constexpr size_type default_bucket_count_{16};
-
-            template<class K, class V, class H, class P, class A>
-            friend bool operator==(unordered_multimap<K, V, H, P, A>&,
-                                   unordered_multimap<K, V, H, P, A>&);
-    };
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    void swap(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
-              unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    void swap(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
-              unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    bool operator==(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
-                    unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
-    {
-        // TODO: this does not compare values, use is_permutation when we have it
-        return lhs.table_.is_eq_to(rhs.table_);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    bool operator!=(unordered_map<Key, Value, Hash, Pred, Alloc>& lhs,
-                    unordered_map<Key, Value, Hash, Pred, Alloc>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    bool operator==(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
-                    unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
-    {
-        return lhs.table_.is_eq_to(rhs.table_);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    bool operator!=(unordered_multimap<Key, Value, Hash, Pred, Alloc>& lhs,
-                    unordered_multimap<Key, Value, Hash, Pred, Alloc>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/unordered_set.hpp
===================================================================
--- uspace/lib/cpp/include/impl/unordered_set.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,917 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_UNORDERED_SET
-#define LIBCPP_UNORDERED_SET
-
-#include <initializer_list>
-#include <__bits/hash_table.hpp>
-#include <functional>
-#include <memory>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 23.5.6, class template unordered_set:
-     */
-
-    template<
-        class Key,
-        class Hash = hash<Key>,
-        class Pred = equal_to<Key>,
-        class Alloc = allocator<Key>
-    >
-    class unordered_set
-    {
-        public:
-            using key_type        = Key;
-            using value_type      = Key;
-            using hasher          = Hash;
-            using key_equal       = Pred;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            /**
-             * Note: Both the iterator and const_iterator (and their local variants)
-             *       types are constant iterators, the standard does not require them
-             *       to be the same type, but why not? :)
-             */
-            using iterator             = aux::hash_table_const_iterator<
-                value_type, const_reference, const_pointer, size_type
-            >;
-            using const_iterator       = iterator;
-            using local_iterator       = aux::hash_table_const_local_iterator<
-                value_type, const_reference, const_pointer
-            >;
-            using const_local_iterator = local_iterator;
-
-            /**
-             * Note: We need () to delegate the constructor,
-             *       otherwise it could be deduced as the initializer
-             *       list constructor when size_type is convertible
-             *       to value_type.
-             */
-            unordered_set()
-                : unordered_set(default_bucket_count_)
-            { /* DUMMY BODY */ }
-
-            explicit unordered_set(size_type bucket_count,
-                                   const hasher& hf = hasher{},
-                                   const key_equal& eql = key_equal{},
-                                   const allocator_type& alloc = allocator_type{})
-                : table_{bucket_count, hf, eql}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_set(InputIterator first, InputIterator last,
-                          size_type bucket_count = default_bucket_count_,
-                          const hasher& hf = hasher{},
-                          const key_equal& eql = key_equal{},
-                          const allocator_type& alloc = allocator_type{})
-                : unordered_set{bucket_count, hf, eql, alloc}
-            {
-                insert(first, last);
-            }
-
-            unordered_set(const unordered_set& other)
-                : unordered_set{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            unordered_set(unordered_set&& other)
-                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_set(const allocator_type& alloc)
-                : table_{default_bucket_count_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(const unordered_set& other, const allocator_type& alloc)
-                : table_{other.table_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(unordered_set&& other, const allocator_type& alloc)
-                : table_{move(other.table_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(initializer_list<value_type> init,
-                          size_type bucket_count = default_bucket_count_,
-                          const hasher& hf = hasher{},
-                          const key_equal& eql = key_equal{},
-                          const allocator_type& alloc = allocator_type{})
-                : unordered_set{bucket_count, hf, eql, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            unordered_set(size_type bucket_count, const allocator_type& alloc)
-                : unordered_set{bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_set{bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_set(InputIterator first, InputIterator last,
-                          size_type bucket_count, const allocator_type& alloc)
-                : unordered_set{first, last, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_set(InputIterator first, InputIterator last,
-                          size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_set{first, last, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(initializer_list<value_type> init, size_type bucket_count,
-                          const allocator_type& alloc)
-                : unordered_set{init, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_set(initializer_list<value_type> init, size_type bucket_count,
-                          const hasher& hf, const allocator_type& alloc)
-                : unordered_set{init, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~unordered_set()
-            { /* DUMMY BODY */ }
-
-            unordered_set& operator=(const unordered_set& other)
-            {
-                table_ = other.table_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            unordered_set& operator=(unordered_set&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<hasher>::value &&
-                         is_nothrow_move_assignable<key_equal>::value)
-            {
-                table_ = move(other.table_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            unordered_set& operator=(initializer_list<value_type>& init)
-            {
-                table_.clear();
-                table_.reserve(init.size());
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            bool empty() const noexcept
-            {
-                return table_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return table_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return table_.max_size(allocator_);
-            }
-
-            iterator begin() noexcept
-            {
-                return table_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return table_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return table_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return table_.cend();
-            }
-
-            template<class... Args>
-            pair<iterator, bool> emplace(Args&&... args)
-            {
-                return table_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...).first;
-            }
-
-            pair<iterator, bool> insert(const value_type& val)
-            {
-                return table_.insert(val);
-            }
-
-            pair<iterator, bool> insert(value_type&& val)
-            {
-                return table_.insert(forward<value_type>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val).first;
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val)).first;
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return table_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return table_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    table_.table(), first.idx(),
-                    table_.bucket_count(), first.node()
-                };
-            }
-
-            void clear() noexcept
-            {
-                table_.clear();
-            }
-
-            void swap(unordered_set& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
-                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
-            {
-                table_.swap(other.table_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            hasher hash_function() const
-            {
-                return table_.hash_function();
-            }
-
-            key_equal key_eq() const
-            {
-                return table_.key_eq();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return table_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return table_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return table_.count(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return table_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return table_.equal_range(key);
-            }
-
-            size_type bucket_count() const noexcept
-            {
-                return table_.bucket_count();
-            }
-
-            size_type max_bucket_count() const noexcept
-            {
-                return table_.max_bucket_count();
-            }
-
-            size_type bucket_size(size_type idx) const
-            {
-                return table_.bucket_size(idx);
-            }
-
-            size_type bucket(const key_type& key) const
-            {
-                return table_.bucket(key);
-            }
-
-            local_iterator begin(size_type idx)
-            {
-                return table_.begin(idx);
-            }
-
-            const_local_iterator begin(size_type idx) const
-            {
-                return table_.begin(idx);
-            }
-
-            local_iterator end(size_type idx)
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator end(size_type idx) const
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator cbegin(size_type idx) const
-            {
-                return table_.cbegin(idx);
-            }
-
-            const_local_iterator cend(size_type idx) const
-            {
-                return table_.cend(idx);
-            }
-
-            float load_factor() const noexcept
-            {
-                return table_.load_factor();
-            }
-
-            float max_load_factor() const noexcept
-            {
-                return table_.max_load_factor();
-            }
-
-            void max_load_factor(float factor)
-            {
-                table_.max_load_factor(factor);
-            }
-
-            void rehash(size_type bucket_count)
-            {
-                table_.rehash(bucket_count);
-            }
-
-            void reserve(size_type count)
-            {
-                table_.reserve(count);
-            }
-
-        private:
-            using table_type = aux::hash_table<
-                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
-                hasher, key_equal, allocator_type, size_type,
-                iterator, const_iterator, local_iterator, const_local_iterator,
-                aux::hash_single_policy
-            >;
-
-            table_type table_;
-            allocator_type allocator_;
-
-            static constexpr size_type default_bucket_count_{16};
-
-            template<class K, class H, class P, class A>
-            friend bool operator==(const unordered_set<K, H, P, A>&,
-                                   const unordered_set<K, H, P, A>&);
-    };
-
-    /**
-     * 23.5.7, class template unordered_multiset:
-     */
-
-    template<
-        class Key,
-        class Hash = hash<Key>,
-        class Pred = equal_to<Key>,
-        class Alloc = allocator<Key>
-    >
-    class unordered_multiset
-    {
-        public:
-            using key_type        = Key;
-            using value_type      = Key;
-            using hasher          = Hash;
-            using key_equal       = Pred;
-            using allocator_type  = Alloc;
-            using pointer         = typename allocator_traits<allocator_type>::pointer;
-            using const_pointer   = typename allocator_traits<allocator_type>::const_pointer;
-            using reference       = value_type&;
-            using const_reference = const value_type&;
-            using size_type       = size_t;
-            using difference_type = ptrdiff_t;
-
-            /**
-             * Note: Both the iterator and const_iterator (and their local variants)
-             *       types are constant iterators, the standard does not require them
-             *       to be the same type, but why not? :)
-             */
-            using iterator             = aux::hash_table_const_iterator<
-                value_type, const_reference, const_pointer, size_type
-            >;
-            using const_iterator       = iterator;
-            using local_iterator       = aux::hash_table_const_local_iterator<
-                value_type, const_reference, const_pointer
-            >;
-            using const_local_iterator = local_iterator;
-
-            /**
-             * Note: We need () to delegate the constructor,
-             *       otherwise it could be deduced as the initializer
-             *       list constructor when size_type is convertible
-             *       to value_type.
-             */
-            unordered_multiset()
-                : unordered_multiset(default_bucket_count_)
-            { /* DUMMY BODY */ }
-
-            explicit unordered_multiset(size_type bucket_count,
-                                        const hasher& hf = hasher{},
-                                        const key_equal& eql = key_equal{},
-                                        const allocator_type& alloc = allocator_type{})
-                : table_{bucket_count, hf, eql}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multiset(InputIterator first, InputIterator last,
-                               size_type bucket_count = default_bucket_count_,
-                               const hasher& hf = hasher{},
-                               const key_equal& eql = key_equal{},
-                               const allocator_type& alloc = allocator_type{})
-                : unordered_multiset{bucket_count, hf, eql, alloc}
-            {
-                insert(first, last);
-            }
-
-            unordered_multiset(const unordered_multiset& other)
-                : unordered_multiset{other, other.allocator_}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(unordered_multiset&& other)
-                : table_{move(other.table_)}, allocator_{move(other.allocator_)}
-            { /* DUMMY BODY */ }
-
-            explicit unordered_multiset(const allocator_type& alloc)
-                : table_{default_bucket_count_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(const unordered_multiset& other, const allocator_type& alloc)
-                : table_{other.table_}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(unordered_multiset&& other, const allocator_type& alloc)
-                : table_{move(other.table_)}, allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(initializer_list<value_type> init,
-                               size_type bucket_count = default_bucket_count_,
-                               const hasher& hf = hasher{},
-                               const key_equal& eql = key_equal{},
-                               const allocator_type& alloc = allocator_type{})
-                : unordered_multiset{bucket_count, hf, eql, alloc}
-            {
-                insert(init.begin(), init.end());
-            }
-
-            unordered_multiset(size_type bucket_count, const allocator_type& alloc)
-                : unordered_multiset{bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_multiset{bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multiset(InputIterator first, InputIterator last,
-                               size_type bucket_count, const allocator_type& alloc)
-                : unordered_multiset{first, last, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            template<class InputIterator>
-            unordered_multiset(InputIterator first, InputIterator last,
-                               size_type bucket_count, const hasher& hf, const allocator_type& alloc)
-                : unordered_multiset{first, last, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
-                               const allocator_type& alloc)
-                : unordered_multiset{init, bucket_count, hasher{}, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            unordered_multiset(initializer_list<value_type> init, size_type bucket_count,
-                               const hasher& hf, const allocator_type& alloc)
-                : unordered_multiset{init, bucket_count, hf, key_equal{}, alloc}
-            { /* DUMMY BODY */ }
-
-            ~unordered_multiset()
-            { /* DUMMY BODY */ }
-
-            unordered_multiset& operator=(const unordered_multiset& other)
-            {
-                table_ = other.table_;
-                allocator_ = other.allocator_;
-
-                return *this;
-            }
-
-            unordered_multiset& operator=(unordered_multiset&& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         is_nothrow_move_assignable<hasher>::value &&
-                         is_nothrow_move_assignable<key_equal>::value)
-            {
-                table_ = move(other.table_);
-                allocator_ = move(other.allocator_);
-
-                return *this;
-            }
-
-            unordered_multiset& operator=(initializer_list<value_type>& init)
-            {
-                table_.clear();
-                table_.reserve(init.size());
-
-                insert(init.begin(), init.end());
-
-                return *this;
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_;
-            }
-
-            bool empty() const noexcept
-            {
-                return table_.empty();
-            }
-
-            size_type size() const noexcept
-            {
-                return table_.size();
-            }
-
-            size_type max_size() const noexcept
-            {
-                return table_.max_size(allocator_);
-            }
-
-            iterator begin() noexcept
-            {
-                return table_.begin();
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return table_.begin();
-            }
-
-            iterator end() noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator end() const noexcept
-            {
-                return table_.end();
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return table_.cbegin();
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return table_.cend();
-            }
-
-            template<class... Args>
-            iterator emplace(Args&&... args)
-            {
-                return table_.emplace(forward<Args>(args)...);
-            }
-
-            template<class... Args>
-            iterator emplace_hint(const_iterator, Args&&... args)
-            {
-                return emplace(forward<Args>(args)...);
-            }
-
-            iterator insert(const value_type& val)
-            {
-                return table_.insert(val);
-            }
-
-            iterator insert(value_type&& val)
-            {
-                return table_.insert(forward<value_type>(val));
-            }
-
-            iterator insert(const_iterator, const value_type& val)
-            {
-                return insert(val);
-            }
-
-            iterator insert(const_iterator, value_type&& val)
-            {
-                return insert(forward<value_type>(val));
-            }
-
-            template<class InputIterator>
-            void insert(InputIterator first, InputIterator last)
-            {
-                while (first != last)
-                    insert(*first++);
-            }
-
-            void insert(initializer_list<value_type> init)
-            {
-                insert(init.begin(), init.end());
-            }
-
-            iterator erase(const_iterator position)
-            {
-                return table_.erase(position);
-            }
-
-            size_type erase(const key_type& key)
-            {
-                return table_.erase(key);
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                while (first != last)
-                    first = erase(first);
-
-                return iterator{
-                    table_.table(), first.idx(),
-                    table_.bucket_count(), table_.head(first.idx())
-                };
-            }
-
-            void clear() noexcept
-            {
-                table_.clear();
-            }
-
-            void swap(unordered_multiset& other)
-                noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-                         noexcept(std::swap(declval<hasher>(), declval<hasher>())) &&
-                         noexcept(std::swap(declval<key_equal>(), declval<key_equal>())))
-            {
-                table_.swap(other.table_);
-                std::swap(allocator_, other.allocator_);
-            }
-
-            hasher hash_function() const
-            {
-                return table_.hash_function();
-            }
-
-            key_equal key_eq() const
-            {
-                return table_.key_eq();
-            }
-
-            iterator find(const key_type& key)
-            {
-                return table_.find(key);
-            }
-
-            const_iterator find(const key_type& key) const
-            {
-                return table_.find(key);
-            }
-
-            size_type count(const key_type& key) const
-            {
-                return table_.count(key);
-            }
-
-            pair<iterator, iterator> equal_range(const key_type& key)
-            {
-                return table_.equal_range(key);
-            }
-
-            pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-            {
-                return table_.equal_range(key);
-            }
-
-            size_type bucket_count() const noexcept
-            {
-                return table_.bucket_count();
-            }
-
-            size_type max_bucket_count() const noexcept
-            {
-                return table_.max_bucket_count();
-            }
-
-            size_type bucket_size(size_type idx) const
-            {
-                return table_.bucket_size(idx);
-            }
-
-            size_type bucket(const key_type& key) const
-            {
-                return table_.bucket(key);
-            }
-
-            local_iterator begin(size_type idx)
-            {
-                return table_.begin(idx);
-            }
-
-            const_local_iterator begin(size_type idx) const
-            {
-                return table_.begin(idx);
-            }
-
-            local_iterator end(size_type idx)
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator end(size_type idx) const
-            {
-                return table_.end(idx);
-            }
-
-            const_local_iterator cbegin(size_type idx) const
-            {
-                return table_.cbegin(idx);
-            }
-
-            const_local_iterator cend(size_type idx) const
-            {
-                return table_.cend(idx);
-            }
-
-            float load_factor() const noexcept
-            {
-                return table_.load_factor();
-            }
-
-            float max_load_factor() const noexcept
-            {
-                return table_.max_load_factor();
-            }
-
-            void max_load_factor(float factor)
-            {
-                table_.max_load_factor(factor);
-            }
-
-            void rehash(size_type bucket_count)
-            {
-                table_.rehash(bucket_count);
-            }
-
-            void reserve(size_type count)
-            {
-                table_.reserve(count);
-            }
-
-        private:
-            using table_type = aux::hash_table<
-                key_type, key_type, aux::key_no_value_key_extractor<key_type>,
-                hasher, key_equal, allocator_type, size_type,
-                iterator, const_iterator, local_iterator, const_local_iterator,
-                aux::hash_multi_policy
-            >;
-
-            table_type table_;
-            allocator_type allocator_;
-
-            static constexpr size_type default_bucket_count_{16};
-
-            template<class K, class H, class P, class A>
-            friend bool operator==(const unordered_multiset<K, H, P, A>&,
-                                   const unordered_multiset<K, H, P, A>&);
-    };
-
-    template<class Key, class Hash, class Pred, class Alloc>
-    void swap(unordered_set<Key, Hash, Pred, Alloc>& lhs,
-              unordered_set<Key, Hash, Pred, Alloc>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class Key, class Hash, class Pred, class Alloc>
-    void swap(unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
-              unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class Key, class Hash, class Pred, class Alloc>
-    bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& lhs,
-                    const unordered_set<Key, Hash, Pred, Alloc>& rhs)
-    {
-        return lhs.table_.is_eq_to(rhs.table_);
-    }
-
-    template<class Key, class Hash, class Pred, class Alloc>
-    bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& lhs,
-                    const unordered_set<Key, Hash, Pred, Alloc>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class Key, class Hash, class Pred, class Alloc>
-    bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
-                    const unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
-    {
-        return lhs.table_.is_eq_to(rhs.table_);
-    }
-
-    template<class Key, class Value, class Hash, class Pred, class Alloc>
-    bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& lhs,
-                    const unordered_multiset<Key, Hash, Pred, Alloc>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/utility.hpp
===================================================================
--- uspace/lib/cpp/include/impl/utility.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,458 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_UTILITY
-#define LIBCPP_UTILITY
-
-#include <cstdint>
-#include <__bits/type_transformation.hpp>
-#include <__bits/utility/forward_move.hpp>
-#include <type_traits>
-
-namespace std
-{
-    /**
-     * 20.2.1, operators:
-     */
-
-    namespace rel_ops
-    {
-        template<typename T>
-        bool operator!=(const T& lhs, const T& rhs)
-        {
-            return !(lhs == rhs);
-        }
-
-        template<typename T>
-        bool operator>(const T& lhs, const T& rhs)
-        {
-            return (rhs < lhs);
-        }
-
-        template<typename T>
-        bool operator<=(const T& lhs, const T& rhs)
-        {
-            return !(rhs < lhs);
-        }
-
-        template<typename T>
-        bool operator>=(const T& lhs, const T& rhs)
-        {
-            return !(lhs < rhs);
-        }
-    }
-
-    /**
-     * 20.2.2, swap:
-     */
-
-    template<class T>
-    void swap(T& x, T& y)
-        /* noexcept(is_nothrow_move_constructible<T>::value && */
-        /*          is_nothrow_move_assignable<T>::value) */
-    {
-        T tmp{move(x)};
-        x = move(y);
-        y = move(tmp);
-    }
-
-    template<class F1, class F2>
-    F2 swap_ranges(F1, F1, F2);
-
-    template<class T, size_t N>
-    void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)))
-    {
-        swap_ranges(a, a + N, b);
-    }
-
-    /**
-     * 20.2.3, exchange:
-     */
-
-    template<class T, class U = T>
-    T exchange(T& obj, U&& new_val)
-    {
-        T old_val = move(obj);
-        obj = forward<U>(new_val);
-
-        return old_val;
-    }
-
-    /**
-     * 20.5.2, class template integer_sequence:
-     */
-
-    template<class T, T... Is>
-    struct integer_sequence
-    {
-        using value_type = T;
-
-        static constexpr size_t size() noexcept
-        {
-            return sizeof...(Is);
-        }
-
-        using next = integer_sequence<T, Is..., sizeof...(Is)>;
-    };
-
-    template<std::size_t... Is>
-    using index_sequence = integer_sequence<std::size_t, Is...>;
-
-    /**
-     * 20.5.3, alias template make_integer_sequence:
-     */
-
-    namespace aux
-    {
-        template<class T, uintmax_t N>
-        struct make_integer_sequence
-        {
-            /**
-             * Recursive to the bottom case below, appends sizeof...(Is) in
-             * every next "call", building the sequence.
-             */
-            using type = typename make_integer_sequence<T, N - 1>::type::next;
-        };
-
-        template<class T>
-        struct make_integer_sequence<T, std::uintmax_t(0)>
-        {
-            using type = integer_sequence<T>;
-        };
-    }
-
-
-    /**
-     * Problem: We can't specialize the N parameter because it is a value parameter
-     *          depending on a type parameter.
-     * Solution: According to the standard: if N is negative, the program is ill-formed,
-     *           so we just recast it to uintmax_t :)
-     */
-    template<class T, T N>
-    using make_integer_sequence = typename aux::make_integer_sequence<T, std::uintmax_t(N)>::type;
-
-    template<size_t N>
-    using make_index_sequence = make_integer_sequence<std::size_t, N>;
-
-    /**
-     * 20.3, pairs:
-     */
-
-    template<size_t, class>
-    class tuple_element;
-
-    template<size_t I, class T>
-    using tuple_element_t = typename tuple_element<I, T>::type;
-
-    template<class...>
-    class tuple;
-
-    template<size_t I, class... Ts>
-    constexpr tuple_element_t<I, tuple<Ts...>>&& get(tuple<Ts...>&&) noexcept;
-
-    namespace aux
-    {
-        template<class T, class... Args, size_t... Is>
-        T from_tuple(tuple<Args...>&& tpl, index_sequence<Is...>)
-        {
-            return T{get<Is>(move(tpl))...};
-        }
-
-        template<class T, class... Args>
-        T from_tuple(tuple<Args...>&& tpl)
-        {
-            return from_tuple<T>(move(tpl), make_index_sequence<sizeof...(Args)>{});
-        }
-    }
-
-    struct piecewise_construct_t
-    {
-        explicit piecewise_construct_t() = default;
-    };
-
-    inline constexpr piecewise_construct_t piecewise_construct{};
-
-    template<typename T1, typename T2>
-    struct pair
-    {
-        using first_type  = T1;
-        using second_type = T2;
-
-        T1 first;
-        T2 second;
-
-        pair(const pair&) = default;
-        pair(pair&&) = default;
-
-        constexpr pair()
-            : first{}, second{}
-        { /* DUMMY BODY */ }
-
-        constexpr pair(const T1& x, const T2& y)
-            : first{x}, second{y}
-        { /* DUMMY BODY */ }
-
-        template<typename U, typename V>
-        constexpr pair(U&& x, V&& y)
-            : first(x), second(y)
-        { /* DUMMY BODY */ }
-
-        template<typename U, typename V>
-        constexpr pair(const pair<U, V>& other)
-            : first(other.first), second(other.second)
-        { /* DUMMY BODY */ }
-
-        template<typename U, typename V>
-        constexpr pair(pair<U, V>&& other)
-            : first(forward<first_type>(other.first)),
-              second(forward<second_type>(other.second))
-        { /* DUMMY BODY */ }
-
-        template<class... Args1, class... Args2>
-        pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args)
-            : first{aux::from_tuple<first_type>(move(first_args))},
-              second{aux::from_tuple<second_type>(move(second_args))}
-        { /* DUMMY BODY */ }
-
-        pair& operator=(const pair& other)
-        {
-            first = other.first;
-            second = other.second;
-
-            return *this;
-        }
-
-        template<typename U, typename V>
-        pair& operator=(const pair<U, V>& other)
-        {
-            first = other.first;
-            second = other.second;
-
-            return *this;
-        }
-
-        pair& operator=(pair&& other) noexcept
-        {
-            first = forward<first_type>(other.first);
-            second = forward<second_type>(other.second);
-
-            return *this;
-        }
-
-        template<typename U, typename V>
-        pair& operator=(pair<U, V>&& other)
-        {
-            first = forward<first_type>(other.first);
-            second = forward<second_type>(other.second);
-
-            return *this;
-        }
-
-        void swap(pair& other) noexcept(
-            noexcept(std::swap(first, other.first)) &&
-            noexcept(std::swap(second, other.second))
-        )
-        {
-            std::swap(first, other.first);
-            std::swap(second, other.second);
-        }
-    };
-
-    /**
-     * 20.3.3, specialized algorithms:
-     */
-
-    template<class T1, class T2>
-    constexpr bool operator==(const pair<T1, T2>& lhs,
-                              const pair<T1, T2>& rhs)
-    {
-        return lhs.first == rhs.first && lhs.second == rhs.second;
-    }
-
-    template<class T1, class T2>
-    constexpr bool operator<(const pair<T1, T2>& lhs,
-                             const pair<T1, T2>& rhs)
-    {
-        return lhs.first < rhs.first ||
-            (!(rhs.first < lhs.first) && lhs.second < rhs.second);
-    }
-
-    template<class T1, class T2>
-    constexpr bool operator!=(const pair<T1, T2>& lhs,
-                              const pair<T1, T2>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class T1, class T2>
-    constexpr bool operator>(const pair<T1, T2>& lhs,
-                             const pair<T1, T2>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class T1, class T2>
-    constexpr bool operator>=(const pair<T1, T2>& lhs,
-                              const pair<T1, T2>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class T1, class T2>
-    constexpr bool operator<=(const pair<T1, T2>& lhs,
-                              const pair<T1, T2>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    template<class T1, class T2>
-    constexpr void swap(pair<T1, T2>& lhs, pair<T1, T2>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    template<class T1, class T2>
-    constexpr auto make_pair(T1&& t1, T2&& t2)
-    {
-        return pair<
-            aux::transform_tuple_types_t<T1>,
-            aux::transform_tuple_types_t<T2>
-        >{
-            forward<T1>(t1), forward<T2>(t2)
-        };
-    }
-
-    /**
-     * 20.3.4, tuple-like access to pair:
-     */
-
-    template<class>
-    struct tuple_size;
-
-    template<class T1, class T2>
-    struct tuple_size<pair<T1, T2>>
-        : integral_constant<size_t, 2>
-    { /* DUMMY BODY */ };
-
-    template<size_t, class>
-    struct tuple_element;
-
-    template<class T1, class T2>
-    struct tuple_element<0, pair<T1, T2>>
-        : aux::type_is<T1>
-    { /* DUMMY BODY */ };
-
-    template<class T1, class T2>
-    struct tuple_element<1, pair<T1, T2>>
-        : aux::type_is<T2>
-    { /* DUMMY BODY */ };
-
-    template<size_t I, class T>
-    using tuple_element_t = typename tuple_element<I, T>::type;
-
-    template<size_t I, class T1, class T2>
-    constexpr tuple_element_t<I, pair<T1, T2>>&
-    get(pair<T1, T2>& p) noexcept
-    {
-        if constexpr (I == 0)
-            return p.first;
-        else
-            return p.second;
-    }
-
-    template<size_t I, class T1, class T2>
-    constexpr const tuple_element_t<I, pair<T1, T2>>&
-    get(const pair<T1, T2>& p) noexcept
-    {
-        if constexpr (I == 0)
-            return p.first;
-        else
-            return p.second;
-    }
-
-    template<size_t I, class T1, class T2>
-    constexpr tuple_element_t<I, pair<T1, T2>>&&
-    get(pair<T1, T2>&& p) noexcept
-    {
-        if constexpr (I == 0)
-            return forward<T1>(p.first);
-        else
-            return forward<T2>(p.second);
-    }
-
-    template<class T, class U>
-    constexpr T& get(pair<T, U>& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<0>(p);
-    }
-
-    template<class T, class U>
-    constexpr const T& get(const pair<T, U>& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<0>(p);
-    }
-
-    template<class T, class U>
-    constexpr T&& get(pair<T, U>&& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<0>(move(p));
-    }
-
-    template<class T, class U>
-    constexpr T& get(pair<U, T>& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<1>(p);
-    }
-
-    template<class T, class U>
-    constexpr const T& get(const pair<U, T>& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<1>(p);
-    }
-
-    template<class T, class U>
-    constexpr T&& get(pair<U, T>&& p) noexcept
-    {
-        static_assert(!is_same_v<T, U>, "get(pair) requires distinct types");
-
-        return get<1>(move(p));
-    }
-}
-
-#endif
Index: uspace/lib/cpp/include/impl/valarray.hpp
===================================================================
--- uspace/lib/cpp/include/impl/valarray.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_VALARRAY
-#define LIBCPP_VALARRAY
-
-#error "<valarray> is not implemented"
-
-#endif
Index: uspace/lib/cpp/include/impl/vector.hpp
===================================================================
--- uspace/lib/cpp/include/impl/vector.hpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ 	(revision )
@@ -1,666 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIBCPP_VECTOR
-#define LIBCPP_VECTOR
-
-#include <algorithm>
-#include <initializer_list>
-#include <iterator>
-#include <memory>
-#include <utility>
-
-namespace std
-{
-    /**
-     * 23.3.6, vector:
-     */
-
-    template<class T, class Allocator = allocator<T>>
-    class vector
-    {
-        public:
-            using value_type             = T;
-            using reference              = value_type&;
-            using const_reference        = const value_type&;
-            using allocator_type         = Allocator;
-            using size_type              = size_t;
-            using difference_type        = ptrdiff_t;
-            using pointer                = typename allocator_traits<Allocator>::pointer;
-            using const_pointer          = typename allocator_traits<Allocator>::pointer;
-            using iterator               = pointer;
-            using const_iterator         = const_pointer;
-            using reverse_iterator       = std::reverse_iterator<iterator>;
-            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-            vector() noexcept
-                : vector{Allocator{}}
-            { /* DUMMY BODY */ }
-
-            explicit vector(const Allocator& alloc)
-                : data_{nullptr}, size_{}, capacity_{},
-                  allocator_{alloc}
-            { /* DUMMY BODY */ }
-
-            explicit vector(size_type n, const Allocator& alloc = Allocator{})
-                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
-            {
-                data_ = allocator_.allocate(capacity_);
-
-                for (size_type i = 0; i < size_; ++i)
-                    allocator_traits<Allocator>::construct(allocator_, data_ + i);
-            }
-
-            vector(size_type n, const T& val, const Allocator& alloc = Allocator{})
-                : data_{}, size_{n}, capacity_{n}, allocator_{alloc}
-            {
-                data_ = allocator_.allocate(capacity_);
-
-                for (size_type i = 0; i < size_; ++i)
-                    data_[i] = val;
-            }
-
-            template<class InputIterator>
-            vector(InputIterator first, InputIterator last,
-                   const Allocator& alloc = Allocator{})
-            {
-                // TODO: research constraints and provide multiple
-                //       implementations via enable_if
-            }
-
-            vector(const vector& other)
-                : data_{nullptr}, size_{other.size_}, capacity_{other.capacity_},
-                  allocator_{other.allocator_}
-            {
-                data_ = allocator_.allocate(capacity_);
-
-                for (size_type i = 0; i < size_; ++i)
-                    data_[i] = other.data_[i];
-            }
-
-            vector(vector&& other) noexcept
-                : data_{other.data_}, size_{other.size_}, capacity_{other.capacity_},
-                  allocator_{move(other.allocator_)}
-            {
-                // other is guaranteed to be empty()
-                other.size_ = other.capacity_ = 0;
-                other.data_ = nullptr;
-            }
-
-            vector(const vector& other, const Allocator& alloc)
-                : data_{nullptr}, size_{other.size_}, capacity_{other.capacity_},
-                  allocator_{alloc}
-            {
-                data_ = allocator_.allocate(capacity_);
-
-                for (size_type i = 0; i < size_; ++i)
-                    data_[i] = other.data_[i];
-            }
-
-            vector(initializer_list<T> init, const Allocator& alloc = Allocator{})
-                : data_{nullptr}, size_{init.size()}, capacity_{init.size()},
-                  allocator_{alloc}
-            {
-                data_ = allocator_.allocate(capacity_);
-
-                auto it = init.begin();
-                for (size_type i = 0; it != init.end(); ++i, ++it)
-                {
-                    data_[i] = *it;
-                }
-            }
-
-            ~vector()
-            {
-                allocator_.deallocate(data_, capacity_);
-            }
-
-            vector& operator=(const vector& other)
-            {
-                vector tmp{other};
-                swap(tmp);
-
-                return *this;
-            }
-
-            vector& operator=(vector&& other)
-                noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
-                         allocator_traits<Allocator>::is_always_equal::value)
-            {
-                if (data_)
-                    allocator_.deallocate(data_, capacity_);
-
-                // TODO: test this
-                data_ = other.data_;
-                size_ = other.size_;
-                capacity_ = other.capacity_;
-                allocator_ = move(other.allocator_);
-
-                other.data_ = nullptr;
-                other.size_ = size_type{};
-                other.capacity_ = size_type{};
-                other.allocator_ = allocator_type{};
-                return *this;
-            }
-
-            vector& operator=(initializer_list<T> init)
-            {
-                vector tmp{init, allocator_};
-                swap(tmp);
-
-                return *this;
-            }
-
-            template<class InputIterator>
-            void assign(InputIterator first, InputIterator last)
-            {
-                vector tmp{first, last};
-                swap(tmp);
-            }
-
-            void assign(size_type size, const T& val)
-            {
-                // Parenthesies required to avoid initializer list
-                // construction.
-                vector tmp(size, val);
-                swap(tmp);
-            }
-
-            void assign(initializer_list<T> init)
-            {
-                vector tmp{init};
-                swap(tmp);
-            }
-
-            allocator_type get_allocator() const noexcept
-            {
-                return allocator_type{allocator_};
-            }
-
-            iterator begin() noexcept
-            {
-                return &data_[0];
-            }
-
-            const_iterator begin() const noexcept
-            {
-                return &data_[0];
-            }
-
-            iterator end() noexcept
-            {
-                return begin() + size_;
-            }
-
-            const_iterator end() const noexcept
-            {
-                return begin() + size_;
-            }
-
-            reverse_iterator rbegin() noexcept
-            {
-                return make_reverse_iterator(end());
-            }
-
-            const_reverse_iterator rbegin() const noexcept
-            {
-                return make_reverse_iterator(cend());
-            }
-
-            reverse_iterator rend() noexcept
-            {
-                return make_reverse_iterator(begin());
-            }
-
-            const_reverse_iterator rend() const noexcept
-            {
-                return make_reverse_iterator(cbegin());
-            }
-
-            const_iterator cbegin() const noexcept
-            {
-                return &data_[0];
-            }
-
-            const_iterator cend() const noexcept
-            {
-                return cbegin() + size_;
-            }
-
-            const_reverse_iterator crbegin() const noexcept
-            {
-                return rbegin();
-            }
-
-            const_reverse_iterator crend() const noexcept
-            {
-                return rend();
-            }
-
-            size_type size() const noexcept
-            {
-                return size_;
-            }
-
-            size_type max_size() const noexcept
-            {
-                return std::allocator_traits<Allocator>::max_size(allocator_);
-            }
-
-            void resize(size_type sz)
-            {
-                resize_with_copy_(size_, capacity_);
-            }
-
-            void resize(size_type sz, const value_type& val)
-            {
-                auto old_size = size_;
-                resize_with_copy_(sz, capacity_);
-
-                for (size_type i = old_size - 1; i < size_; ++i)
-                    data_[i] = val;
-            }
-
-            size_type capacity() const noexcept
-            {
-                return capacity_;
-            }
-
-            bool empty() const noexcept
-            {
-                return size_ == 0;
-            }
-
-            void reserve(size_type new_capacity)
-            {
-                // TODO: if new_capacity > max_size() throw
-                //       length_error (this function shall have no
-                //       effect in such case)
-                if (new_capacity > capacity_)
-                    resize_with_copy_(size_, new_capacity);
-            }
-
-            void shrink_to_fit()
-            {
-                resize_with_copy_(size_, size_);
-            }
-
-            reference operator[](size_type idx)
-            {
-                return data_[idx];
-            }
-
-            const_reference operator[](size_type idx) const
-            {
-                return data_[idx];
-            }
-
-            reference at(size_type idx)
-            {
-                // TODO: bounds checking
-                return data_[idx];
-            }
-
-            const_reference at(size_type idx) const
-            {
-                // TODO: bounds checking
-                return data_[idx];
-            }
-
-            reference front()
-            {
-                /**
-                 * Note: Calling front/back on an empty container
-                 *       is undefined, we opted for at-like
-                 *       behavior to provide our users with means
-                 *       to protect their programs from accidental
-                 *       accesses to an empty vector.
-                 */
-                return at(0);
-            }
-
-            const_reference front() const
-            {
-                return at(0);
-            }
-
-            reference back()
-            {
-                return at(size_ - 1);
-            }
-
-            const_reference back() const
-            {
-                return at(size - 1);
-            }
-
-            T* data() noexcept
-            {
-                return data_;
-            }
-
-            const T* data() const noexcept
-            {
-                return data_;
-            }
-
-            template<class... Args>
-            reference emplace_back(Args&&... args)
-            {
-                if (size_ >= capacity_)
-                    resize_with_copy_(size_, next_capacity_());
-
-                allocator_traits<Allocator>::construct(allocator_,
-                                                       begin() + size_, forward<Args>(args)...);
-
-                return back();
-            }
-
-            void push_back(const T& x)
-            {
-                if (size_ >= capacity_)
-                    resize_with_copy_(size_, next_capacity_());
-                data_[size_++] = x;
-            }
-
-            void push_back(T&& x)
-            {
-                if (size_ >= capacity_)
-                    resize_with_copy_(size_, next_capacity_());
-                data_[size_++] = forward<T>(x);
-            }
-
-            void pop_back()
-            {
-                destroy_from_end_until_(end() - 1);
-                --size_;
-            }
-
-            template<class... Args>
-            iterator emplace(const_iterator position, Args&&... args)
-            {
-                auto pos = const_cast<iterator>(position);
-
-                pos = shift_(pos, 1);
-                allocator_.construct(pos, forward<Args>(args)...);
-
-                return pos;
-            }
-
-            iterator insert(const_iterator position, const value_type& x)
-            {
-                auto pos = const_cast<iterator>(position);
-
-                pos = shift_(pos, 1);
-                *pos = x;
-
-                return pos;
-            }
-
-            iterator insert(const_iterator position, value_type&& x)
-            {
-                auto pos = const_cast<iterator>(position);
-
-                pos = shift_(pos, 1);
-                *pos = forward<value_type>(x);
-
-                return pos;
-            }
-
-            iterator insert(const_iterator position, size_type count, const value_type& x)
-            {
-                auto pos = const_cast<iterator>(position);
-
-                pos = shift_(pos, count);
-                auto copy_target = pos;
-                for (size_type i = 0; i < count; ++i)
-                    *copy_target++ = x;
-
-                return pos;
-            }
-
-            template<class InputIterator>
-            iterator insert(const_iterator position, InputIterator first,
-                            InputIterator last)
-            {
-                auto pos = const_cast<iterator>(position);
-                auto count = static_cast<size_type>(last - first);
-
-                pos = shift_(pos, count);
-                copy(first, last, pos);
-
-                return pos;
-            }
-
-            iterator insert(const_iterator position, initializer_list<T> init)
-            {
-                auto pos = const_cast<iterator>(position);
-
-                pos = shift_(pos, init.size());
-                copy(init.begin(), init.end(), pos);
-
-                return pos;
-            }
-
-            iterator erase(const_iterator position)
-            {
-                iterator pos = const_cast<iterator>(position);
-                copy(position + 1, cend(), pos);
-                --size_;
-
-                return pos;
-            }
-
-            iterator erase(const_iterator first, const_iterator last)
-            {
-                iterator pos = const_cast<iterator>(first);
-                copy(last, cend(), pos);
-                size_ -= static_cast<size_type>(last - first);
-
-                return pos;
-            }
-
-            void swap(vector& other)
-                noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
-                         allocator_traits<Allocator>::is_always_equal::value)
-            {
-                std::swap(data_, other.data_);
-                std::swap(size_, other.size_);
-                std::swap(capacity_, other.capacity_);
-            }
-
-            void clear() noexcept
-            {
-                // Note: Capacity remains unchanged.
-                destroy_from_end_until_(begin());
-                size_ = 0;
-            }
-
-        private:
-            value_type* data_;
-            size_type size_;
-            size_type capacity_;
-            allocator_type allocator_;
-
-            void resize_without_copy_(size_type capacity)
-            {
-                if (data_)
-                    allocator_.deallocate(data_, capacity_);
-
-                data_ = allocator_.allocate(capacity);
-                size_ = 0;
-                capacity_ = capacity;
-            }
-
-            void resize_with_copy_(size_type size, size_type capacity)
-            {
-                if (size < size_)
-                    destroy_from_end_until_(begin() + size);
-
-                if(capacity_ == 0 || capacity_ < capacity)
-                {
-                    auto new_data = allocator_.allocate(capacity);
-
-                    auto to_copy = min(size, size_);
-                    for (size_type i = 0; i < to_copy; ++i)
-                        new_data[i] = move(data_[i]);
-
-                    std::swap(data_, new_data);
-
-                    allocator_.deallocate(new_data, capacity_);
-                }
-
-                capacity_ = capacity;
-                size_ = size;
-            }
-
-            void destroy_from_end_until_(iterator target)
-            {
-                if (!empty())
-                {
-                    auto last = end();
-                    while(last != target)
-                        allocator_traits<Allocator>::destroy(allocator_, --last);
-                }
-            }
-
-            size_type next_capacity_(size_type hint = 0) const noexcept
-            {
-                if (hint != 0)
-                    return max(capacity_ * 2, hint);
-                else
-                    return max(capacity_ * 2, 2ul);
-            }
-
-            iterator shift_(iterator position, size_type count)
-            {
-                if (size_ + count < capacity_)
-                {
-                    copy_backward(position, end(), end() + count);
-                    size_ += count;
-
-                    return position;
-                }
-                else
-                {
-                    auto start_idx = static_cast<size_type>(position - begin());
-                    auto end_idx = start_idx + count;
-                    auto new_size = size_ + count;
-
-                    // Auxiliary vector for easier swap.
-                    vector tmp{};
-                    tmp.resize_without_copy_(max(new_size, capacity_));
-                    tmp.size_ = new_size;
-
-                    // Copy before insertion index.
-                    copy(begin(), begin() + start_idx, tmp.begin());
-
-                    // Copy after insertion index.
-                    copy(begin() + start_idx, end(), tmp.begin() + end_idx);
-
-                    swap(tmp);
-
-                    // Position was invalidated!
-                    return begin() + start_idx;
-                }
-            }
-    };
-
-    template<class T, class Alloc>
-    bool operator==(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        if (lhs.size() != rhs.size())
-            return false;
-
-        for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i)
-        {
-            if (lhs[i] != rhs[i])
-                return false;
-        }
-
-        return true;
-    }
-
-    template<class T, class Alloc>
-    bool operator<(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        auto min_size = min(lhs.size(), rhs.size());
-        for (decltype(lhs.size()) i = 0; i < min_size; ++i)
-        {
-            if (lhs[i] >= rhs[i])
-                return false;
-        }
-
-        if (lhs.size() == rhs.size())
-            return true;
-        else
-            return lhs.size() < rhs.size();
-    }
-
-    template<class T, class Alloc>
-    bool operator!=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        return !(lhs == rhs);
-    }
-
-    template<class T, class Alloc>
-    bool operator>(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        return rhs < lhs;
-    }
-
-    template<class T, class Alloc>
-    bool operator>=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        return !(lhs < rhs);
-    }
-
-    template<class T, class Alloc>
-    bool operator<=(const vector<T, Alloc>& lhs, const vector<T, Alloc>& rhs)
-    {
-        return !(rhs < lhs);
-    }
-
-    /**
-     * 23.3.6.6, specialized algorithms:
-     */
-    template<class T, class Alloc>
-    void swap(vector<T, Alloc>& lhs, vector<T, Alloc>& rhs)
-        noexcept(noexcept(lhs.swap(rhs)))
-    {
-        lhs.swap(rhs);
-    }
-
-    /**
-     * 23.3.7, class vector<bool>:
-     */
-
-    // TODO: implement
-}
-
-#endif
Index: uspace/lib/cpp/include/initializer_list
===================================================================
--- uspace/lib/cpp/include/initializer_list	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/initializer_list	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/initializer_list.hpp>
+#include <__bits/adt/initializer_list.hpp>
Index: uspace/lib/cpp/include/iomanip
===================================================================
--- uspace/lib/cpp/include/iomanip	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/iomanip	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/iomanip.hpp>
+#include <__bits/io/iomanip.hpp>
Index: uspace/lib/cpp/include/ios
===================================================================
--- uspace/lib/cpp/include/ios	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/ios	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/ios.hpp>
+#include <__bits/io/ios.hpp>
Index: uspace/lib/cpp/include/iosfwd
===================================================================
--- uspace/lib/cpp/include/iosfwd	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/iosfwd	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/iosfwd.hpp>
+#include <__bits/io/iosfwd.hpp>
Index: uspace/lib/cpp/include/iostream
===================================================================
--- uspace/lib/cpp/include/iostream	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/iostream	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/iostream.hpp>
+#include <__bits/io/iostream.hpp>
Index: uspace/lib/cpp/include/istream
===================================================================
--- uspace/lib/cpp/include/istream	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/istream	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/istream.hpp>
+#include <__bits/io/istream.hpp>
Index: uspace/lib/cpp/include/iterator
===================================================================
--- uspace/lib/cpp/include/iterator	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/iterator	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/iterator.hpp>
+#include <__bits/iterator.hpp>
Index: uspace/lib/cpp/include/limits
===================================================================
--- uspace/lib/cpp/include/limits	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/limits	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/limits.hpp>
+#include <__bits/limits.hpp>
Index: uspace/lib/cpp/include/list
===================================================================
--- uspace/lib/cpp/include/list	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/list	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/list.hpp>
+#include <__bits/adt/list.hpp>
Index: uspace/lib/cpp/include/locale
===================================================================
--- uspace/lib/cpp/include/locale	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/locale	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,9 @@
  */
 
-#include <impl/locale.hpp>
+#include <__bits/locale/codecvt.hpp>
+#include <__bits/locale/ctype.hpp>
+#include <__bits/locale/locale.hpp>
+#include <__bits/locale/locale_misc.hpp>
+#include <__bits/locale/num_get.hpp>
+#include <__bits/locale/num_put.hpp>
+#include <__bits/locale/numpunct.hpp>
Index: uspace/lib/cpp/include/map
===================================================================
--- uspace/lib/cpp/include/map	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/map	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/map.hpp>
+#include <__bits/adt/map.hpp>
Index: uspace/lib/cpp/include/mutex
===================================================================
--- uspace/lib/cpp/include/mutex	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/mutex	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/mutex.hpp>
+#include <__bits/thread/mutex.hpp>
Index: uspace/lib/cpp/include/new
===================================================================
--- uspace/lib/cpp/include/new	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/new	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/new.hpp>
+#include <__bits/new.hpp>
Index: uspace/lib/cpp/include/numeric
===================================================================
--- uspace/lib/cpp/include/numeric	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/numeric	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/numeric.hpp>
+#include <__bits/numeric.hpp>
Index: uspace/lib/cpp/include/ostream
===================================================================
--- uspace/lib/cpp/include/ostream	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/ostream	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/ostream.hpp>
+#include <__bits/io/ostream.hpp>
Index: uspace/lib/cpp/include/queue
===================================================================
--- uspace/lib/cpp/include/queue	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/queue	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/queue.hpp>
+#include <__bits/adt/queue.hpp>
Index: uspace/lib/cpp/include/random
===================================================================
--- uspace/lib/cpp/include/random	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/random	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/random.hpp>
+#include <__bits/random.hpp>
Index: uspace/lib/cpp/include/ratio
===================================================================
--- uspace/lib/cpp/include/ratio	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/ratio	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/ratio.hpp>
+#include <__bits/ratio.hpp>
Index: uspace/lib/cpp/include/regex
===================================================================
--- uspace/lib/cpp/include/regex	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/regex	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/regex.hpp>
+#include <__bits/regex.hpp>
Index: uspace/lib/cpp/include/scoped_allocator
===================================================================
--- uspace/lib/cpp/include/scoped_allocator	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/scoped_allocator	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/scoped_allocator.hpp>
+#include <__bits/scoped_allocator.hpp>
Index: uspace/lib/cpp/include/set
===================================================================
--- uspace/lib/cpp/include/set	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/set	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/set.hpp>
+#include <__bits/adt/set.hpp>
Index: uspace/lib/cpp/include/shared_mutex
===================================================================
--- uspace/lib/cpp/include/shared_mutex	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/shared_mutex	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/shared_mutex.hpp>
+#include <__bits/thread/shared_mutex.hpp>
Index: uspace/lib/cpp/include/sstream
===================================================================
--- uspace/lib/cpp/include/sstream	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/sstream	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/sstream.hpp>
+#include <__bits/io/sstream.hpp>
Index: uspace/lib/cpp/include/stack
===================================================================
--- uspace/lib/cpp/include/stack	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/stack	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/stack.hpp>
+#include <__bits/adt/stack.hpp>
Index: uspace/lib/cpp/include/stdexcept
===================================================================
--- uspace/lib/cpp/include/stdexcept	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/stdexcept	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/stdexcept.hpp>
+#include <__bits/stdexcept.hpp>
Index: uspace/lib/cpp/include/streambuf
===================================================================
--- uspace/lib/cpp/include/streambuf	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/streambuf	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/streambuf.hpp>
+#include <__bits/io/streambuf.hpp>
Index: uspace/lib/cpp/include/string
===================================================================
--- uspace/lib/cpp/include/string	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/string	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,4 @@
  */
 
-#include <impl/string.hpp>
-#include <__bits/string_io.hpp>
+#include <__bits/string/string.hpp>
+#include <__bits/string/string_io.hpp>
Index: uspace/lib/cpp/include/system_error
===================================================================
--- uspace/lib/cpp/include/system_error	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/system_error	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/system_error.hpp>
+#include <__bits/system_error.hpp>
Index: uspace/lib/cpp/include/thread
===================================================================
--- uspace/lib/cpp/include/thread	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/thread	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/thread.hpp>
+#include <__bits/thread/thread.hpp>
Index: uspace/lib/cpp/include/tuple
===================================================================
--- uspace/lib/cpp/include/tuple	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/tuple	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/tuple.hpp>
+#include <__bits/tuple/tuple.hpp>
Index: uspace/lib/cpp/include/type_traits
===================================================================
--- uspace/lib/cpp/include/type_traits	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/type_traits	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,5 +27,5 @@
  */
 
-#include <impl/type_traits.hpp>
 #include <__bits/type_traits/references.hpp>
 #include <__bits/type_traits/result_of.hpp>
+#include <__bits/type_traits/type_traits.hpp>
Index: uspace/lib/cpp/include/typeindex
===================================================================
--- uspace/lib/cpp/include/typeindex	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/typeindex	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/typeindex.hpp>
+#include <__bits/typeindex.hpp>
Index: uspace/lib/cpp/include/typeinfo
===================================================================
--- uspace/lib/cpp/include/typeinfo	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/typeinfo	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/typeinfo.hpp>
+#include <__bits/typeinfo.hpp>
Index: uspace/lib/cpp/include/unordered_map
===================================================================
--- uspace/lib/cpp/include/unordered_map	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/unordered_map	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/unordered_map.hpp>
+#include <__bits/adt/unordered_map.hpp>
Index: uspace/lib/cpp/include/unordered_set
===================================================================
--- uspace/lib/cpp/include/unordered_set	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/unordered_set	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/unordered_set.hpp>
+#include <__bits/adt/unordered_set.hpp>
Index: uspace/lib/cpp/include/utility
===================================================================
--- uspace/lib/cpp/include/utility	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/utility	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,5 +27,5 @@
  */
 
-#include <impl/utility.hpp>
 #include <__bits/utility/declval.hpp>
 #include <__bits/utility/forward_move.hpp>
+#include <__bits/utility/utility.hpp>
Index: uspace/lib/cpp/include/valarray
===================================================================
--- uspace/lib/cpp/include/valarray	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/valarray	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,3 +27,3 @@
  */
 
-#include <impl/valarray.hpp>
+#include <__bits/adt/valarray.hpp>
Index: uspace/lib/cpp/include/vector
===================================================================
--- uspace/lib/cpp/include/vector	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/include/vector	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,3 +27,3 @@
  */
 
-#include <impl/vector.hpp>
+#include <__bits/adt/vector.hpp>
Index: uspace/lib/cpp/src/__bits/runtime.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/runtime.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/runtime.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/abi.hpp>
 #include <cstdlib>
 #include <cstdint>
-#include <__bits/abi.hpp>
 #include <exception>
 #include <mutex>
Index: uspace/lib/cpp/src/__bits/test/adaptors.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/adaptors.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/adaptors.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,9 +27,9 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <cstdlib>
 #include <deque>
 #include <functional>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <iterator>
 #include <queue>
Index: uspace/lib/cpp/src/__bits/test/array.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/array.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/array.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,8 +27,8 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <algorithm>
 #include <array>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 
 namespace std::test
Index: uspace/lib/cpp/src/__bits/test/bitset.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/bitset.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/bitset.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <bitset>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <sstream>
 #include <string>
Index: uspace/lib/cpp/src/__bits/test/deque.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/deque.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/deque.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <deque>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <utility>
 
Index: uspace/lib/cpp/src/__bits/test/map.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/map.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/map.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,6 +27,6 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <map>
 #include <string>
Index: uspace/lib/cpp/src/__bits/test/memory.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/memory.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/memory.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
-#include <initializer_list>
 #include <__bits/test/mock.hpp>
 #include <__bits/test/tests.hpp>
+#include <initializer_list>
 #include <memory>
 #include <type_traits>
Index: uspace/lib/cpp/src/__bits/test/numeric.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/numeric.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/numeric.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,8 +27,8 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <array>
 #include <complex>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <numeric>
 #include <utility>
Index: uspace/lib/cpp/src/__bits/test/set.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/set.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/set.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,6 +27,6 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <set>
 #include <string>
Index: uspace/lib/cpp/src/__bits/test/string.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/string.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/string.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
-#include <string>
 #include <initializer_list>
 #include <__bits/test/tests.hpp>
+#include <string>
 #include <cstdio>
 
Index: uspace/lib/cpp/src/__bits/test/test.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/test.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/test.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,6 +27,6 @@
  */
 
+#include <__bits/test/test.hpp>
 #include <cstdio>
-#include <__bits/test/test.hpp>
 
 namespace std::test
Index: uspace/lib/cpp/src/__bits/test/tuple.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/tuple.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/tuple.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <functional>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <string>
 #include <tuple>
Index: uspace/lib/cpp/src/__bits/test/unordered_map.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/unordered_map.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/unordered_map.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,6 +27,6 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <unordered_map>
 #include <string>
Index: uspace/lib/cpp/src/__bits/test/unordered_set.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/unordered_set.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/unordered_set.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,6 +27,6 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <unordered_set>
 #include <string>
Index: uspace/lib/cpp/src/__bits/test/vector.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/test/vector.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/__bits/test/vector.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/test/tests.hpp>
 #include <algorithm>
 #include <initializer_list>
-#include <__bits/test/tests.hpp>
 #include <utility>
 #include <vector>
Index: uspace/lib/cpp/src/exception.cpp
===================================================================
--- uspace/lib/cpp/src/exception.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/exception.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
Index: uspace/lib/cpp/src/iomanip.cpp
===================================================================
--- uspace/lib/cpp/src/iomanip.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/iomanip.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -27,5 +27,5 @@
  */
 
-#include <__bits/iomanip.hpp>
+#include <__bits/io/iomanip_objs.hpp>
 #include <iomanip>
 
Index: uspace/lib/cpp/src/ios.cpp
===================================================================
--- uspace/lib/cpp/src/ios.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/ios.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
Index: uspace/lib/cpp/src/iostream.cpp
===================================================================
--- uspace/lib/cpp/src/iostream.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/iostream.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,7 +27,7 @@
  */
 
+#include <__bits/io/streambufs.hpp>
 #include <ios>
 #include <iostream>
-#include <__bits/streambufs.hpp>
 #include <new>
 
Index: uspace/lib/cpp/src/locale.cpp
===================================================================
--- uspace/lib/cpp/src/locale.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/locale.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -33,10 +33,10 @@
     locale::facet::facet(size_t refs)
     {
-        // TODO:
+        // TODO: implement
     }
 
     locale::facet::~facet()
     {
-        // TODO:
+        // TODO: implement
     }
 
Index: uspace/lib/cpp/src/new.cpp
===================================================================
--- uspace/lib/cpp/src/new.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/new.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
Index: uspace/lib/cpp/src/string.cpp
===================================================================
--- uspace/lib/cpp/src/string.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/string.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
Index: uspace/lib/cpp/src/thread.cpp
===================================================================
--- uspace/lib/cpp/src/thread.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/thread.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -31,6 +31,4 @@
 #include <thread>
 #include <utility>
-
-#include <iostream>
 
 namespace std
Index: uspace/lib/cpp/src/typeindex.cpp
===================================================================
--- uspace/lib/cpp/src/typeindex.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/typeindex.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
Index: uspace/lib/cpp/src/typeinfo.cpp
===================================================================
--- uspace/lib/cpp/src/typeinfo.cpp	(revision 8a8a9273c13177ca6277765605879db5859330b5)
+++ uspace/lib/cpp/src/typeinfo.cpp	(revision b57a3eeb719e9e5b79cc78424c1aa35aaecdb4d0)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2018 Jaroslav Jindrak
  * All rights reserved.
  *
