1/*
2 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
3 SPDX-FileContributor: 2010 Stephen Kelly <stephen@kdab.com>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KVOIDPOINTERFACTORY_P_H
9#define KVOIDPOINTERFACTORY_P_H
10
11#include <cstddef>
12#include <cstdlib>
13#include <vector>
14
15#define DEFAULT_BLOCK_SIZE 256
16
17/**
18 * @brief A Class for managing void pointers for use in QModelIndexes.
19 *
20 * This class creates void pointers pointing to individual blocks of memory.
21 * The pointed-to memory contains zeros.
22 *
23 * Memory is allocated in blocks of size @p blockSize times sizeof(void*) at a time. The used
24 * memory is automatically freed and can be cleared manually.
25 *
26 * The void pointers should not be dereferenced, but only used as a unique
27 * identifier suitable for use with createIndex() and for comparison with other void pointers.
28 */
29template<std::size_t blockSize = DEFAULT_BLOCK_SIZE>
30class KVoidPointerFactory
31{
32 // a class with size 1.
33 class Bit
34 {
35 bool bit;
36 };
37
38public:
39 KVoidPointerFactory()
40 : m_previousPointer(nullptr)
41 , m_finalPointer(nullptr)
42 {
43 }
44
45 KVoidPointerFactory(const KVoidPointerFactory<blockSize> &other)
46 {
47 *this = other;
48 }
49
50 KVoidPointerFactory<blockSize> &operator=(const KVoidPointerFactory<blockSize> &other)
51 {
52 m_previousPointer = other.m_previousPointer;
53 m_finalPointer = other.m_finalPointer;
54 m_blocks = other.m_blocks;
55 return *this;
56 }
57
58 ~KVoidPointerFactory()
59 {
60 clear();
61 }
62
63 void clear()
64 {
65 typename std::vector<Bit *>::const_iterator it = m_blocks.begin();
66 const typename std::vector<Bit *>::const_iterator end = m_blocks.end();
67 for (; it != end; ++it) {
68 free(*it);
69 }
70 m_blocks.clear();
71 m_finalPointer = nullptr;
72 m_previousPointer = nullptr;
73 }
74
75 void *createPointer() const
76 {
77 if (m_previousPointer == m_finalPointer) {
78 static const std::size_t pointer_size = sizeof(Bit *);
79 Bit *const bit = static_cast<Bit *>(calloc(nmemb: blockSize, size: pointer_size));
80 m_blocks.push_back(bit);
81 m_finalPointer = bit + (blockSize * pointer_size) - 1;
82 m_previousPointer = bit;
83 return bit;
84 }
85 return ++m_previousPointer;
86 }
87
88private:
89 mutable std::vector<Bit *> m_blocks;
90 mutable Bit *m_previousPointer;
91 mutable Bit *m_finalPointer;
92};
93
94// Disable factory with 0 blockSize
95template<>
96class KVoidPointerFactory<0>
97{
98public:
99 KVoidPointerFactory();
100
101 void clear();
102 void *createPointer();
103};
104
105#endif
106

source code of kitemmodels/src/core/kvoidpointerfactory_p.h