File indexing completed on 2024-10-20 03:40:09
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0003 SPDX-FileContributor: 2010 Stephen Kelly <stephen@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KVOIDPOINTERFACTORY_P_H 0009 #define KVOIDPOINTERFACTORY_P_H 0010 0011 #include <cstddef> 0012 #include <cstdlib> 0013 #include <vector> 0014 0015 #define DEFAULT_BLOCK_SIZE 256 0016 0017 /** 0018 * @brief A Class for managing void pointers for use in QModelIndexes. 0019 * 0020 * This class creates void pointers pointing to individual blocks of memory. 0021 * The pointed-to memory contains zeros. 0022 * 0023 * Memory is allocated in blocks of size @p blockSize times sizeof(void*) at a time. The used 0024 * memory is automatically freed and can be cleared manually. 0025 * 0026 * The void pointers should not be dereferenced, but only used as a unique 0027 * identifier suitable for use with createIndex() and for comparison with other void pointers. 0028 */ 0029 template<std::size_t blockSize = DEFAULT_BLOCK_SIZE> 0030 class KVoidPointerFactory 0031 { 0032 // a class with size 1. 0033 class Bit 0034 { 0035 bool bit; 0036 }; 0037 0038 public: 0039 KVoidPointerFactory() 0040 : m_previousPointer(nullptr) 0041 , m_finalPointer(nullptr) 0042 { 0043 } 0044 0045 KVoidPointerFactory(const KVoidPointerFactory<blockSize> &other) 0046 { 0047 *this = other; 0048 } 0049 0050 KVoidPointerFactory<blockSize> &operator=(const KVoidPointerFactory<blockSize> &other) 0051 { 0052 m_previousPointer = other.m_previousPointer; 0053 m_finalPointer = other.m_finalPointer; 0054 m_blocks = other.m_blocks; 0055 return *this; 0056 } 0057 0058 ~KVoidPointerFactory() 0059 { 0060 clear(); 0061 } 0062 0063 void clear() 0064 { 0065 typename std::vector<Bit *>::const_iterator it = m_blocks.begin(); 0066 const typename std::vector<Bit *>::const_iterator end = m_blocks.end(); 0067 for (; it != end; ++it) { 0068 free(*it); 0069 } 0070 m_blocks.clear(); 0071 m_finalPointer = nullptr; 0072 m_previousPointer = nullptr; 0073 } 0074 0075 void *createPointer() const 0076 { 0077 if (m_previousPointer == m_finalPointer) { 0078 static const std::size_t pointer_size = sizeof(Bit *); 0079 Bit *const bit = static_cast<Bit *>(calloc(blockSize, pointer_size)); 0080 m_blocks.push_back(bit); 0081 m_finalPointer = bit + (blockSize * pointer_size) - 1; 0082 m_previousPointer = bit; 0083 return bit; 0084 } 0085 return ++m_previousPointer; 0086 } 0087 0088 private: 0089 mutable std::vector<Bit *> m_blocks; 0090 mutable Bit *m_previousPointer; 0091 mutable Bit *m_finalPointer; 0092 }; 0093 0094 // Disable factory with 0 blockSize 0095 template<> 0096 class KVoidPointerFactory<0> 0097 { 0098 public: 0099 KVoidPointerFactory(); 0100 0101 void clear(); 0102 void *createPointer(); 0103 }; 0104 0105 #endif