1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 2020-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 <cstddef>
19#include <cstdint>
20#include <type_traits>
21
22class C4Object;
23class StdCompiler;
24
25class C4EnumeratedObjectPtr
26{
27public:
28 using Enumerated = std::int32_t;
29
30private:
31 C4Object *object{};
32 Enumerated number{};
33
34public:
35 C4EnumeratedObjectPtr() = default;
36 C4EnumeratedObjectPtr(const C4EnumeratedObjectPtr &) = default;
37 C4EnumeratedObjectPtr(C4EnumeratedObjectPtr &&) = default;
38 explicit C4EnumeratedObjectPtr(C4Object *object) : object{object} {}
39
40 constexpr C4Object *operator->() const noexcept { return Object(); }
41 constexpr C4Object *operator*() const noexcept { return Object(); }
42 constexpr C4Object *Object() const noexcept { return object; }
43 constexpr Enumerated Number() const noexcept { return number; }
44 constexpr operator C4Object *() const noexcept { return Object(); }
45
46 C4EnumeratedObjectPtr &operator=(const C4EnumeratedObjectPtr &) = default;
47 C4EnumeratedObjectPtr &operator=(C4EnumeratedObjectPtr &&) = default;
48 constexpr C4EnumeratedObjectPtr &operator=(C4Object *obj) noexcept
49 {
50 object = obj;
51 return *this;
52 }
53 constexpr C4EnumeratedObjectPtr &operator=(std::nullptr_t) noexcept
54 {
55 Reset();
56 return *this;
57 }
58
59 constexpr void Reset() noexcept
60 {
61 object = nullptr;
62 number = {};
63 }
64 constexpr void SetNumber(Enumerated enumerated) noexcept
65 {
66 number = enumerated;
67 }
68
69 void Enumerate();
70 void Denumerate();
71
72 void CompileFunc(StdCompiler *compiler, bool intPack = false);
73};
74
75namespace
76{
77 template<typename... Args>
78 constexpr void CheckArgs(Args &...args) noexcept
79 {
80 static_assert(sizeof...(args) > 0, "At least one argument is required");
81 static_assert((std::is_same_v<Args, C4EnumeratedObjectPtr> && ...), "Only C4EnumeratedObjectPtr& can be passed as arguments");
82 }
83}
84
85template<typename... Args>
86void EnumerateObjectPtrs(Args &...args)
87{
88 CheckArgs(args...);
89 (args.Enumerate(), ...);
90}
91
92template<typename... Args>
93void DenumerateObjectPtrs(Args &...args)
94{
95 CheckArgs(args...);
96 (args.Denumerate(), ...);
97}
98