I have implemented a thread safe holder to safely pass data between threads.

User can set value many times, but only the first `SetIfEmpty` call stores the value, then user may read the value many times.

    template <typename T>
    class ThreadSafeHolder {
    public:
        ThreadSafeHolder() : is_value_set_(false) {
        }

        void SetIfEmpty(const T& value) {
            std::lock_guard<std::mutex> lock(mutex_);
            // memory_order_relaxed is enough because storing to
            // `is_value_set_` happens only in `SetIfEmpty` methods
            // which are protected by mutex.
            if (!is_value_set_.load(std::memory_order_relaxed)) {
                new(GetPtr()) T(value);
                is_value_set_.store(true, std::memory_order_release);
            }
        }

        void SetIfEmpty(T&& value) {
            std::lock_guard<std::mutex> lock(mutex_);
            if (!is_value_set_.load(std::memory_order_relaxed)) {
                new(GetPtr()) T(std::move(value));
                is_value_set_.store(true, std::memory_order_release);
            }
        }

        //! This method might be safely call only if previous `IsEmpty()`
        //! call returned `false`.
        const T& Get() const {
            assert(!IsEmpty());
            return *GetPtr();
        }

        bool IsEmpty() const {
            // memory_order_acquire loading to become synchronize with
            // memory_order_release storing in `SetIfEmpty` methods.
            return !is_value_set_.load(std::memory_order_acquire);
        }

        ~ThreadSafeHolder() {
            if (!IsEmpty()) {
                GetPtr()->~T();
            }
        }

    private:
        T* GetPtr() {
            return reinterpret_cast<T*>(value_place_holder_);
        }

        const T* GetPtr() const {
            return reinterpret_cast<const T*>(value_place_holder_);
        }

        // Reserved place for user data.
        char value_place_holder_[sizeof(T)];
        // Mutex for protecting writing access to placeholder.
        std::mutex mutex_;
        // Boolean indicator whether value was set or not.
        std::atomic<bool> is_value_set_;
    };

**Questions**

 - Is the code correct in general?
 - Is access to `is_value_set_` member properly synchronized?
 - Might be access to `is_value_set_` member even more relaxed?

**Application**

I wanted to develop such holder to pass active exceptions from worker threads to main thread.

Main thread:

    ThreadSafeHolder<std::exception_ptr> exceptionPtrHolder;
    // Run many workers.
    // Join workers.
    if (!exceptionPtrHolder.IsEmpty()) {
        std::rethrow_exception(exceptionPtrHolder.Get());
    }


Worker thread:

    try {
        while (exceptionPtrHolder.IsEmpty()) {
            // Do hard work...
        }
    } catch (...) {
        exceptionPtrHolder.SetIfEmpty(std::current_exception());
    }

**Note about `std::promise`**

`std::promise` is not suitable here (despite the fact that `std::promise::set_value` is thread safe) because
> An exception is thrown if there is no shared state or the shared state already stores a value or exception.

---
**EDIT:**

Incorporating remarks from the comments:

It is much better to have the same alignment as `T`:

    using ValueStorage = std::aligned_storage<sizeof(T), alignof(T)>;
    ValueStorage value_place_holder_;

Turn two `SetIfEmpty` methods to one:

    template <typename... Args>
    void SetIfEmpty(Args&&... args) {
        std::lock_guard<std::mutex> lock(mutex_);
        if (!is_value_set_.load(std::memory_order_relaxed)) {
            new (GetPtr()) T(std::forward<Args>(args)...);
            is_value_set_.store(true, std::memory_order_release);
        }
    }

To follow [the rule of three/five/zero](http://en.cppreference.com/w/cpp/language/rule_of_three) I have added move constructor and move assignment operator:

    ThreadSafeHolder(ThreadSafeHolder&& other)
        : is_value_set_(other.is_value_set_.load())
    {
        if (!other.IsEmpty()) {
            new (GetPtr()) T(std::move(other.Get()));
        }
    }

    ThreadSafeHolder& operator=(ThreadSafeHolder&& other) {
        if (&other != this) {
            DestroyValueIfNecessary();
            if (!other.IsEmpty()) {
                new (GetPtr()) T(std::move(other.Get()));
            }
            is_value_set_ = other.is_value_set_.load();
        }
        return *this;
    }

The full code is available on https://gist.github.com/anonymous/c5d987abfc73eda11e71