/** 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