Index: uspace/lib/cpp/include/impl/tuple.hpp
===================================================================
--- uspace/lib/cpp/include/impl/tuple.hpp	(revision f6f636ff61ebfcb4af2d344a89c84f4503efcbc7)
+++ uspace/lib/cpp/include/impl/tuple.hpp	(revision 9c9ee5da8792a73f1ea29a7684d8fc70c84b2277)
@@ -81,5 +81,5 @@
     template<class... Tuples>
     constexpr aux::tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls)
-    {
+    { // TODO: currently does not work because of index mismatch
         return aux::tuple_cat(
             forward<Tuples>(tpls)...,
@@ -206,4 +206,24 @@
                     : tuple_element_wrapper<Is, Ts>(forward<Us>(us))...
                 { /* DUMMY BODY */ }
+
+                template<class... Us>
+                constexpr tuple_impl(const tuple<Us...>& tpl)
+                    : tuple_impl{tpl, make_index_sequence<sizeof...(Us)>{}}
+                { /* DUMMY BODY */ }
+
+                template<class... Us>
+                constexpr tuple_impl(tuple<Us...>&& tpl)
+                    : tuple_impl{move<tuple<Us...>>(tpl), make_index_sequence<sizeof...(Us)>{}}
+                { /* DUMMY BODY */ }
+
+                template<class... Us, size_t... Iss>
+                constexpr tuple_impl(const tuple<Us...>& tpl, index_sequence<Iss...>)
+                    : tuple_impl{get<Iss>(tpl)...}
+                { /* DUMMY BODY */ }
+
+                template<class... Us, size_t... Iss>
+                constexpr tuple_impl(tuple<Us...>&& tpl, index_sequence<Iss...>)
+                    : tuple_impl{get<Iss>(move(tpl))...}
+                { /* DUMMY BODY */ }
         };
 
@@ -313,6 +333,6 @@
             { /* DUMMY BODY */ }
 
-            template<class... Us>
-            constexpr explicit tuple(Us&&... us)
+            template<class... Us> // TODO: is_convertible == true for all Us to all Ts
+            constexpr explicit tuple(Us&&... us, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
                 : base_t(forward<Us>(us)...)
             { /* DUMMY BODY */ }
@@ -322,11 +342,11 @@
 
             template<class... Us>
-            constexpr tuple(const tuple<Us...>& tpl)
+            constexpr tuple(const tuple<Us...>& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
                 : base_t(tpl)
             { /* DUMMY BODY */ }
 
             template<class... Us>
-            constexpr tuple(tuple<Us...>&& tpl)
-                : base_t(forward<tuple<Us>>(tpl)...)
+            constexpr tuple(tuple<Us...>&& tpl, enable_if_t<sizeof...(Us) == sizeof...(Ts)>* = nullptr)
+                : base_t(move(tpl))
             { /* DUMMY BODY */ }
 
@@ -356,5 +376,5 @@
             tuple& operator=(const tuple& other)
             {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign(*this, other);
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
 
                 return *this;
@@ -363,5 +383,5 @@
             tuple& operator=(tuple&& other) noexcept(aux::tuple_noexcept_assignment<Ts...>::value)
             {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign(*this, forward<tuple>(other));
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
 
                 return *this;
@@ -371,5 +391,5 @@
             tuple& operator=(const tuple<Us...>& other)
             {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign(*this, other);
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_copy(*this, other);
 
                 return *this;
@@ -379,5 +399,5 @@
             tuple& operator=(tuple<Us...>&& other)
             {
-                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign(*this, forward<Us>(other)...);
+                aux::tuple_ops<0, sizeof...(Ts) - 1>::assign_move(*this, move(other));
 
                 return *this;
@@ -389,4 +409,6 @@
                 get<0>(*this) = p.first;
                 get<1>(*this) = p.second;
+
+                return *this;
             }
 
@@ -396,4 +418,6 @@
                 get<0>(*this) = forward<U1>(p.first);
                 get<1>(*this) = forward<U2>(p.second);
+
+                return *this;
             }
 
Index: uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp
===================================================================
--- uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp	(revision f6f636ff61ebfcb4af2d344a89c84f4503efcbc7)
+++ uspace/lib/cpp/include/internal/tuple/tuple_ops.hpp	(revision 9c9ee5da8792a73f1ea29a7684d8fc70c84b2277)
@@ -50,9 +50,17 @@
     {
         template<class T, class U>
-        static void assign(T&& lhs, U&& rhs)
+        static void assign_copy(T& lhs, const U& rhs)
         {
-            get<I>(forward<T>(lhs)) = get<I>(forward<U>(rhs));
+            get<I>(lhs) = get<I>(rhs);
 
-            tuple_ops<I + 1, N>::assign(forward<T>(lhs), forward<U>(rhs));
+            tuple_ops<I + 1, N>::assign_copy(lhs, rhs);
+        }
+
+        template<class T, class U>
+        static void assign_move(T& lhs, U&& rhs)
+        {
+            get<I>(lhs) = move(get<I>(rhs));
+
+            tuple_ops<I + 1, N>::assign_move(lhs, move(rhs));
         }
 
@@ -83,7 +91,13 @@
     {
         template<class T, class U>
-        static void assign(T&& lhs, U&& rhs)
+        static void assign_copy(T& lhs, const U& rhs)
         {
-            get<N>(forward<T>(lhs)) = get<N>(forward<U>(rhs));
+            get<N>(lhs) = get<N>(rhs);
+        }
+
+        template<class T, class U>
+        static void assign_move(T& lhs, U&& rhs)
+        {
+            get<N>(lhs) = move(get<N>(rhs));
         }
 
