HelenOS sources

root/uspace/lib/cpp/include/__bits/thread/shared_future.hpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get
  2. __state

/*
 * Copyright (c) 2019 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_BITS_THREAD_SHARED_FUTURE
#define LIBCPP_BITS_THREAD_SHARED_FUTURE

#include <__bits/thread/future.hpp>
#include <__bits/thread/future_common.hpp>
#include <type_traits>

/**
 * Note: We do synchronization directly on the shared
 *       state, this means that with the exception of
 *       some member functions (which are only defined
 *       for specializations anyway) our future and
 *       shared_future are basically identical. Because
 *       of that, we can use aux::future_base for
 *       shared_future as well.
 */

namespace std
{
    /**
     * 30.6.7, class template shared_future:
     */

    template<class R>
    class shared_future: public aux::future_base<aux::future_inner_t<R>>
    {
        public:
            shared_future() noexcept = default;

            shared_future(const shared_future&) = default;

            shared_future(shared_future&&) noexcept = default;

            shared_future(future<R>&& rhs)
                : aux::future_base<aux::future_inner_t<R>>{move(rhs.state_)}
            {
                rhs.state_ = nullptr;
            }

            shared_future& operator=(const shared_future&) = default;

            shared_future& operator=(shared_future&&) noexcept = default;

            aux::future_return_shared_t<R> get() const
            {
                assert(this->state_);

                this->wait();

                if (this->state_->has_exception())
                    this->state_->throw_stored_exception();

                /**
                 * Using constexpr if and the future_inner and future_result
                 * metafunctions we can actually avoid having to create specializations
                 * for R& and void in this case.
                 */
                if constexpr (!is_same_v<R, void>)
                {
                    if constexpr (is_reference_v<R>)
                    {
                        assert(this->state_->get());

                        return *this->state_->get();
                    }
                    else
                        return this->state_->get();
                }
            }

            /**
             * Useful for testing as we can check some information
             * otherwise unavailable to us without waiting, e.g.
             * to check whether the state is ready, its reference
             * count etc.
             */
            aux::shared_state<aux::future_inner_t<R>>* __state() noexcept
            {
                return this->state_;
            }
    };
}

#endif

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub