#ifndef _TILE_BASE_INTERNAL_UTILITY_H
#define _TILE_BASE_INTERNAL_UTILITY_H

#pragma once

#include <atomic>
#include <utility>

namespace tile {
namespace internal {
template<typename T, class U = T>
T
Exchange(T &obj, U &&new_value)
{
    T old_value = std::move(obj);
    obj         = std::forward<U>(new_value);
    return old_value;
}

template<typename T, typename U = T>
bool
TestAndSet(std::atomic<T> &obj, T expected_val, U &&new_value)
{
    return obj.compare_exchange_strong(expected_val, std::forward<U>(new_value));
}

}// namespace internal
}// namespace tile

#endif// _TILE_BASE_INTERNAL_UTILITY_H
