Index: uspace/lib/cpp/include/impl/tuple.hpp
===================================================================
--- uspace/lib/cpp/include/impl/tuple.hpp	(revision 55cd8299a72ca04832bff65f238be1619989a9a2)
+++ uspace/lib/cpp/include/impl/tuple.hpp	(revision e29ce3dd480dbab7ebe69b1d9473f2a2bb242d32)
@@ -31,4 +31,6 @@
 
 #include <internal/aux.hpp>
+#include <internal/tuple_cat.hpp>
+#include <internal/tuple_ops.hpp>
 #include <functional>
 #include <type_traits>
@@ -93,6 +95,13 @@
     }
 
-    template<class... Tuples> // TODO: dafuq is ctypes?
-    constexpr tuple<Tuples...> tuple_cat(Tuples&&... tpls);
+    template<class... Tuples>
+    constexpr aux::tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls)
+    {
+        return aux::tuple_cat(
+            forward<Tuples>(tpls)...,
+            make_index_sequence<sizeof...(Tuples)>{},
+            aux::generate_indices_t<Tuples...>{}
+        );
+    }
 
     /**
@@ -180,6 +189,17 @@
             constexpr tuple_element_wrapper() = default;
 
-            constexpr explicit tuple_element_wrapper(T val)
-                : value{val}
+            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 */ }
 
@@ -198,6 +218,12 @@
                 { /* DUMMY BODY */ }
 
-                constexpr explicit tuple_impl(const Ts&... ts)
-                    : tuple_element_wrapper<Is, Ts>(ts)...
+                constexpr explicit tuple_impl(Ts&&... ts)
+                    : tuple_element_wrapper<Is, Ts>(forward<Ts>(ts))...
+                { /* DUMMY BODY */ }
+
+                // TODO: enable only if Us is convertible to Ts and they are not same
+                template<class... Us>
+                constexpr explicit tuple_impl(Us&&... us)
+                    : tuple_element_wrapper<Is, Ts>(forward<Us>(us))...
                 { /* DUMMY BODY */ }
         };
@@ -255,5 +281,4 @@
         return wrapper.value;
     }
-
 
     namespace aux
@@ -286,72 +311,7 @@
     }
 
-    namespace 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);
-            }
-        };
-    }
-
     /**
      * 20.4.2, class template tuple:
      */
-
 
     template<class... Ts>
@@ -382,13 +342,13 @@
             tuple(tuple&&) = default;
 
-            /* template<class... Us> */
-            /* constexpr tuple(const tuple<Us...>& tpl) */
-            /*     : base_t(tpl) */
-            //{ /* DUMMY BODY */ }
-
-            /* template<class... Us> */
-            /* constexpr tuple(tuple<Us...>& tpl) */
-            /*     : base_t(forward<tuple<Us>>(tpl)...) */
-            //{ /* DUMMY BODY */ }
+            template<class... Us>
+            constexpr tuple(const tuple<Us...>& tpl)
+                : base_t(tpl)
+            { /* DUMMY BODY */ }
+
+            template<class... Us>
+            constexpr tuple(tuple<Us...>&& tpl)
+                : base_t(forward<tuple<Us>>(tpl)...)
+            { /* DUMMY BODY */ }
 
             // TODO: pair related construction and assignment needs convertibility, not size
