Index: uspace/lib/cpp/include/__bits/thread/promise.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/promise.hpp	(revision 87efcb1f8ff924519fb6b9edc89557f4281eeda9)
+++ uspace/lib/cpp/include/__bits/thread/promise.hpp	(revision cf2792705d47bab8766bafc93b628620a7f0814d)
@@ -41,15 +41,96 @@
      */
 
+    namespace aux
+    {
+        template<class R>
+        class promise_base
+        {
+            public:
+                promise_base()
+                    : state_{new aux::shared_state<R>{}}
+                { /* DUMMY BODY */ }
+
+                template<class Allocator>
+                promise_base(allocator_arg_t, const Allocator& a)
+                    : promise_base{}
+                {
+                    // TODO: Use the allocator.
+                }
+
+                promise_base(promise_base&& rhs) noexcept
+                    : state_{}
+                {
+                    state_ = rhs.state_;
+                    rhs.state_ = nullptr;
+                }
+
+                promise_base(const promise_base&) = delete;
+
+                virtual ~promise_base()
+                {
+                    this->abandon_state_();
+                }
+
+                promise_base& operator=(promise_base&& rhs) noexcept
+                {
+                    abandon_state_();
+                    promise_base{std::move(rhs)}.swap(*this);
+
+                    return *this;
+                }
+
+                promise_base& operator=(const promise_base&) = delete;
+
+                void swap(promise_base& other) noexcept
+                {
+                    std::swap(state_, other.state_);
+                }
+
+                future<R> get_future()
+                {
+                    return future<R>{state_};
+                }
+
+                void set_exception(exception_ptr ptr)
+                {
+                    assert(state_);
+
+                    state_->set_exception(ptr);
+                }
+
+                void set_exception_at_thread_exit(exception_ptr)
+                {
+                    // TODO: No exception handling, no-op at this time.
+                }
+
+            protected:
+                void abandon_state_()
+                {
+                    /**
+                     * Note: This is the 'abandon' move described in
+                     *       30.6.4 (7).
+                     * 1) If state is not ready:
+                     *   a) Store exception of type future_error with
+                     *      error condition broken_promise.
+                     *   b) Mark state as ready.
+                     * 2) Release the state.
+                     */
+                }
+
+                aux::shared_state<R>* state_;
+        };
+    }
+
     template<class R>
