File indexing completed on 2024-05-05 04:38:10

0001 /*
0002     SPDX-FileCopyrightText: 2022 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_ITEMREPOSITORYREFERENCECOUNTING_H
0008 #define KDEVPLATFORM_ITEMREPOSITORYREFERENCECOUNTING_H
0009 
0010 #include "itemrepository.h"
0011 
0012 namespace KDevelop {
0013 
0014 struct ItemRepositoryReferenceCounting {
0015     template <typename Item>
0016     static inline bool inc(Item* item)
0017     {
0018         Q_ASSERT(item);
0019         const auto index = item->index();
0020         Q_ASSERT(index);
0021 
0022         if (!shouldDoDUChainReferenceCounting(item)) {
0023             return false;
0024         }
0025 
0026         LockedItemRepository::write<Item>(
0027             [&](auto& repo) { item->increase(repo.dynamicItemFromIndexSimple(index)->m_refCount, index); });
0028         return true;
0029     }
0030 
0031     template <typename Item>
0032     static inline bool dec(Item* item)
0033     {
0034         Q_ASSERT(item);
0035         const auto index = item->index();
0036         Q_ASSERT(index);
0037 
0038         if (!shouldDoDUChainReferenceCounting(item)) {
0039             return false;
0040         }
0041 
0042         LockedItemRepository::write<Item>(
0043             [&](auto& repo) { item->decrease(repo.dynamicItemFromIndexSimple(index)->m_refCount, index); });
0044         return true;
0045     }
0046 
0047     struct AssumeValidIndex {
0048         bool operator()(unsigned int index) const
0049         {
0050             Q_ASSERT(index);
0051             return true;
0052         }
0053     };
0054 
0055     template <typename Item, typename CheckIndex = AssumeValidIndex>
0056     static inline void setIndex(Item* item, unsigned int& m_index, unsigned int index,
0057                                 CheckIndex checkIndex = AssumeValidIndex{})
0058     {
0059         Q_ASSERT(item);
0060         if (m_index == index) {
0061             return;
0062         }
0063 
0064         if (shouldDoDUChainReferenceCounting(item)) {
0065             LockedItemRepository::write<Item>([&](auto& repo) {
0066                 if (checkIndex(m_index)) {
0067                     item->decrease(repo.dynamicItemFromIndexSimple(m_index)->m_refCount, m_index);
0068                 }
0069 
0070                 m_index = index;
0071 
0072                 if (checkIndex(m_index)) {
0073                     item->increase(repo.dynamicItemFromIndexSimple(m_index)->m_refCount, m_index);
0074                 }
0075             });
0076         } else {
0077             m_index = index;
0078         }
0079     }
0080 };
0081 
0082 }
0083 
0084 #endif