Index: uspace/lib/cpp/include/functional
===================================================================
--- uspace/lib/cpp/include/functional	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/functional	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -28,2 +28,6 @@
 
 #include <impl/functional.hpp>
+#include <internal/functional/bind.hpp>
+#include <internal/functional/function.hpp>
+#include <internal/functional/invoke.hpp>
+#include <internal/functional/reference_wrapper.hpp>
Index: uspace/lib/cpp/include/impl/functional.hpp
===================================================================
--- uspace/lib/cpp/include/impl/functional.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/impl/functional.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -30,7 +30,7 @@
 #define LIBCPP_FUNCTIONAL
 
+#include <internal/functional/invoke.hpp>
 #include <limits>
 #include <memory>
-#include <typeinfo>
 #include <type_traits>
 #include <utility>
@@ -38,52 +38,4 @@
 namespace std
 {
-    namespace aux
-    {
-        /**
-         * 20.9.2, requirements:
-         */
-        template<class R, class T, class T1, class... Ts>
-        decltype(auto) invoke(R T::* f, T1&& t1, Ts&&... args)
-        {
-            if constexpr (is_member_function_pointer_v<decltype(f)>)
-            {
-                if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
-                    // (1.1)
-                    return (t1.*f)(forward<Ts>(args)...);
-                else
-                    // (1.2)
-                    return ((*t1).*f)(forward<Ts>(args)...);
-            }
-            else if constexpr (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
-            {
-                /**
-                 * Note: Standard requires to N be equal to 1, but we take t1 directly
-                 *       so we need sizeof...(args) to be 0.
-                 */
-                if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
-                    // (1.3)
-                    return t1.*f;
-                else
-                    // (1.4)
-                    return (*t1).*f;
-            }
-
-            /**
-             * Note: If this condition holds this will not be reachable,
-             *       but a new addition to the standard (17.7 point (8.1))
-             *       prohibits us from simply using false as the condition here,
-             *       so we use this because we know it is false here.
-             */
-            static_assert(is_member_function_pointer_v<decltype(f)>, "invalid invoke");
-        }
-
-        template<class F, class... Args>
-        decltype(auto) invoke(F&& f, Args&&... args)
-        {
-            // (1.5)
-            return f(forward<Args>(args)...);
-        }
-    }
-
     /**
      * 20.9.3, invoke:
@@ -91,85 +43,7 @@
 
     template<class F, class... Args>
-    result_of_t<F&&(Args&&...)> invoke(F&& f, Args&&... args)
+    decltype(auto) invoke(F&& f, Args&&... args)
     {
         return aux::invoke(forward<F>(f)(forward<Args>(args)...));
-    }
-
-    /**
-     * 20.9.4, reference_wrapper:
-     */
-
-    template<class T>
-    class reference_wrapper
-    {
-        public:
-            using type = T;
-            // TODO: conditional typedefs
-
-            reference_wrapper(type& val) noexcept
-                : data_{&val}
-            { /* DUMMY BODY */ }
-
-            reference_wrapper(type&&) = delete;
-
-            reference_wrapper(const reference_wrapper& other) noexcept
-                : data_{other.data_}
-            { /* DUMMY BODY */ }
-
-            reference_wrapper& operator=(const reference_wrapper& other) noexcept
-            {
-                data_ = other.data_;
-
-                return *this;
-            }
-
-            operator type&() const noexcept
-            {
-                return *data_;
-            }
-
-            type& get() const noexcept
-            {
-                return *data_;
-            }
-
-            template<class... Args>
-            result_of_t<type&(Args&&...)> operator()(Args&&... args) const
-            {
-                return invoke(*data_, std::forward<Args>(args)...);
-            }
-
-        private:
-            type* data_;
-    };
-
-    template<class T>
-    reference_wrapper<T> ref(T& t) noexcept
-    {
-        return reference_wrapper<T>{t};
-    }
-
-    template<class T>
-    reference_wrapper<const T> cref(const T& t) noexcept
-    {
-        return reference_wrapper<const T>{t};
-    }
-
-    template<class T>
-    void ref(const T&&) = delete;
-
-    template<class T>
-    void cref(const T&&) = delete;
-
-    template<class T>
-    reference_wrapper<T> ref(reference_wrapper<T> t) noexcept
-    {
-        return ref(t.get());
-    }
-
-    template<class T>
-    reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept
-    {
-        return cref(t.get());
     }
 
@@ -756,539 +630,4 @@
     template<class Predicate>
     constexpr binary_negate<Predicate> not2(const Predicate& pred);
-
-    /**
-     * 20.9.12, polymorphic function adaptors:
-     */
-
-    namespace aux
-    {
-        // TODO: fix this
-        /* template<class, class T, class... Args> */
-        /* struct is_callable_impl: false_type */
-        /* { /1* DUMMY BODY *1/ }; */
-
-        /* template<class, class R, class... Args> */
-        /* struct is_callable_impl< */
-        /*     void_t<decltype(aux::invoke(declval<R(Args...)>(), declval<Args>()..., R))>, */
-        /*     R, Args... */
-        /* > : true_type */
-        /* { /1* DUMMY BODY *1/ }; */
-
-        /* template<class T> */
-        /* struct is_callable: is_callable_impl<void_t<>, T> */
-        /* { /1* DUMMY BODY *1/ }; */
-
-        template<class Callable, class R, class... Args>
-        R invoke_callable(Callable* clbl, Args&&... args)
-        {
-            return (*clbl)(forward<Args>(args)...);
-        }
-
-        template<class Callable>
-        void copy_callable(Callable* to, Callable* from)
-        {
-            new(to) Callable{*from};
-        }
-
-        template<class Callable>
-        void destroy_callable(Callable* clbl)
-        {
-            if (clbl)
-                clbl->~Callable();
-        }
-    }
-
-    // TODO: implement
-    class bad_function_call;
-
-    template<class>
-    class function; // undefined
-
-    /**
-     * Note: Ideally, this implementation wouldn't
-     *       copy the target if it was a pointer to
-     *       a function, but for the simplicity of the
-     *       implementation, we do copy even in that
-     *       case for now. It would be a nice optimization
-     *       if this was changed in the future.
-     */
-    template<class R, class... Args>
-    class function<R(Args...)>
-    {
-        public:
-            using result_type = R;
-            // TODO: conditional typedefs
-
-            /**
-             * 20.9.12.2.1, construct/copy/destroy:
-             */
-
-            function() noexcept
-                : callable_{}, callable_size_{}, call_{},
-                  copy_{}, dest_{}
-            { /* DUMMY BODY */ }
-
-            function(nullptr_t) noexcept
-                : function{}
-            { /* DUMMY BODY */ }
-
-            function(const function& other)
-                : callable_{}, callable_size_{other.callable_size_},
-                  call_{other.call_}, copy_{other.copy_}, dest_{other.dest_}
-            {
-                callable_ = new uint8_t[callable_size_];
-                (*copy_)(callable_, other.callable_);
-            }
-
-            function(function&& other)
-                : callable_{other.callable_}, callable_size_{other.callable_size_},
-                  call_{other.call_}, copy_{other.copy_}, dest_{other.dest_}
-            {
-                other.callable_ = nullptr;
-                other.callable_size_ = size_t{};
-                other.call_ = nullptr;
-                other.copy_ = nullptr;
-                other.dest_ = nullptr;
-            }
-
-            // TODO: shall not participate in overloading unless aux::is_callable<F>
-            template<class F>
-            function(F f)
-                : callable_{}, callable_size_{sizeof(F)},
-                  call_{(call_t)aux::invoke_callable<F, R, Args...>},
-                  copy_{(copy_t)aux::copy_callable<F>},
-                  dest_{(dest_t)aux::destroy_callable<F>}
-            {
-                callable_ = new uint8_t[callable_size_];
-                (*copy_)(callable_, (uint8_t*)&f);
-            }
-
-            /**
-             * Note: For the moment we're ignoring the allocator
-             *       for simplicity of the implementation.
-             */
-
-            template<class A>
-            function(allocator_arg_t, const A& a) noexcept
-                : function{}
-            { /* DUMMY BODY */ }
-
-            template<class A>
-            function(allocator_arg_t, const A& a, nullptr_t) noexcept
-                : function{}
-            { /* DUMMY BODY */ }
-
-            template<class A>
-            function(allocator_arg_t, const A& a, const function& other)
-                : function{other}
-            { /* DUMMY BODY */ }
-
-            template<class A>
-            function(allocator_arg_t, const A& a, function&& other)
-                : function{move(other)}
-            { /* DUMMY BODY */ }
-
-            // TODO: shall not participate in overloading unless aux::is_callable<F>
-            template<class F, class A>
-            function(allocator_arg_t, const A& a, F f)
-                : function{f}
-            { /* DUMMY BODY */ }
-
-            function& operator=(const function& rhs)
-            {
-                function{rhs}.swap(*this);
-
-                return *this;
-            }
-
-            /**
-             * Note: We have to copy call_, copy_
-             *       and dest_ because they can be templated
-             *       by a type F we don't know.
-             */
-            function& operator=(function&& rhs)
-            {
-                clear_();
-
-                callable_ = rhs.callable_;
-                callable_size_ = rhs.callable_size_;
-                call_ = rhs.call_;
-                copy_ = rhs.copy_;
-                dest_ = rhs.dest_;
-
-                rhs.callable_ = nullptr;
-                rhs.callable_size_ = size_t{};
-                rhs.call_ = nullptr;
-                rhs.copy_ = nullptr;
-                rhs.dest_ = nullptr;
-
-                return *this;
-            }
-
-            function& operator=(nullptr_t) noexcept
-            {
-                clear_();
-
-                return *this;
-            }
-
-            // TODO: shall not participate in overloading unless aux::is_callable<F>
-            template<class F>
-            function& operator=(F&& f)
-            {
-                callable_size_ = sizeof(F);
-                callable_ = new uint8_t[callable_size_];
-                call_ = aux::invoke_callable<F, R, Args...>;
-                copy_ = aux::copy_callable<F>;
-                dest_ = aux::destroy_callable<F>;
-
-                (*copy_)(callable_, (uint8_t*)&f);
-            }
-
-            template<class F>
-            function& operator=(reference_wrapper<F> ref) noexcept
-            {
-                return (*this) = ref.get();
-            }
-
-            ~function()
-            {
-                if (callable_)
-                {
-                    (*dest_)(callable_);
-                    delete[] callable_;
-                }
-            }
-
-            /**
-             * 20.9.12.2.2, function modifiers:
-             */
-
-            void swap(function& other) noexcept
-            {
-                std::swap(callable_, other.callable_);
-                std::swap(callable_size_, other.callable_size_);
-                std::swap(call_, other.call_);
-                std::swap(copy_, other.copy_);
-                std::swap(dest_, other.dest_);
-            }
-
-            template<class F, class A>
-            void assign(F&& f, const A& a)
-            {
-                function{allocator_arg, a, forward<F>(f)}.swap(*this);
-            }
-
-            /**
-             * 20.9.12.2.3, function capacity:
-             */
-
-            explicit operator bool() const noexcept
-            {
-                return callable_ != nullptr;
-            }
-
-            /**
-             * 20.9.12.2.4, function invocation:
-             */
-
-            result_type operator()(Args... args) const
-            {
-                // TODO: throw bad_function_call if !callable_ || !call_
-                if constexpr (is_same_v<R, void>)
-                    (*call_)(callable_, forward<Args>(args)...);
-                else
-                    return (*call_)(callable_, forward<Args>(args)...);
-            }
-
-            /**
-             * 20.9.12.2.5, function target access:
-             */
-
-            const type_info& target_type() const noexcept
-            {
-                return typeid(*callable_);
-            }
-
-            template<class T>
-            T* target() noexcept
-            {
-                if (target_type() == typeid(T))
-                    return (T*)callable_;
-                else
-                    return nullptr;
-            }
-
-            template<class T>
-            const T* target() const noexcept
-            {
-                if (target_type() == typeid(T))
-                    return (T*)callable_;
-                else
-                    return nullptr;
-            }
-
-        private:
-            using call_t = R(*)(uint8_t*, Args&&...);
-            using copy_t = void (*)(uint8_t*, uint8_t*);
-            using dest_t = void (*)(uint8_t*);
-
-            uint8_t* callable_;
-            size_t callable_size_;
-            call_t call_;
-            copy_t copy_;
-            dest_t dest_;
-
-            void clear_()
-            {
-                if (callable_)
-                {
-                    (*dest_)(callable_);
-                    delete[] callable_;
-                    callable_ = nullptr;
-                }
-            }
-    };
-
-    /**
-     * 20.9.12.2.6, null pointer comparisons:
-     */
-
-    template<class R, class... Args>
-    bool operator==(const function<R(Args...)>& f, nullptr_t) noexcept
-    {
-        return !f;
-    }
-
-    template<class R, class... Args>
-    bool operator==(nullptr_t, const function<R(Args...)>& f) noexcept
-    {
-        return !f;
-    }
-
-    template<class R, class... Args>
-    bool operator!=(const function<R(Args...)>& f, nullptr_t) noexcept
-    {
-        return (bool)f;
-    }
-
-    template<class R, class... Args>
-    bool operator!=(nullptr_t, const function<R(Args...)>& f) noexcept
-    {
-        return (bool)f;
-    }
-
-    /**
-     * 20.9.12.2.7, specialized algorithms:
-     */
-
-    template<class R, class... Args>
-    void swap(function<R(Args...)>& f1, function<R(Args...)>& f2)
-    {
-        f1.swap(f2);
-    }
-
-    template<class R, class... Args, class Alloc>
-    struct uses_allocator<function<R(Args...)>, Alloc>
-        : true_type
-    { /* DUMMY BODY */ };
-
-    /**
-     * 20.9.10, bind:
-     */
-
-    namespace aux
-    {
-        template<int N>
-        struct placeholder_t
-        {
-            constexpr placeholder_t() = default;
-            constexpr placeholder_t(const placeholder_t&) = default;
-            constexpr placeholder_t(placeholder_t&&) = default;
-        };
-    }
-
-    template<class T>
-    struct is_placeholder: integral_constant<int, 0>
-    { /* DUMMY BODY */ };
-
-    template<int N> // Note: const because they are all constexpr.
-    struct is_placeholder<const aux::placeholder_t<N>>
-        : integral_constant<int, N>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    inline constexpr int is_placeholder_v = is_placeholder<T>::value;
-
-    namespace aux
-    {
-        /**
-         * Note: Our internal bind return type has an extra type
-         *       template parameter and an extra bool template parameter.
-         *       We use this for the special version of bind that has
-         *       the return type to have a result_type typedef
-         *       (i.e. when the bool is true, the extra type parameter
-         *       is typedefed as result_type - see the structure below).
-         *       This is just a simplification of the implementation
-         *       so that we don't need to have two return types for
-         *       the two bind functions, because unlike function or
-         *       mem_fn, we know exactly when to make the typedef.
-         */
-
-        template<class, bool = false>
-        struct bind_conditional_result_type
-        { /* DUMMY BODY */ };
-
-        template<class R>
-        struct bind_conditional_result_type<R, true>
-        {
-            using result_type = R;
-        };
-
-        template<class, bool, class, class...>
-        class bind_t;
-
-        /**
-         * Filter class that uses its overloaded operator[]
-         * to filter our placeholders, reference_wrappers and bind
-         * subexpressions and replace them with the correct
-         * arguments (extracts references, calls the subexpressions etc).
-         */
-        template<class... Args>
-        class bind_arg_filter
-        {
-            public:
-                bind_arg_filter(Args&&... args)
-                    : args_{forward<Args>(args)...}
-                { /* DUMMY BODY */ }
-
-                template<class T>
-                constexpr decltype(auto) operator[](T&& t)
-                {
-                    return forward<T>(t);
-                }
-
-                template<int N>
-                constexpr decltype(auto) operator[](const placeholder_t<N>)
-                { // Since placeholders are constexpr, this is the best match for them.
-                    /**
-                     * Come on, it's int! Why not use -1 as not placeholder
-                     * and start them at 0? -.-
-                     */
-                    return get<N - 1>(args_);
-                }
-
-                template<class T>
-                constexpr T& operator[](reference_wrapper<T> ref)
-                {
-                    return ref.get();
-                }
-
-                template<class R, bool B, class F, class... BindArgs>
-                constexpr decltype(auto) operator[](const bind_t<R, B, F, BindArgs...> b)
-                {
-                    return b; // TODO: bind subexpressions
-                }
-
-
-            private:
-                tuple<Args...> args_;
-        };
-
-        template<class R, bool HasResultType, class F, class... Args>
-        class bind_t: public bind_conditional_result_type<R, HasResultType>
-        {
-            public:
-                template<class G, class... BoundArgs>
-                constexpr bind_t(G&& g, BoundArgs&&... args)
-                    : func_{forward<F>(g)},
-                      bound_args_{forward<Args>(args)...}
-                { /* DUMMY BODY */ }
-
-                constexpr bind_t(const bind_t& other) = default;
-                constexpr bind_t(bind_t&& other) = default;
-
-                template<class... ActualArgs>
-                constexpr decltype(auto) operator()(ActualArgs&&... args)
-                {
-                    return invoke_(
-                        make_index_sequence<sizeof...(Args)>{},
-                        forward<ActualArgs>(args)...
-                    );
-                }
-
-            private:
-                function<decay_t<F>> func_;
-                tuple<decay_t<Args>...> bound_args_;
-
-                template<size_t... Is, class... ActualArgs>
-                constexpr decltype(auto) invoke_(
-                    index_sequence<Is...>, ActualArgs&&... args
-                )
-                {
-                    /**
-                     * The expression filter[bound_args_[bind_arg_index<Is>()]]...
-                     * here expands bind_arg_index to 0, 1, ... sizeof...(ActualArgs) - 1
-                     * and then passes this variadic list of indices to the bound_args_
-                     * tuple which extracts the bound args from it.
-                     * Our filter will then have its operator[] called on each of them
-                     * and filter out the placeholders, reference_wrappers etc and changes
-                     * them to the actual arguments.
-                     */
-                    bind_arg_filter<ActualArgs...> filter{forward<ActualArgs>(args)...};
-
-                    return invoke(
-                        func_,
-                        filter[get<Is>(bound_args_)]...
-                    );
-                }
-        };
-    }
-
-    template<class T>
-    struct is_bind_expression: false_type
-    { /* DUMMY BODY */ };
-
-    template<class R, bool B, class F, class... Args>
-    struct is_bind_expression<aux::bind_t<R, B, F, Args...>>
-        : true_type
-    { /* DUMMY BODY */ };
-
-    template<class F, class... Args>
-    aux::bind_t<void, false, F, Args...> bind(F&& f, Args&&... args)
-    {
-        return aux::bind_t<void, false, F, Args...>{forward<F>(f), forward<Args>(args)...};
-    }
-
-    template<class R, class F, class... Args>
-    aux::bind_t<R, true, F, Args...> bind(F&& f, Args&&... args)
-    {
-        return aux::bind_t<R, true, F, Args...>{forward<F>(f), forward<Args>(args)...};
-    }
-
-    namespace placeholders
-    {
-        /**
-         * Note: The number of placeholders is
-         *       implementation defined, we've chosen
-         *       8 because it is a nice number
-         *       and should be enough for any function
-         *       call.
-         * Note: According to the C++14 standard, these
-         *       are all extern non-const. We decided to use
-         *       the C++17 form of them being inline constexpr
-         *       because it is more convenient, makes sense
-         *       and would eventually need to be upgraded
-         *       anyway.
-         */
-        inline constexpr aux::placeholder_t<1> _1;
-        inline constexpr aux::placeholder_t<2> _2;
-        inline constexpr aux::placeholder_t<3> _3;
-        inline constexpr aux::placeholder_t<4> _4;
-        inline constexpr aux::placeholder_t<5> _5;
-        inline constexpr aux::placeholder_t<6> _6;
-        inline constexpr aux::placeholder_t<7> _7;
-        inline constexpr aux::placeholder_t<8> _8;
-    }
 
     /**
Index: uspace/lib/cpp/include/impl/tuple.hpp
===================================================================
--- uspace/lib/cpp/include/impl/tuple.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/impl/tuple.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -31,6 +31,6 @@
 
 #include <internal/aux.hpp>
-#include <internal/tuple_cat.hpp>
-#include <internal/tuple_ops.hpp>
+#include <internal/tuple/tuple_cat.hpp>
+#include <internal/tuple/tuple_ops.hpp>
 #include <internal/type_transformation.hpp>
 #include <functional>
Index: uspace/lib/cpp/include/impl/type_traits.hpp
===================================================================
--- uspace/lib/cpp/include/impl/type_traits.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/impl/type_traits.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -33,4 +33,5 @@
 #include <cstddef>
 #include <internal/aux.hpp>
+#include <internal/type_traits/references.hpp>
 
 namespace std
@@ -893,43 +894,4 @@
 
     /**
-     * 20.10.7.2, reference modifications:
-     */
-
-    template<class T>
-    struct remove_reference: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_reference<T&>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct remove_reference<T&&>: aux::type_is<T>
-    { /* DUMMY BODY */ };
-
-    // TODO: is this good?
-    template<class T>
-    struct add_lvalue_reference: aux::type_is<T&>
-    { /* DUMMY BODY */ };
-
-    // TODO: Special case when T is not referencable!
-    template<class T>
-    struct add_rvalue_reference: aux::type_is<T&&>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    struct add_rvalue_reference<T&>: aux::type_is<T&>
-    { /* DUMMY BODY */ };
-
-    template<class T>
-    using remove_reference_t = typename remove_reference<T>::type;
-
-    template<class T>
-    using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
-
-    template<class T>
-    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
-
-    /**
      * 20.10.7.3, sign modifications:
      */
@@ -1067,10 +1029,4 @@
     struct underlying_type;
 
-    template<class>
-    class result_of; // not defined
-
-    template<class F, class... ArgTypes>
-    class result_of<F(ArgTypes...)>;
-
     template<std::size_t Len, std::size_t Align = 0>
     using aligned_storage_t = typename aligned_storage<Len, Align>::type;
@@ -1087,7 +1043,4 @@
     template<class T>
     using underlying_type_t = typename underlying_type<T>::type;
-
-    template<class T>
-    using result_of_t = typename result_of<T>::type;
 }
 
Index: uspace/lib/cpp/include/impl/utility.hpp
===================================================================
--- uspace/lib/cpp/include/impl/utility.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/impl/utility.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -32,4 +32,5 @@
 #include <cstdint>
 #include <internal/type_transformation.hpp>
+#include <internal/utility/forward_move.hpp>
 #include <type_traits>
 
@@ -65,26 +66,4 @@
             return !(lhs < rhs);
         }
