diff --git a/include/raii/atomic_shared.hpp b/include/raii/atomic_shared.hpp new file mode 100644 index 0000000..d73059d --- /dev/null +++ b/include/raii/atomic_shared.hpp @@ -0,0 +1,98 @@ +/** + This file is a part of rexy's matrix client + Copyright (C) 2019 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef RAII_ATOMIC_SHARED_HPP +#define RAII_ATOMIC_SHARED_HPP + +#include //shared_ptr +#include //atomic_shared_ptr + +#if __cplusplus > 201703L //newer than c++17 + +namespace raii{ + template + using atomic_shared_ptr = std::atomic>; +} + +#else //c++17 or older + +namespace raii{ + + template + class atomic_shared_ptr + { + private: + static constexpr bool is_always_lock_free = (ATOMIC_POINTER_LOCK_FREE == 2); + + private: + std::shared_ptr m_data; + + public: + constexpr atomic_shared_ptr(void)noexcept = default; + atomic_shared_ptr(std::shared_ptr desired)noexcept: + m_data(std::move(desired)){} + atomic_shared_ptr(const atomic_shared_ptr&) = delete; + + void operator=(const atomic_shared_ptr&) = delete; + void operator=(std::shared_ptr desired)noexcept{ + store(desired); + } + bool is_lock_free(void)const noexcept{ + return std::atomic_is_lock_free(&m_data); + } + void store(std::shared_ptr desired, std::memory_order order = std::memory_order_seq_cst)noexcept{ + return std::atomic_store_explicit(&m_data, desired, order); + } + std::shared_ptr load(std::memory_order order = std::memory_order_seq_cst)const noexcept{ + return std::atomic_load(&m_data); + } + operator std::shared_ptr(void)const noexcept{ + return load(); + } + std::shared_ptr exchange(std::shared_ptr desired, std::memory_order order = std::memory_order_seq_cst)noexcept{ + return std::atomic_exchange_explicit(&m_data, desired, order); + } + bool compare_exchange_strong(std::shared_ptr& expected, std::shared_ptr desired, std::memory_order success, std::memory_order failure)noexcept{ + return std::atomic_compare_exchange_strong_explicit(&m_data, &expected, desired, success, failure); + } + bool compare_exchange_strong(std::shared_ptr& expected, std::shared_ptr desired, std::memory_order order = std::memory_order_seq_cst)noexcept{ + std::memory_order fail_order = order; + if(fail_order == std::memory_order_acq_rel) + fail_order = std::memory_order_acquire; + else if(fail_order == std::memory_order_release) + fail_order = std::memory_order_relaxed; + return compare_exchange_strong(expected, desired, order, fail_order); + } + bool compare_exchange_weak(std::shared_ptr& expected, std::shared_ptr desired, std::memory_order success, std::memory_order failure)noexcept{ + return std::atomic_compare_exchange_weak_explicit(&m_data, &expected, desired, success, failure); + } + bool compare_exchange_weak(std::shared_ptr& expected, std::shared_ptr desired, std::memory_order order = std::memory_order_seq_cst)noexcept{ + std::memory_order fail_order = order; + if(fail_order == std::memory_order_acq_rel) + fail_order = std::memory_order_acquire; + else if(fail_order == std::memory_order_release) + fail_order = std::memory_order_relaxed; + return compare_exchange_weak(expected, desired, order, fail_order); + } + }; + +} + +#endif //__cplusplus + +#endif //RAII_ATOMIC_SHARED_HPP