.. _program_listing_file_liberate_concurrency_lock_policy.h: Program Listing for File lock_policy.h ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``liberate/concurrency/lock_policy.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * This file is part of liberate. * * Author(s): Jens Finkhaeuser * * Copyright (c) 2021 Jens Finkhaeuser. * Copyright (c) 2022 Interpeer gUG (haftungsbeschränkt) * * SPDX-License-Identifier: GPL-3.0-only * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LIBERATE_CONCURRENCY_LOCK_POLICY_H #define LIBERATE_CONCURRENCY_LOCK_POLICY_H #ifndef __cplusplus #error You are trying to include a C++ only header file #endif #include #include namespace liberate::concurrency { namespace detail { struct null_mutex { }; template struct null_lock { template inline null_lock(discardT &) { } }; template struct enable_if_smart_ptr_type { typedef R type; }; template struct is_smart_ptr : std::false_type {}; template struct is_smart_ptr< T, typename enable_if_smart_ptr_type< typename T::element_type >::type > : std::true_type {}; template struct mutex_ptr_lock_proxy { template inline mutex_ptr_lock_proxy( mutex_ptrT & mutex_ptr, argsT &&... args) : m_lock{*mutex_ptr, std::forward(args)...} { } static inline lockT & lock_ref(mutex_ptr_lock_proxy & proxy) { return proxy.m_lock; } lockT m_lock; }; template < typename mutexT, typename lockT, bool IS_POINTER, bool IS_SMART_POINTER > struct lock_selector { // Also selected for IS_POINTER && IS_SMART_POINTER, which should never // happen, so it's good that it fails. }; template < typename mutexT, typename lockT > struct lock_selector { using mutex_type = mutexT; using lock_type = lockT; static inline lockT & lock_ref(lockT & lock) { return lock; } }; template < typename mutexT, typename lockT > struct lock_selector { using mutex_type = mutexT; using lock_type = mutex_ptr_lock_proxy< mutexT, lockT >; static inline lockT & lock_ref(lockT & lock) { return lock_type::lock_ref(lock); } }; template < typename mutexT, typename lockT > struct lock_selector { using mutex_type = mutexT; using lock_type = mutex_ptr_lock_proxy< mutexT, lockT >; static inline lockT & lock_ref(lockT & lock) { return lock_type::lock_ref(lock); } }; } // namespace detail struct null_lock_policy { using mutex_type = detail::null_mutex; using lock_type = detail::null_lock; using _passed_lock_type = lock_type; }; template struct lock_policy { using _selector = detail::lock_selector< mutexT, lockT, std::is_pointer::value, detail::is_smart_ptr::value >; using mutex_type = typename _selector::mutex_type; using lock_type = typename _selector::lock_type; using _passed_lock_type = lockT; }; template inline typename lock_policyT::_passed_lock_type & lock_ref(typename lock_policyT::lock_type & lock) { return lock_policyT::_selector::lock_ref(lock); } template <> inline typename null_lock_policy::_passed_lock_type & lock_ref(typename null_lock_policy::lock_type & lock) { return lock; } } // namespace liberate::concurrency #endif // guard