-    }
-
-    /**
-     * 20.2.4, forward/move helpers:
-     */
-
-    template<class T>
-    constexpr T&& forward(remove_reference_t<T>& t) noexcept
-    {
-        return static_cast<T&&>(t);
-    }
-
-    template<class T>
-    constexpr T&& forward(remove_reference_t<T>&& t) noexcept
-    {
-        return static_cast<T&&>(t);
-    }
-
-    template<class T>
-    constexpr remove_reference_t<T>&& move(T&& t) noexcept
-    {
-        return static_cast<remove_reference_t<T>&&>(t);
     }
 
@@ -124,13 +103,4 @@
         return old_val;
     }
-
-    /**
-     * 20.2.5, function template declval:
-     * Note: This function only needs declaration, not
-     *       implementation.
-     */
-
-    template<class T>
-    add_rvalue_reference_t<T> declval() noexcept;
 
     /**
Index: uspace/lib/cpp/include/internal/functional/bind.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/bind.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/functional/bind.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,240 @@
+/*
+ * 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_INTERNAL_FUNCTIONAL_BIND
+#define LIBCPP_INTERNAL_FUNCTIONAL_BIND
+
+#include <internal/functional/function.hpp>
+#include <internal/functional/invoke.hpp>
+#include <internal/functional/reference_wrapper.hpp>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+namespace std
+{
+    /**
+     * 20.9.10, bind:
+     */
+
+    namespace aux
+    {
+        template<int N>
+        struct placeholder_t
+        {
+            constexpr placeholder_t() = default;
+            constexpr placeholder_t(const placeholder_t&) = default;
+            constexpr placeholder_t(placeholder_t&&) = default;
+        };
+    }
+
+    template<class T>
+    struct is_placeholder: integral_constant<int, 0>
+    { /* DUMMY BODY */ };
+
+    template<int N> // Note: const because they are all constexpr.
+    struct is_placeholder<const aux::placeholder_t<N>>
+        : integral_constant<int, N>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    inline constexpr int is_placeholder_v = is_placeholder<T>::value;
+
+    namespace aux
+    {
+        /**
+         * Note: Our internal bind return type has an extra type
+         *       template parameter and an extra bool template parameter.
+         *       We use this for the special version of bind that has
+         *       the return type to have a result_type typedef
+         *       (i.e. when the bool is true, the extra type parameter
+         *       is typedefed as result_type - see the structure below).
+         *       This is just a simplification of the implementation
+         *       so that we don't need to have two return types for
+         *       the two bind functions, because unlike function or
+         *       mem_fn, we know exactly when to make the typedef.
+         */
+
+        template<class, bool = false>
+        struct bind_conditional_result_type
+        { /* DUMMY BODY */ };
+
+        template<class R>
+        struct bind_conditional_result_type<R, true>
+        {
+            using result_type = R;
+        };
+
+        template<class, bool, class, class...>
+        class bind_t;
+
+        /**
+         * Filter class that uses its overloaded operator[]
+         * to filter our placeholders, reference_wrappers and bind
+         * subexpressions and replace them with the correct
+         * arguments (extracts references, calls the subexpressions etc).
+         */
+        template<class... Args>
+        class bind_arg_filter
+        {
+            public:
+                bind_arg_filter(Args&&... args)
+                    : args_{forward<Args>(args)...}
+                { /* DUMMY BODY */ }
+
+                template<class T>
+                constexpr decltype(auto) operator[](T&& t)
+                {
+                    return forward<T>(t);
+                }
+
+                template<int N>
+                constexpr decltype(auto) operator[](const placeholder_t<N>)
+                { // Since placeholders are constexpr, this is the best match for them.
+                    /**
+                     * Come on, it's int! Why not use -1 as not placeholder
+                     * and start them at 0? -.-
+                     */
+                    return get<N - 1>(args_);
+                }
+
+                template<class T>
+                constexpr T& operator[](reference_wrapper<T> ref)
+                {
+                    return ref.get();
+                }
+
+                template<class R, bool B, class F, class... BindArgs>
+                constexpr decltype(auto) operator[](const bind_t<R, B, F, BindArgs...> b)
+                {
+                    return b; // TODO: bind subexpressions
+                }
+
+
+            private:
+                tuple<Args...> args_;
+        };
+
+        template<class R, bool HasResultType, class F, class... Args>
+        class bind_t: public bind_conditional_result_type<R, HasResultType>
+        {
+            public:
+                template<class G, class... BoundArgs>
+                constexpr bind_t(G&& g, BoundArgs&&... args)
+                    : func_{forward<F>(g)},
+                      bound_args_{forward<Args>(args)...}
+                { /* DUMMY BODY */ }
+
+                constexpr bind_t(const bind_t& other) = default;
+                constexpr bind_t(bind_t&& other) = default;
+
+                template<class... ActualArgs>
+                constexpr decltype(auto) operator()(ActualArgs&&... args)
+                {
+                    return invoke_(
+                        make_index_sequence<sizeof...(Args)>{},
+                        forward<ActualArgs>(args)...
+                    );
+                }
+
+            private:
+                function<decay_t<F>> func_;
+                tuple<decay_t<Args>...> bound_args_;
+
+                template<size_t... Is, class... ActualArgs>
+                constexpr decltype(auto) invoke_(
+                    index_sequence<Is...>, ActualArgs&&... args
+                )
+                {
+                    /**
+                     * The expression filter[bound_args_[bind_arg_index<Is>()]]...
+                     * here expands bind_arg_index to 0, 1, ... sizeof...(ActualArgs) - 1
+                     * and then passes this variadic list of indices to the bound_args_
+                     * tuple which extracts the bound args from it.
+                     * Our filter will then have its operator[] called on each of them
+                     * and filter out the placeholders, reference_wrappers etc and changes
+                     * them to the actual arguments.
+                     */
+                    bind_arg_filter<ActualArgs...> filter{forward<ActualArgs>(args)...};
+
+                    return invoke(
+                        func_,
+                        filter[get<Is>(bound_args_)]...
+                    );
+                }
+        };
+    }
+
+    template<class T>
+    struct is_bind_expression: false_type
+    { /* DUMMY BODY */ };
+
+    template<class R, bool B, class F, class... Args>
+    struct is_bind_expression<aux::bind_t<R, B, F, Args...>>
+        : true_type
+    { /* DUMMY BODY */ };
+
+    template<class F, class... Args>
+    aux::bind_t<void, false, F, Args...> bind(F&& f, Args&&... args)
+    {
+        return aux::bind_t<void, false, F, Args...>{forward<F>(f), forward<Args>(args)...};
+    }
+
+    template<class R, class F, class... Args>
+    aux::bind_t<R, true, F, Args...> bind(F&& f, Args&&... args)
+    {
+        return aux::bind_t<R, true, F, Args...>{forward<F>(f), forward<Args>(args)...};
+    }
+
+    namespace placeholders
+    {
+        /**
+         * Note: The number of placeholders is
+         *       implementation defined, we've chosen
+         *       8 because it is a nice number
+         *       and should be enough for any function
+         *       call.
+         * Note: According to the C++14 standard, these
+         *       are all extern non-const. We decided to use
+         *       the C++17 form of them being inline constexpr
+         *       because it is more convenient, makes sense
+         *       and would eventually need to be upgraded
+         *       anyway.
+         */
+        inline constexpr aux::placeholder_t<1> _1;
+        inline constexpr aux::placeholder_t<2> _2;
+        inline constexpr aux::placeholder_t<3> _3;
+        inline constexpr aux::placeholder_t<4> _4;
+        inline constexpr aux::placeholder_t<5> _5;
+        inline constexpr aux::placeholder_t<6> _6;
+        inline constexpr aux::placeholder_t<7> _7;
+        inline constexpr aux::placeholder_t<8> _8;
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/functional/function.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/function.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/functional/function.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,376 @@
+/*
+ * 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_INTERNAL_FUNCTIONAL_FUNCTION
+#define LIBCPP_INTERNAL_FUNCTIONAL_FUNCTION
+
+#include <internal/functional/reference_wrapper.hpp>
+#include <typeinfo>
+#include <type_traits>
+
+namespace std
+{
+    /**
+     * 20.9.12, polymorphic function adaptors:
+     */
+
+    namespace aux
+    {
+        // TODO: fix this
+        /* template<class, class T, class... Args> */
+        /* struct is_callable_impl: false_type */
+        /* { /1* DUMMY BODY *1/ }; */
+
+        /* template<class, class R, class... Args> */
+        /* struct is_callable_impl< */
+        /*     void_t<decltype(aux::invoke(declval<R(Args...)>(), declval<Args>()..., R))>, */
+        /*     R, Args... */
+        /* > : true_type */
+        /* { /1* DUMMY BODY *1/ }; */
+
+        /* template<class T> */
+        /* struct is_callable: is_callable_impl<void_t<>, T> */
+        /* { /1* DUMMY BODY *1/ }; */
+
+        template<class Callable, class R, class... Args>
+        R invoke_callable(Callable* clbl, Args&&... args)
+        {
+            return (*clbl)(forward<Args>(args)...);
+        }
+
+        template<class Callable>
+        void copy_callable(Callable* to, Callable* from)
+        {
+            new(to) Callable{*from};
+        }
+
+        template<class Callable>
+        void destroy_callable(Callable* clbl)
+        {
+            if (clbl)
+                clbl->~Callable();
+        }
+    }
+
+    // TODO: implement
+    class bad_function_call;
+
+    template<class>
+    class function; // undefined
+
+    /**
+     * Note: Ideally, this implementation wouldn't
+     *       copy the target if it was a pointer to
+     *       a function, but for the simplicity of the
+     *       implementation, we do copy even in that
+     *       case for now. It would be a nice optimization
+     *       if this was changed in the future.
+     */
+    template<class R, class... Args>
+    class function<R(Args...)>
+    {
+        public:
+            using result_type = R;
+            // TODO: conditional typedefs
+
+            /**
+             * 20.9.12.2.1, construct/copy/destroy:
+             */
+
+            function() noexcept
+                : callable_{}, callable_size_{}, call_{},
+                  copy_{}, dest_{}
+            { /* DUMMY BODY */ }
+
+            function(nullptr_t) noexcept
+                : function{}
+            { /* DUMMY BODY */ }
+
+            function(const function& other)
+                : callable_{}, callable_size_{other.callable_size_},
+                  call_{other.call_}, copy_{other.copy_}, dest_{other.dest_}
+            {
+                callable_ = new uint8_t[callable_size_];
+                (*copy_)(callable_, other.callable_);
+            }
+
+            function(function&& other)
+                : callable_{other.callable_}, callable_size_{other.callable_size_},
+                  call_{other.call_}, copy_{other.copy_}, dest_{other.dest_}
+            {
+                other.callable_ = nullptr;
+                other.callable_size_ = size_t{};
+                other.call_ = nullptr;
+                other.copy_ = nullptr;
+                other.dest_ = nullptr;
+            }
+
+            // TODO: shall not participate in overloading unless aux::is_callable<F>
+            template<class F>
+            function(F f)
+                : callable_{}, callable_size_{sizeof(F)},
+                  call_{(call_t)aux::invoke_callable<F, R, Args...>},
+                  copy_{(copy_t)aux::copy_callable<F>},
+                  dest_{(dest_t)aux::destroy_callable<F>}
+            {
+                callable_ = new uint8_t[callable_size_];
+                (*copy_)(callable_, (uint8_t*)&f);
+            }
+
+            /**
+             * Note: For the moment we're ignoring the allocator
+             *       for simplicity of the implementation.
+             */
+
+            template<class A>
+            function(allocator_arg_t, const A& a) noexcept
+                : function{}
+            { /* DUMMY BODY */ }
+
+            template<class A>
+            function(allocator_arg_t, const A& a, nullptr_t) noexcept
+                : function{}
+            { /* DUMMY BODY */ }
+
+            template<class A>
+            function(allocator_arg_t, const A& a, const function& other)
+                : function{other}
+            { /* DUMMY BODY */ }
+
+            template<class A>
+            function(allocator_arg_t, const A& a, function&& other)
+                : function{move(other)}
+            { /* DUMMY BODY */ }
+
+            // TODO: shall not participate in overloading unless aux::is_callable<F>
+            template<class F, class A>
+            function(allocator_arg_t, const A& a, F f)
+                : function{f}
+            { /* DUMMY BODY */ }
+
+            function& operator=(const function& rhs)
+            {
+                function{rhs}.swap(*this);
+
+                return *this;
+            }
+
+            /**
+             * Note: We have to copy call_, copy_
+             *       and dest_ because they can be templated
+             *       by a type F we don't know.
+             */
+            function& operator=(function&& rhs)
+            {
+                clear_();
+
+                callable_ = rhs.callable_;
+                callable_size_ = rhs.callable_size_;
+                call_ = rhs.call_;
+                copy_ = rhs.copy_;
+                dest_ = rhs.dest_;
+
+                rhs.callable_ = nullptr;
+                rhs.callable_size_ = size_t{};
+                rhs.call_ = nullptr;
+                rhs.copy_ = nullptr;
+                rhs.dest_ = nullptr;
+
+                return *this;
+            }
+
+            function& operator=(nullptr_t) noexcept
+            {
+                clear_();
+
+                return *this;
+            }
+
+            // TODO: shall not participate in overloading unless aux::is_callable<F>
+            template<class F>
+            function& operator=(F&& f)
+            {
+                callable_size_ = sizeof(F);
+                callable_ = new uint8_t[callable_size_];
+                call_ = aux::invoke_callable<F, R, Args...>;
+                copy_ = aux::copy_callable<F>;
+                dest_ = aux::destroy_callable<F>;
+
+                (*copy_)(callable_, (uint8_t*)&f);
+            }
+
+            template<class F>
+            function& operator=(reference_wrapper<F> ref) noexcept
+            {
+                return (*this) = ref.get();
+            }
+
+            ~function()
+            {
+                if (callable_)
+                {
+                    (*dest_)(callable_);
+                    delete[] callable_;
+                }
+            }
+
+            /**
+             * 20.9.12.2.2, function modifiers:
+             */
+
+            void swap(function& other) noexcept
+            {
+                std::swap(callable_, other.callable_);
+                std::swap(callable_size_, other.callable_size_);
+                std::swap(call_, other.call_);
+                std::swap(copy_, other.copy_);
+                std::swap(dest_, other.dest_);
+            }
+
+            template<class F, class A>
+            void assign(F&& f, const A& a)
+            {
+                function{allocator_arg, a, forward<F>(f)}.swap(*this);
+            }
+
+            /**
+             * 20.9.12.2.3, function capacity:
+             */
+
+            explicit operator bool() const noexcept
+            {
+                return callable_ != nullptr;
+            }
+
+            /**
+             * 20.9.12.2.4, function invocation:
+             */
+
+            result_type operator()(Args... args) const
+            {
+                // TODO: throw bad_function_call if !callable_ || !call_
+                if constexpr (is_same_v<R, void>)
+                    (*call_)(callable_, forward<Args>(args)...);
+                else
+                    return (*call_)(callable_, forward<Args>(args)...);
+            }
+
+            /**
+             * 20.9.12.2.5, function target access:
+             */
+
+            const type_info& target_type() const noexcept
+            {
+                return typeid(*callable_);
+            }
+
+            template<class T>
+            T* target() noexcept
+            {
+                if (target_type() == typeid(T))
+                    return (T*)callable_;
+                else
+                    return nullptr;
+            }
+
+            template<class T>
+            const T* target() const noexcept
+            {
+                if (target_type() == typeid(T))
+                    return (T*)callable_;
+                else
+                    return nullptr;
+            }
+
+        private:
+            using call_t = R(*)(uint8_t*, Args&&...);
+            using copy_t = void (*)(uint8_t*, uint8_t*);
+            using dest_t = void (*)(uint8_t*);
+
+            uint8_t* callable_;
+            size_t callable_size_;
+            call_t call_;
+            copy_t copy_;
+            dest_t dest_;
+
+            void clear_()
+            {
+                if (callable_)
+                {
+                    (*dest_)(callable_);
+                    delete[] callable_;
+                    callable_ = nullptr;
+                }
+            }
+    };
+
+    /**
+     * 20.9.12.2.6, null pointer comparisons:
+     */
+
+    template<class R, class... Args>
+    bool operator==(const function<R(Args...)>& f, nullptr_t) noexcept
+    {
+        return !f;
+    }
+
+    template<class R, class... Args>
+    bool operator==(nullptr_t, const function<R(Args...)>& f) noexcept
+    {
+        return !f;
+    }
+
+    template<class R, class... Args>
+    bool operator!=(const function<R(Args...)>& f, nullptr_t) noexcept
+    {
+        return (bool)f;
+    }
+
+    template<class R, class... Args>
+    bool operator!=(nullptr_t, const function<R(Args...)>& f) noexcept
+    {
+        return (bool)f;
+    }
+
+    /**
+     * 20.9.12.2.7, specialized algorithms:
+     */
+
+    template<class R, class... Args>
+    void swap(function<R(Args...)>& f1, function<R(Args...)>& f2)
+    {
+        f1.swap(f2);
+    }
+
+    template<class R, class... Args, class Alloc>
+    struct uses_allocator<function<R(Args...)>, Alloc>
+        : true_type
+    { /* DUMMY BODY */ };
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/functional/invoke.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/invoke.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/functional/invoke.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,85 @@
+/*
+ * 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_INTERNAL_FUNCTIONAL_INVOKE
+#define LIBCPP_INTERNAL_FUNCTIONAL_INVOKE
+
+#include <internal/utility/declval.hpp>
+#include <internal/utility/forward_move.hpp>
+#include <type_traits>
+
+namespace std::aux
+{
+    /**
+     * 20.9.2, requirements:
+     */
+
+    template<class R, class T, class T1, class... Ts>
+    decltype(auto) invoke(R T::* f, T1&& t1, Ts&&... args)
+    {
+        if constexpr (is_member_function_pointer_v<decltype(f)>)
+        {
+            if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
+                // (1.1)
+                return (t1.*f)(forward<Ts>(args)...);
+            else
+                // (1.2)
+                return ((*t1).*f)(forward<Ts>(args)...);
+        }
+        else if constexpr (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
+        {
+            /**
+             * Note: Standard requires to N be equal to 1, but we take t1 directly
+             *       so we need sizeof...(args) to be 0.
+             */
+            if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
+                // (1.3)
+                return t1.*f;
+            else
+                // (1.4)
+                return (*t1).*f;
+        }
+
+        /**
+         * Note: If this condition holds this will not be reachable,
+         *       but a new addition to the standard (17.7 point (8.1))
+         *       prohibits us from simply using false as the condition here,
+         *       so we use this because we know it is false here.
+         */
+        static_assert(is_member_function_pointer_v<decltype(f)>, "invalid invoke");
+    }
+
+    template<class F, class... Args>
+    decltype(auto) invoke(F&& f, Args&&... args)
+    {
+        // (1.5)
+        return f(forward<Args>(args)...);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp
===================================================================
--- uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/functional/reference_wrapper.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,116 @@
+/*
+ * 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_INTERNAL_FUNCTIONAL_REFERENCE_WRAPPER
+#define LIBCPP_INTERNAL_FUNCTIONAL_REFERENCE_WRAPPER
+
+#include <internal/functional/invoke.hpp>
+#include <type_traits>
+
+namespace std
+{
+    /**
+     * 20.9.4, reference_wrapper:
+     */
+
+    template<class T>
+    class reference_wrapper
+    {
+        public:
+            using type = T;
+            // TODO: conditional typedefs
+
+            reference_wrapper(type& val) noexcept
+                : data_{&val}
+            { /* DUMMY BODY */ }
+
+            reference_wrapper(type&&) = delete;
+
+            reference_wrapper(const reference_wrapper& other) noexcept
+                : data_{other.data_}
+            { /* DUMMY BODY */ }
+
+            reference_wrapper& operator=(const reference_wrapper& other) noexcept
+            {
+                data_ = other.data_;
+
+                return *this;
+            }
+
+            operator type&() const noexcept
+            {
+                return *data_;
+            }
+
+            type& get() const noexcept
+            {
+                return *data_;
+            }
+
+            template<class... Args>
+            result_of_t<type&(Args&&...)> operator()(Args&&... args) const
+            {
+                return invoke(*data_, std::forward<Args>(args)...);
+            }
+
+        private:
+            type* data_;
+    };
+
+    template<class T>
+    reference_wrapper<T> ref(T& t) noexcept
+    {
+        return reference_wrapper<T>{t};
+    }
+
+    template<class T>
+    reference_wrapper<const T> cref(const T& t) noexcept
+    {
+        return reference_wrapper<const T>{t};
+    }
+
+    template<class T>
+    void ref(const T&&) = delete;
+
+    template<class T>
+    void cref(const T&&) = delete;
+
+    template<class T>
+    reference_wrapper<T> ref(reference_wrapper<T> t) noexcept
+    {
+        return ref(t.get());
+    }
+
+    template<class T>
+    reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept
+    {
+        return cref(t.get());
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/result_of.hpp
===================================================================
--- uspace/lib/cpp/include/internal/result_of.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/result_of.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,57 @@
+/*
+ * 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_INTERNAL_RESULT_OF
+#define LIBCPP_INTERNAL_RESULT_OF
+
+#include <internal/invoke.hpp>
+
+namespace std
+{
+    /**
+     * Note: This doesn't work, C++14 standard allows for F
+     *       to be any complete type, our implementation
+     *       currently works like the C++11 version where
+     *       F has to be callable.
+     * TODO: Fix this.
+     */
+
+    template<class>
+    struct result_of;
+
+    template<class F, class... Args>
+    class result_of<F(Args...)>: aux::type_is<
+        decltype(aux::invoke(declval<F>(), declval<ArgTypes>()...))
+    >
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using result_of_t = typename result_of<T>::type;
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/tuple/tuple_cat.hpp
===================================================================
--- uspace/lib/cpp/include/internal/tuple/tuple_cat.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/tuple/tuple_cat.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,172 @@
+/*
+ * 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_INTERNAL_TUPLE_TUPLE_CAT
+#define LIBCPP_INTERNAL_TUPLE_TUPLE_CAT
+
+#include <utility>
+
+namespace std
+{ // forward declarations
+    template<class... Ts>
+    struct tuple;
+
+    template<size_t I, class T>
+    struct tuple_element;
+
+    template<size_t I, class... Ts>
+    constexpr typename tuple_element<I, tuple<Ts...>>::type& get(tuple<Ts...>& tpl) noexcept;
+
+    template<class T, T...>
+    struct integer_sequence;
+
+    template<size_t... Is>
+    using index_sequence = integer_sequence<size_t, Is...>;
+}
+
+namespace std::aux
+{
+    template<class...>
+    struct tuple_append;
+
+    template<class... Ts, class... Us, class... Vs>
+    struct tuple_append<tuple<Ts...>, tuple<Us...>, Vs...>
+        : type_is<tuple<Ts..., Us...>>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using tuple_append_t = typename tuple_append<Ts...>::type;
+
+    template<class...>
+    struct remove_first_tuple;
+
+    template<class... Ts, class... Tuples>
+    struct remove_first_tuple<tuple<Ts...>, Tuples...>
+        : type_is<Tuples...>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using remove_first_tuple_t = typename remove_first_tuple<Ts...>::type;
+
+    template<class...>
+    struct get_first_tuple;
+
+    template<class... Ts, class... Tuples>
+    struct get_first_tuple<tuple<Ts...>, Tuples...>
+        : type_is<tuple<Ts...>>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using get_first_tuple_t = typename get_first_tuple<Ts...>::type;
+
+    template<class...>
+    struct tuple_cat_type_impl;
+
+    template<class... Ts, class... Tuples>
+    struct tuple_cat_type_impl<tuple<Ts...>, Tuples...>
+        : type_is<
+        typename tuple_cat_type_impl<
+            tuple_append_t<tuple<Ts...>, get_first_tuple_t<Tuples...>>,
+            remove_first_tuple_t<Tuples...>
+        >::type
+    >
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using tuple_cat_type_impl_t = typename tuple_cat_type_impl<Ts...>::type;
+
+    template<class...>
+    struct tuple_cat_type;
+
+    template<class... Ts, class... Tuples>
+    struct tuple_cat_type<tuple<Ts...>, Tuples...>
+        : type_is<tuple_cat_type_impl_t<tuple<Ts...>, Tuples...>>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using tuple_cat_type_t = typename tuple_cat_type<Ts...>::type;
+
+    template<class...>
+    struct concatenate_sequences;
+
+    template<size_t... Is1, size_t... Is2>
+    struct concatenate_sequences<index_sequence<Is1...>, index_sequence<Is2...>>
+        : type_is<index_sequence<Is1..., Is2...>>
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using concatenate_sequences_t = typename concatenate_sequences<Ts...>::type;
+
+    template<class...>
+    struct append_indices;
+
+    template<size_t... Is, class... Ts, class... Tuples>
+    struct append_indices<index_sequence<Is...>, tuple<Ts...>, Tuples...>
+        : append_indices<
+        concatenate_sequences_t<
+            index_sequence<Is...>, make_index_sequence<sizeof...(Ts)>
+        >,
+        Tuples...
+    >
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using append_indices_t = typename append_indices<Ts...>::types;
+
+    template<class...>
+    struct generate_indices;
+
+    template<class... Ts, class... Tuples>
+    struct generate_indices<tuple<Ts...>, Tuples...>
+        : type_is<
+        append_indices_t<
+            make_index_sequence<sizeof...(Ts)>,
+            Tuples...
+        >
+    >
+    { /* DUMMY BODY */ };
+
+    template<class... Ts>
+    using generate_indices_t = typename generate_indices<Ts...>::type;
+
+    template<class... Tuples, size_t... Is1, size_t... Is2>
+    tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls,
+                                          index_sequence<Is1...>,
+                                          index_sequence<Is2...>)
+    {
+        return tuple_cat_type_t<Tuples...>{
+            get<Is1...>(
+                get<Is2...>(
+                    forward<Tuples>(tpls)
+                )
+            )...
+        };
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp
===================================================================
--- uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,110 @@
+/*
+ * 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_INTERNAL_TUPLE_TUPLE_OPS
+#define LIBCPP_INTERNAL_TUPLE_TUPLE_OPS
+
+#include <utility>
+
+namespace std
+{ // forward declarations
+    template<class... Ts>
+    struct tuple;
+
+    template<size_t I, class T>
+    struct tuple_element;
+
+    template<size_t I, class... Ts>
+    constexpr typename tuple_element<I, tuple<Ts...>>::type& get(tuple<Ts...>& tpl) noexcept;
+}
+
+namespace std::aux
+{
+    template<size_t I, size_t N>
+    struct tuple_ops
+    {
+        template<class T, class U>
+        static void assign(T&& lhs, U&& rhs)
+        {
+            get<I>(forward<T>(lhs)) = get<I>(forward<U>(rhs));
+
+            tuple_ops<I + 1, N>::assign(forward<T>(lhs), forward<U>(rhs));
+        }
+
+        template<class T, class U>
+        static void swap(T& lhs, U& rhs)
+        {
+            std::swap(get<I>(lhs), get<I>(rhs));
+
+            tuple_ops<I + 1, N>::swap(lhs, rhs);
+        }
+
+        template<class T, class U>
+        static bool eq(const T& lhs, const U& rhs)
+        {
+            return (get<I>(lhs) == get<I>(rhs)) && tuple_ops<I + 1, N>::eq(lhs, rhs);
+        }
+
+        template<class T, class U>
+        static bool lt(const T& lhs, const U& rhs)
+        {
+            return (get<I>(lhs) < get<I>(rhs)) ||
+                (!(get<I>(rhs) < get<I>(lhs)) && tuple_ops<I + 1, N>::lt(lhs, rhs));
+        }
+    };
+
+    template<size_t N>
+    struct tuple_ops<N, N>
+    {
+        template<class T, class U>
+        static void assign(T&& lhs, U&& rhs)
+        {
+            get<N>(forward<T>(lhs)) = get<N>(forward<U>(rhs));
+        }
+
+        template<class T, class U>
+        static void swap(T& lhs, U& rhs)
+        {
+            std::swap(get<N>(lhs), get<N>(rhs));
+        }
+
+        template<class T, class U>
+        static bool eq(const T& lhs, const U& rhs)
+        {
+            return get<N>(lhs) == get<N>(rhs);
+        }
+
+        template<class T, class U>
+        static bool lt(const T& lhs, const U& rhs)
+        {
+            return get<N>(lhs) < get<N>(rhs);
+        }
+    };
+}
+
+#endif
Index: pace/lib/cpp/include/internal/tuple_cat.hpp
===================================================================
--- uspace/lib/cpp/include/internal/tuple_cat.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ 	(revision )
@@ -1,172 +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_CAT
-#define LIBCPP_TUPLE_CAT
-
-#include <utility>
-
-namespace std
-{ // forward declarations
-    template<class... Ts>
-    struct tuple;
-
-    template<size_t I, class T>
-    struct tuple_element;
-
-    template<size_t I, class... Ts>
-    constexpr typename tuple_element<I, tuple<Ts...>>::type& get(tuple<Ts...>& tpl) noexcept;
-
-    template<class T, T...>
-    struct integer_sequence;
-
-    template<size_t... Is>
-    using index_sequence = integer_sequence<size_t, Is...>;
-}
-
-namespace std::aux
-{
-    template<class...>
-    struct tuple_append;
-
-    template<class... Ts, class... Us, class... Vs>
-    struct tuple_append<tuple<Ts...>, tuple<Us...>, Vs...>
-        : type_is<tuple<Ts..., Us...>>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using tuple_append_t = typename tuple_append<Ts...>::type;
-
-    template<class...>
-    struct remove_first_tuple;
-
-    template<class... Ts, class... Tuples>
-    struct remove_first_tuple<tuple<Ts...>, Tuples...>
-        : type_is<Tuples...>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using remove_first_tuple_t = typename remove_first_tuple<Ts...>::type;
-
-    template<class...>
-    struct get_first_tuple;
-
-    template<class... Ts, class... Tuples>
-    struct get_first_tuple<tuple<Ts...>, Tuples...>
-        : type_is<tuple<Ts...>>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using get_first_tuple_t = typename get_first_tuple<Ts...>::type;
-
-    template<class...>
-    struct tuple_cat_type_impl;
-
-    template<class... Ts, class... Tuples>
-    struct tuple_cat_type_impl<tuple<Ts...>, Tuples...>
-        : type_is<
-        typename tuple_cat_type_impl<
-            tuple_append_t<tuple<Ts...>, get_first_tuple_t<Tuples...>>,
-            remove_first_tuple_t<Tuples...>
-        >::type
-    >
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using tuple_cat_type_impl_t = typename tuple_cat_type_impl<Ts...>::type;
-
-    template<class...>
-    struct tuple_cat_type;
-
-    template<class... Ts, class... Tuples>
-    struct tuple_cat_type<tuple<Ts...>, Tuples...>
-        : type_is<tuple_cat_type_impl_t<tuple<Ts...>, Tuples...>>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using tuple_cat_type_t = typename tuple_cat_type<Ts...>::type;
-
-    template<class...>
-    struct concatenate_sequences;
-
-    template<size_t... Is1, size_t... Is2>
-    struct concatenate_sequences<index_sequence<Is1...>, index_sequence<Is2...>>
-        : type_is<index_sequence<Is1..., Is2...>>
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using concatenate_sequences_t = typename concatenate_sequences<Ts...>::type;
-
-    template<class...>
-    struct append_indices;
-
-    template<size_t... Is, class... Ts, class... Tuples>
-    struct append_indices<index_sequence<Is...>, tuple<Ts...>, Tuples...>
-        : append_indices<
-        concatenate_sequences_t<
-            index_sequence<Is...>, make_index_sequence<sizeof...(Ts)>
-        >,
-        Tuples...
-    >
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using append_indices_t = typename append_indices<Ts...>::types;
-
-    template<class...>
-    struct generate_indices;
-
-    template<class... Ts, class... Tuples>
-    struct generate_indices<tuple<Ts...>, Tuples...>
-        : type_is<
-        append_indices_t<
-            make_index_sequence<sizeof...(Ts)>,
-            Tuples...
-        >
-    >
-    { /* DUMMY BODY */ };
-
-    template<class... Ts>
-    using generate_indices_t = typename generate_indices<Ts...>::type;
-
-    template<class... Tuples, size_t... Is1, size_t... Is2>
-    tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls,
-                                          index_sequence<Is1...>,
-                                          index_sequence<Is2...>)
-    {
-        return tuple_cat_type_t<Tuples...>{
-            get<Is1...>(
-                get<Is2...>(
-                    forward<Tuples>(tpls)
-                )
-            )...
-        };
-    }
-}
-
-#endif
Index: pace/lib/cpp/include/internal/tuple_ops.hpp
===================================================================
--- uspace/lib/cpp/include/internal/tuple_ops.hpp	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ 	(revision )
@@ -1,110 +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_OPS
-#define LIBCPP_TUPLE_OPS
-
-#include <utility>
-
-namespace std
-{ // forward declarations
-    template<class... Ts>
-    struct tuple;
-
-    template<size_t I, class T>
-    struct tuple_element;
-
-    template<size_t I, class... Ts>
-    constexpr typename tuple_element<I, tuple<Ts...>>::type& get(tuple<Ts...>& tpl) noexcept;
-}
-
-namespace std::aux
-{
-    template<size_t I, size_t N>
-    struct tuple_ops
-    {
-        template<class T, class U>
-        static void assign(T&& lhs, U&& rhs)
-        {
-            get<I>(forward<T>(lhs)) = get<I>(forward<U>(rhs));
-
-            tuple_ops<I + 1, N>::assign(forward<T>(lhs), forward<U>(rhs));
-        }
-
-        template<class T, class U>
-        static void swap(T& lhs, U& rhs)
-        {
-            std::swap(get<I>(lhs), get<I>(rhs));
-
-            tuple_ops<I + 1, N>::swap(lhs, rhs);
-        }
-
-        template<class T, class U>
-        static bool eq(const T& lhs, const U& rhs)
-        {
-            return (get<I>(lhs) == get<I>(rhs)) && tuple_ops<I + 1, N>::eq(lhs, rhs);
-        }
-
-        template<class T, class U>
-        static bool lt(const T& lhs, const U& rhs)
-        {
-            return (get<I>(lhs) < get<I>(rhs)) ||
-                (!(get<I>(rhs) < get<I>(lhs)) && tuple_ops<I + 1, N>::lt(lhs, rhs));
-        }
-    };
-
-    template<size_t N>
-    struct tuple_ops<N, N>
-    {
-        template<class T, class U>
-        static void assign(T&& lhs, U&& rhs)
-        {
-            get<N>(forward<T>(lhs)) = get<N>(forward<U>(rhs));
-        }
-
-        template<class T, class U>
-        static void swap(T& lhs, U& rhs)
-        {
-            std::swap(get<N>(lhs), get<N>(rhs));
-        }
-
-        template<class T, class U>
-        static bool eq(const T& lhs, const U& rhs)
-        {
-            return get<N>(lhs) == get<N>(rhs);
-        }
-
-        template<class T, class U>
-        static bool lt(const T& lhs, const U& rhs)
-        {
-            return get<N>(lhs) < get<N>(rhs);
-        }
-    };
-}
-
-#endif
Index: uspace/lib/cpp/include/internal/type_traits/references.hpp
===================================================================
--- uspace/lib/cpp/include/internal/type_traits/references.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/type_traits/references.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,76 @@
+/*
+ * 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_INTERNAL_TYPE_TRAITS_REFERENCES
+#define LIBCPP_INTERNAL_TYPE_TRAITS_REFERENCES
+
+#include <internal/aux.hpp>
+
+namespace std
+{
+    /**
+     * 20.10.7.2, reference modifications:
+     */
+
+    template<class T>
+    struct remove_reference: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_reference<T&>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct remove_reference<T&&>: aux::type_is<T>
+    { /* DUMMY BODY */ };
+
+    // TODO: is this good?
+    template<class T>
+    struct add_lvalue_reference: aux::type_is<T&>
+    { /* DUMMY BODY */ };
+
+    // TODO: Special case when T is not referencable!
+    template<class T>
+    struct add_rvalue_reference: aux::type_is<T&&>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    struct add_rvalue_reference<T&>: aux::type_is<T&>
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using remove_reference_t = typename remove_reference<T>::type;
+
+    template<class T>
+    using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
+
+    template<class T>
+    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/type_traits/result_of.hpp
===================================================================
--- uspace/lib/cpp/include/internal/type_traits/result_of.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/type_traits/result_of.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -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_INTERNAL_TYPE_TRAITS_RESULT_OF
+#define LIBCPP_INTERNAL_TYPE_TRAITS_RESULT_OF
+
+#include <internal/functional/invoke.hpp>
+
+namespace std
+{
+    template<class>
+    class result_of
+    { /* DUMMY BODY */ };
+
+    template<class F, class... ArgTypes>
+    class result_of<F(ArgTypes...)>: aux::type_is<
+        decltype(aux::invoke(declval<F>(), declval<ArgTypes>()...))
+    >
+    { /* DUMMY BODY */ };
+
+    template<class T>
+    using result_of_t = typename result_of<T>::type;
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/utility/declval.hpp
===================================================================
--- uspace/lib/cpp/include/internal/utility/declval.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/utility/declval.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,46 @@
+/*
+ * 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_INTERNAL_UTILITY_DECLVAL
+#define LIBCPP_INTERNAL_UTILITY_DECLVAL
+
+#include <internal/type_traits/references.hpp>
+
+namespace std
+{
+    /**
+     * 20.2.5, function template declval:
+     * Note: This function only needs declaration, not
+     *       implementation.
+     */
+
+    template<class T>
+    add_rvalue_reference_t<T> declval() noexcept;
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/utility/forward_move.hpp
===================================================================
--- uspace/lib/cpp/include/internal/utility/forward_move.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
+++ uspace/lib/cpp/include/internal/utility/forward_move.hpp	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -0,0 +1,59 @@
+/*
+ * 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_INTERNAL_UTILITY_FORWARD_MOVE
+#define LIBCPP_INTERNAL_UTILITY_FORWARD_MOVE
+
+#include <internal/type_traits/references.hpp>
+
+namespace std
+{
+    /**
+     * 20.2.4, forward/move helpers:
+     */
+
+    template<class T>
+    constexpr T&& forward(remove_reference_t<T>& t) noexcept
+    {
+        return static_cast<T&&>(t);
+    }
+
+    template<class T>
+    constexpr T&& forward(remove_reference_t<T>&& t) noexcept
+    {
+        return static_cast<T&&>(t);
+    }
+
+    template<class T>
+    constexpr remove_reference_t<T>&& move(T&& t) noexcept
+    {
+        return static_cast<remove_reference_t<T>&&>(t);
+    }
+}
+
+#endif
Index: uspace/lib/cpp/include/type_traits
===================================================================
--- uspace/lib/cpp/include/type_traits	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/type_traits	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -28,2 +28,4 @@
 
 #include <impl/type_traits.hpp>
+#include <internal/type_traits/references.hpp>
+#include <internal/type_traits/result_of.hpp>
Index: uspace/lib/cpp/include/utility
===================================================================
--- uspace/lib/cpp/include/utility	(revision daef596e7da9c68c8b9a6b33dd996a2452436ef4)
+++ uspace/lib/cpp/include/utility	(revision c866a83963c9d6c8d137e5814d6b98011c19030f)
@@ -28,2 +28,4 @@
 
 #include <impl/utility.hpp>
+#include <internal/utility/declval.hpp>
+#include <internal/utility/forward_move.hpp>
