Index: uspace/lib/cpp/include/internal/memory/shared_payload.hpp
===================================================================
--- uspace/lib/cpp/include/internal/memory/shared_payload.hpp	(revision 537b300f24e8c19c411f63ebc05e76d50df16563)
+++ uspace/lib/cpp/include/internal/memory/shared_payload.hpp	(revision 537b300f24e8c19c411f63ebc05e76d50df16563)
@@ -0,0 +1,97 @@
+/*
+ * 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_MEMORY_SHARED_PAYLOAD
+#define LIBCPP_INTERNAL_MEMORY_SHARED_PAYLOAD
+
+#include <internal/list.hpp>
+
+namespace std::aux
+{
+    /**
+     * At the moment we do not have atomics, change this
+     * to std::atomic<long> once we do.
+     */
+    using refcount_t = long;
+
+    template<class T>
+    class shared_payload
+    {
+        public:
+
+            template<class... Args>
+            shared_payload(Args&&... args)
+            { /* DUMMY BODY */ }
+
+            template<class Alloc, class... Args>
+            shared_payloda(Alloc alloc, Args&&... args)
+            { /* DUMMY BODY */ }
+
+            T* get() const
+            {
+                return data_;
+            }
+
+            void increment_refcount()
+            {
+                ++refcount_;
+            }
+
+            void increment_weak_refcount()
+            {
+                ++weak_refcount_;
+            }
+
+            bool decrement_refcount()
+            {
+                return --refcount_ == 0;
+            }
+
+            bool decrement_weak_refcount()
+            {
+                return --weak_refcount_ == 0;
+            }
+
+            refcount_t refs() const
+            {
+                return refcount_;
+            }
+
+            refcount_t weak_refs() const
+            {
+                return weak_refcount_;
+            }
+
+        private:
+            T* data_;
+            refcount_t refcount_;
+            refcount_t weak_refcount_;
+    };
+}
+
+#endif
Index: uspace/lib/cpp/include/internal/memory/shared_ptr.hpp
===================================================================
--- uspace/lib/cpp/include/internal/memory/shared_ptr.hpp	(revision 3c32c483ffebb7ee4542267eab14b4a7b91003ba)
+++ uspace/lib/cpp/include/internal/memory/shared_ptr.hpp	(revision 537b300f24e8c19c411f63ebc05e76d50df16563)
@@ -31,4 +31,6 @@
 
 #include <exception>
+#include <functional>
+#include <type_traits>
 
 namespace std
@@ -147,34 +149,84 @@
              */
 
-            element_type* get() const noexcept;
+            element_type* get() const noexcept
+            {
+                if (payload_)
+                    return payload_->get();
+                else
+                    return nullptr;
+            }
 
             T& operator*() const noexcept;
 
-            T* operator->() const noexcept;
-
-            long use_count() const noexcept;
-
-            bool unique() const noexcept;
-
-            explicit operator bool() const noexcept;
-
-            template<class U>
-            bool owner_before(const shared_ptr<U>& ptr) const;
+            T* operator->() const noexcept
+            {
+                return get();
+            }
+
+            long use_count() const noexcept
+            {
+                if (payload_)
+                    return payload_->refcount();
+                else
+                    return 0L;
+            }
+
+            bool unique() const noexcept
+            {
+                return use_count() == 1L;
+            }
+
+            explicit operator bool() const noexcept
+            {
+                return get() != nullptr;
+            }
+
+            template<class U>
+            bool owner_before(const shared_ptr<U>& ptr) const
+            {
+                return payload_ < ptr.payload_;
+            }
 
             template<class U>
             bool owner_before(const weak_ptr<U>& ptr) const;
 
-        /* private: */
+        private:
+            aux::shared_payload<element_type>* payload_;
+
+            shared_ptr(aux::shared_payload<element_type>* payload)
+                : payload_{payload}
+            { /* DUMMY BODY */ }
+
+            template<class U, class... Args>
+            friend shared_ptr<U> make_shared(Args&&...);
+
+            template<class U, class A, class... Args>
+            friend shared_ptr<U> allocate_shared(const A&, Args&&...);
     };
 
     /**
      * 20.8.2.2.6, shared_ptr creation:
+     * Note: According to the standard, these two functions
+     *       should perform at most one memory allocation
+     *       (should, don't have to :P). It might be better
+     *       to create payloads that embed the type T to
+     *       perform this optimization.
      */
 
     template<class T, class... Args>
-    shared_ptr<T> make_shared(Args&&... args);
+    shared_ptr<T> make_shared(Args&&... args)
+    {
+        return shared_ptr<T>{
+            new aux::shared_payload<T>{forward<Args>(args)...}
+        };
+    }
 
     template<class T, class A, class... Args>
