Index: uspace/lib/cpp/include/impl/functional.hpp
===================================================================
--- uspace/lib/cpp/include/impl/functional.hpp	(revision 9f77d98f542414bdbcb510aa5ada108b1df5d2cc)
+++ uspace/lib/cpp/include/impl/functional.hpp	(revision 48d9187cafdfe2d670bcf148be2f60d87fcdf264)
@@ -30,9 +30,7 @@
 #define LIBCPP_FUNCTIONAL
 
+#include <limits>
 #include <type_traits>
-
-extern "C" {
-#include <adt/hash.h>
-}
+#include <utility>
 
 namespace std
@@ -44,5 +42,5 @@
          */
         template<class R, class T, class T1, class... Ts>
-        decltype(auto) invoke(R T::* f, T1&& t1, Args&&... args)
+        decltype(auto) invoke(R T::* f, T1&& t1, Ts&&... args)
         {
             if constexpr (is_member_function_pointer_v<decltype(f)>)
@@ -50,10 +48,10 @@
                 if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
                     // (1.1)
-                    return (t1.*f)(forward<Args>(args)...);
+                    return (t1.*f)(forward<Ts>(args)...);
                 else
                     // (1.2)
-                    return ((*t1).*f)(forward<Args>(args)...);
+                    return ((*t1).*f)(forward<Ts>(args)...);
             }
-            else if (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
+            else if constexpr (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
             {
                 /**
@@ -68,5 +66,12 @@
                     return (*t1).*f;
             }
-            static_assert(false, "invalid invoke");
+
+            /**
+             * 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");
         }
 
@@ -208,5 +213,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) + forward<U>(rhs))
         {
@@ -221,5 +226,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) - forward<U>(rhs))
         {
@@ -234,5 +239,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) * forward<U>(rhs))
         {
@@ -247,5 +252,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) / forward<U>(rhs))
         {
@@ -260,5 +265,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) % forward<U>(rhs))
         {
@@ -273,5 +278,5 @@
     {
         template<class T>
-        constexpr auto operator(T&& x) const
+        constexpr auto operator()(T&& x) const
             -> decltype(-forward<T>(x))
         {
@@ -287,5 +292,5 @@
 
     template<class T = void>
-    struct equal_to;
+    struct equal_to
     {
         constexpr bool operator()(const T& lhs, const T& rhs) const
@@ -368,5 +373,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) == forward<U>(rhs))
         {
@@ -381,5 +386,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) != forward<U>(rhs))
         {
@@ -394,5 +399,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) > forward<U>(rhs))
         {
@@ -407,5 +412,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) < forward<U>(rhs))
         {
@@ -420,5 +425,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) >= forward<U>(rhs))
         {
@@ -433,5 +438,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) <= forward<U>(rhs))
         {
@@ -488,5 +493,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) && forward<U>(rhs))
         {
@@ -501,5 +506,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) || forward<U>(rhs))
         {
@@ -514,8 +519,8 @@
     {
         template<class T>
-        constexpr auto operator(T&& x) const
+        constexpr auto operator()(T&& x) const
             -> decltype(!forward<T>(x))
         {
-            return !forward<T>(lhs);
+            return !forward<T>(x);
         }
 
@@ -582,5 +587,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) & forward<U>(rhs))
         {
@@ -595,5 +600,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) | forward<U>(rhs))
         {
@@ -608,5 +613,5 @@
     {
         template<class T, class U>
-        constexpr auto operator(T&& lhs, U&& rhs) const
+        constexpr auto operator()(T&& lhs, U&& rhs) const
             -> decltype(forward<T>(lhs) ^ forward<U>(rhs))
         {
@@ -621,8 +626,8 @@
     {
         template<class T>
-        constexpr auto operator(T&& x) const
+        constexpr auto operator()(T&& x) const
             -> decltype(~forward<T>(x))
         {
-            return ~forward<T>(lhs);
+            return ~forward<T>(x);
         }
 
@@ -710,4 +715,40 @@
      */
 
+    namespace aux
+    {
+        template<class T>
+        union converter
+        {
+            T value;
+            uint64_t converted;
+        };
+
+        template<class T>
+        T hash_(uint64_t x) noexcept
+        {
+            // TODO: This is copied form adt/hash (temporarily),
+            //       check if we can use something better.
+            x = (x ^ 61) ^ (x >> 16);
+            x = x + (x << 3);
+            x = x ^ (x >> 4);
+            x = x * 0x27d4eb2d;
+            x = x ^ (x >> 15);
+
+            return static_cast<T>((x << 32) | (x >> 32));
+        }
+
+        template<class T>
+        size_t hash(T x) noexcept
+        {
+            static_assert(is_arithmetic_v<T> || is_pointer_v<T>,
+                          "invalid type passed to aux::hash");
+
+            converter<T> conv;
+            conv.value = x;
+
+            return hash_<size_t>(conv.converted);
+        }
+    }
+
     template<class T>
     struct hash
@@ -719,5 +760,5 @@
         size_t operator()(bool x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -731,5 +772,5 @@
         size_t operator()(char x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -743,5 +784,5 @@
         size_t operator()(signed char x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -755,5 +796,5 @@
         size_t operator()(unsigned char x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -767,5 +808,5 @@
         size_t operator()(char16_t x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -779,5 +820,5 @@
         size_t operator()(char32_t x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -791,5 +832,5 @@
         size_t operator()(wchar_t x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -803,5 +844,5 @@
         size_t operator()(short x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -815,5 +856,5 @@
         size_t operator()(unsigned short x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -827,5 +868,5 @@
         size_t operator()(int x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -839,5 +880,5 @@
         size_t operator()(unsigned int x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -851,5 +892,5 @@
         size_t operator()(long x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -863,5 +904,5 @@
         size_t operator()(long long x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -875,5 +916,5 @@
         size_t operator()(unsigned long x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -887,5 +928,5 @@
         size_t operator()(unsigned long long x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
@@ -899,5 +940,5 @@
         size_t operator()(float x) const noexcept
         {
-            return hash_mix(*(size_t*)(&x));
+            return aux::hash(x);
         }
 
@@ -907,9 +948,9 @@
 
     template<>
-    struct hash<double>;
+    struct hash<double>
     {
         size_t operator()(double x) const noexcept
         {
-            return hash_mix(*(size_t*)(&x));
+            return aux::hash(x);
         }
 
@@ -919,9 +960,9 @@
 
     template<>
-    struct hash<long double>;
+    struct hash<long double>
     {
         size_t operator()(long double x) const noexcept
         {
-            return hash_mix(*(size_t*)(&x));
+            return aux::hash(x);
         }
 
@@ -935,5 +976,5 @@
         size_t operator()(T* x) const noexcept
         {
-            return hash_mix(static_cast<size_t>(x));
+            return aux::hash(x);
         }
 
