#ifndef TILE_BASE_OPTION_DYNAMICALLY_CHANGED_H
#define TILE_BASE_OPTION_DYNAMICALLY_CHANGED_H

#pragma once

#include "tile/base/internal/meta.h"
#include "tile/base/thread/mutex.h"
#include "tile/base/thread/scoped_lock.h"

namespace tile {
namespace option {
namespace detail {
template<typename T>
class DynamicallyChanged {
public:
    explicit DynamicallyChanged(T default_value = {}) : value_(std::move(default_value)) {}

    const T &Get() const noexcept
    {
        ScopedLock _(m);
        return value_;
    }

    template<typename... Us>
    void Emplace(Us &&...us)
    {
        ScopedLock _(m);
        value_ = T(std::forward<Us>(us)...);
    }

private:
    T value_;
    mutable Mutex m;
};
}// namespace detail
}// namespace option
}// namespace tile

#endif// TILE_BASE_OPTION_DYNAMICALLY_CHANGED_H