-    shared_ptr<T> allocate_shared(const A& alloc, Args&&... args);
+    shared_ptr<T> allocate_shared(const A& alloc, Args&&... args)
+    {
+        return shared_ptr<T>{
+            new aux::shared_payload<T>{A{alloc}, forward<Args>(args)...}
+        };
+    }
 
     /**
@@ -183,56 +235,110 @@
 
     template<class T, class U>
-    bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T, class U>
-    bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T, class U>
-    bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T, class U>
-    bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T, class U>
-    bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T, class U>
-    bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept;
-
-    template<class T>
-    bool operator==(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator==(nullptr_t, const shared_ptr<T>& rhs) noexcept;
-
-    template<class T>
-    bool operator!=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator!=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
-
-    template<class T>
-    bool operator<(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator<(nullptr_t, const shared_ptr<T>& rhs) noexcept;
-
-    template<class T>
-    bool operator>(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator>(nullptr_t, const shared_ptr<T>& rhs) noexcept;
-
-    template<class T>
-    bool operator<=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator<=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
-
-    template<class T>
-    bool operator>=(const shared_ptr<T>& lhs, nullptr_t) noexcept;
-
-    template<class T>
-    bool operator>=(nullptr_t, const shared_ptr<T>& rhs) noexcept;
+    bool operator==(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return lhs.get() == rhs.get();
+    }
+
+    template<class T, class U>
+    bool operator!=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return !(lhs == rhs);
+    }
+
+    template<class T, class U>
+    bool operator<(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return less<common_type_t<T*, U*>>{}(lhs.get(), rhs.get());
+    }
+
+    template<class T, class U>
+    bool operator>(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return rhs < lhs;
+    }
+
+    template<class T, class U>
+    bool operator<=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return !(rhs < lhs);
+    }
+
+    template<class T, class U>
+    bool operator>=(const shared_ptr<T>& lhs, const shared_ptr<U>& rhs) noexcept
+    {
+        return !(lhs < rhs);
+    }
+
+    template<class T>
+    bool operator==(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return !lhs;
+    }
+
+    template<class T>
+    bool operator==(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return !rhs;
+    }
+
+    template<class T>
+    bool operator!=(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return (bool)lhs;
+    }
+
+    template<class T>
+    bool operator!=(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return (bool)rhs;
+    }
+
+    template<class T>
+    bool operator<(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return less<T*>{}(lhs.get(), nullptr);
+    }
+
+    template<class T>
+    bool operator<(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return less<T*>{}(nullptr, rhs.get());
+    }
+
+    template<class T>
+    bool operator>(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return nullptr < lhs;
+    }
+
+    template<class T>
+    bool operator>(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return rhs < nullptr;
+    }
+
+    template<class T>
+    bool operator<=(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return !(nullptr < lhs);
+    }
+
+    template<class T>
+    bool operator<=(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return !(rhs < nullptr);
+    }
+
+    template<class T>
+    bool operator>=(const shared_ptr<T>& lhs, nullptr_t) noexcept
+    {
+        return !(lhs < nullptr);
+    }
+
+    template<class T>
+    bool operator>=(nullptr_t, const shared_ptr<T>& rhs) noexcept
+    {
+        return !(nullptr < rhs);
+    }
 
     /**
@@ -251,11 +357,33 @@
 
     template<class T, class U>
-    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& ptr) noexcept;
-
-    template<class T, class U>
-    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& ptr) noexcept;
-
-    template<class T, class U>
-    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& ptr) noexcept;
+    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& ptr) noexcept
+    {
+        if (!ptr)
+            return shared_ptr<T>{};
+
+        return shared_ptr<T>{
+            ptr, static_cast<T*>(ptr.get())
+        };
+    }
+
+    template<class T, class U>
+    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& ptr) noexcept
+    {
+        if (auto res = dynamic_cast<T*>(ptr.get()))
+            return shared_ptr<T>{ptr, res};
+        else
+            return shared_ptr<T>{};
+    }
+
+    template<class T, class U>
+    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& ptr) noexcept
+    {
+        if (!ptr)
+            return shared_ptr<T>{};
+
+        return shared_ptr<T>{
+            ptr, const_cast<T*>(ptr.get())
+        };
+    }
 
     /**
@@ -264,5 +392,8 @@
 
     template<class D, class T>
-    D* get_deleter(const shared_ptr<T>& ptr) noexcept;
+    D* get_deleter(const shared_ptr<T>& ptr) noexcept
+    {
+        // TODO: implement this through payload
+    }
 
     /**
@@ -272,5 +403,8 @@
     template<class Char, class Traits, class T>
     basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
-                                            const shared_ptr<T>& ptr);
+                                            const shared_ptr<T>& ptr)
+    {
+        return os << ptr.get();
+    }
 }
 