-    class promise
+    class promise: public aux::promise_base<R>
     {
         public:
             promise()
-                : state_{new aux::shared_state<R>{}}
+                : aux::promise_base<R>{}
             { /* DUMMY BODY */ }
 
             template<class Allocator>
             promise(allocator_arg_t, const Allocator& a)
-                : promise{}
+                : aux::promise_base<R>{}
             {
                 // TODO: Use the allocator.
@@ -57,82 +138,55 @@
 
             promise(promise&& rhs) noexcept
-                : state_{}
-            {
-                state_ = rhs.state_;
-                rhs.state_ = nullptr;
-            }
+                : aux::promise_base<R>{move(rhs)}
+            { /* DUMMY BODY */ }
 
             promise(const promise&) = delete;
 
-            ~promise()
-            {
-                abandon_state_();
-            }
-
-            promise& operator=(promise&& rhs) noexcept
-            {
-                abandon_state_();
-                promise{std::move(rhs)}.swap(*this);
-            }
+            ~promise() override = default;
+
+            promise& operator=(promise&& rhs) noexcept = default;
 
             promise& operator=(const promise&) = delete;
 
-            void swap(promise& other) noexcept
-            {
-                std::swap(state_, other.state_);
-            }
-
-            future<R> get_future()
-            {
-                return future<R>{state_};
-            }
-
             void set_value(const R& val)
             {
-                if (!state_)
-                    throw future_error{make_error_code(future_errc::no_state)};
-                if (state_->is_set())
-                {
-                    throw future_error{
-                        make_error_code(future_errc::promise_already_satisfied)
-                    };
-                }
-
-                state_->set_value(val, true);
+                if (!this->state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (this->state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                this->state_->set_value(val, true);
             }
 
             void set_value(R&& val)
             {
-                if (!state_)
-                    throw future_error{make_error_code(future_errc::no_state)};
-                if (state_->is_set())
-                {
-                    throw future_error{
-                        make_error_code(future_errc::promise_already_satisfied)
-                    };
-                }
-
-                state_->set_value(std::forward<R>(val), true);
-            }
-
-            void set_exception(exception_ptr ptr)
-            {
-                assert(state_);
-
-                state_->set_exception(ptr);
+                if (!this->state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (this->state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                this->state_->set_value(std::forward<R>(val), true);
             }
 
             void set_value_at_thread_exit(const R& val)
             {
-                if (!state_)
-                    throw future_error{make_error_code(future_errc::no_state)};
-                if (state_->is_set())
-                {
-                    throw future_error{
-                        make_error_code(future_errc::promise_already_satisfied)
-                    };
-                }
-
-                state_->set_value(val, false);
+                if (!this->state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (this->state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                this->state_->set_value(val, false);
                 // TODO: schedule it to be set as ready when thread exits
             }
@@ -140,49 +194,86 @@
             void set_value_at_thread_exit(R&& val)
             {
-                if (!state_)
-                    throw future_error{make_error_code(future_errc::no_state)};
-                if (state_->is_set())
-                {
-                    throw future_error{
-                        make_error_code(future_errc::promise_already_satisfied)
-                    };
-                }
-
-                state_->set_value(std::forward<R>(val), false);
+                if (!this->state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (this->state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                this->state_->set_value(std::forward<R>(val), false);
                 // TODO: schedule it to be set as ready when thread exits
             }
-
-            void set_exception_at_thread_exit(exception_ptr)
-            {
-                // TODO: No exception handling, no-op at this time.
-            }
-
-        private:
-            void abandon_state_()
-            {
-                /**
-                 * Note: This is the 'abandon' move described in
-                 *       30.6.4 (7).
-                 * 1) If state is not ready:
-                 *   a) Store exception of type future_error with
-                 *      error condition broken_promise.
-                 *   b) Mark state as ready.
-                 * 2) Rekease the state.
-                 */
-            }
-
-            aux::shared_state<R>* state_;
     };
 
     template<class R>
-    class promise<R&>
-    {
-        // TODO: Copy & modify once promise is done.
+    class promise<R&>: public aux::promise_base<R>
+    { // TODO: I'm afraid we will need aux::shared_state<R&> specialization for this :/
+        public:
+            promise()
+                : aux::promise_base<R&>{}
+            { /* DUMMY BODY */ }
+
+            template<class Allocator>
+            promise(allocator_arg_t, const Allocator& a)
+                : aux::promise_base<R&>{}
+            {
+                // TODO: Use the allocator.
+            }
+
+            promise(promise&& rhs) noexcept
+                : aux::promise_base<R&>{move(rhs)}
+            { /* DUMMY BODY */ }
+
+            promise(const promise&) = delete;
+
+            ~promise() override = default;
+
+            promise& operator=(promise&& rhs) noexcept = default;
+
+            promise& operator=(const promise&) = delete;
     };
 
     template<>
-    class promise<void>
-    {
-        // TODO: Copy & modify once promise is done.
+    class promise<void>: public aux::promise_base<void>
+    {
+        public:
+            promise()
+                : aux::promise_base<void>{}
+            { /* DUMMY BODY */ }
+
+            template<class Allocator>
+            promise(allocator_arg_t, const Allocator& a)
+                : aux::promise_base<void>{}
+            {
+                // TODO: Use the allocator.
+            }
+
+            promise(promise&& rhs) noexcept
+                : aux::promise_base<void>{move(rhs)}
+            { /* DUMMY BODY */ }
+
+            promise(const promise&) = delete;
+
+            ~promise() override = default;
+
+            promise& operator=(promise&& rhs) noexcept = default;
+
+            promise& operator=(const promise&) = delete;
+
+            void set_value()
+            {
+                if (!this->state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (this->state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                this->state_->set_value();
+            }
     };
 
