1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 2019-2021, The LegacyClonk Team and contributors
5 *
6 * Distributed under the terms of the ISC license; see accompanying file
7 * "COPYING" for details.
8 *
9 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10 * See accompanying file "TRADEMARK" for details.
11 *
12 * To redistribute this file separately, substitute the full license texts
13 * for the above references.
14 */
15
16#pragma once
17
18#include "C4ValueContainer.h"
19
20template <typename T>
21class C4ValueStandardRefCountedContainer : public C4ValueContainer
22{
23 size_t referenceCount = 0;
24 size_t elementReferenceCount = 0;
25
26public:
27 virtual C4ValueContainer *IncRef() override
28 {
29 if (referenceCount && elementReferenceCount)
30 {
31 auto newContainer = new T(*static_cast<T *>(this));
32 ++newContainer->referenceCount;
33 return newContainer;
34 }
35 ++referenceCount;
36 return this;
37 }
38
39 virtual void DecRef() override
40 {
41 assert(referenceCount);
42 if (!--referenceCount)
43 {
44 delete this;
45 }
46 }
47
48 virtual C4ValueContainer *IncElementRef() override
49 {
50 if (referenceCount > 1)
51 {
52 auto newContainer = new T(*static_cast<T *>(this));
53 ++newContainer->referenceCount;
54 newContainer->elementReferenceCount = 1;
55 DecRef();
56 return newContainer;
57 }
58 ++elementReferenceCount;
59 return this;
60 }
61
62 virtual void DecElementRef() override
63 {
64 assert(elementReferenceCount);
65 --elementReferenceCount;
66 }
67
68protected:
69 size_t GetRefCount()
70 {
71 return referenceCount;
72 }
73};
74