1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16
17/* Load strings from a primitive memory string table */
18
19#pragma once
20
21#include "generated/C4ResStrTableGenerated.h"
22
23#include <string>
24#include <string_view>
25#include <unordered_map>
26#include <utility>
27
28#include <fmt/printf.h>
29
30template<typename... Args>
31struct C4ResStrTableKeyFormat
32{
33 consteval C4ResStrTableKeyFormat(const C4ResStrTableKey id) : Id{id}
34 {
35 if (sizeof...(Args) != C4ResStrTableKeyFormatStringArgsCount[std::to_underlying(value: id)])
36 {
37 throw id;
38 }
39 }
40
41 C4ResStrTableKey Id;
42};
43
44const char *LoadResStrV(C4ResStrTableKey id);
45std::string LoadResStrNoAmpV(C4ResStrTableKey id);
46
47template<typename... Args>
48std::string LoadResStr(const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> id, Args &&...args)
49{
50 return fmt::sprintf(LoadResStrV(id.Id), std::forward<Args>(args)...);
51}
52
53inline const char *LoadResStr(const C4ResStrTableKeyFormat<> id)
54{
55 return LoadResStrV(id: id.Id);
56}
57
58template<typename... Args>
59std::string LoadResStrChoice(const bool condition, const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> ifTrue, const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> ifFalse, Args &&...args)
60{
61 return fmt::sprintf(LoadResStrV(condition ? ifTrue.Id : ifFalse.Id), std::forward<Args>(args)...);
62}
63
64inline const char *LoadResStrChoice(const bool condition, const C4ResStrTableKeyFormat<> ifTrue, const C4ResStrTableKeyFormat<> ifFalse)
65{
66 return LoadResStrV(id: condition ? ifTrue.Id : ifFalse.Id);
67}
68
69template<typename... Args>
70std::string LoadResStrNoAmp(const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> id, Args &&...args)
71{
72 return fmt::sprintf(LoadResStrNoAmpV(id.Id), std::forward<Args>(args)...);
73}
74
75inline std::string LoadResStrNoAmp(const C4ResStrTableKeyFormat<> id)
76{
77 return LoadResStrNoAmpV(id: id.Id);
78}
79
80template<typename... Args>
81std::string LoadResStrNoAmpChoice(const bool condition, const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> ifTrue, const C4ResStrTableKeyFormat<std::type_identity_t<Args>...> ifFalse, Args &&...args)
82{
83 return fmt::sprintf(LoadResStrNoAmpV(condition ? ifTrue.Id : ifFalse.Id), std::forward<Args>(args)...);
84}
85
86inline std::string LoadResStrNoAmpChoice(const bool condition, const C4ResStrTableKeyFormat<> ifTrue, const C4ResStrTableKeyFormat<> ifFalse)
87{
88 return LoadResStrNoAmpV(id: condition ? ifTrue.Id : ifFalse.Id);
89}
90
91class C4ResStrTable
92{
93public:
94 C4ResStrTable(std::string_view code, std::string_view table);
95
96public:
97 std::string_view GetEntry(C4ResStrTableKey key) const;
98
99private:
100 static std::unordered_map<std::string_view, C4ResStrTableKey> GetKeyStringMap();
101
102private:
103 std::array<std::string, static_cast<std::size_t>(C4ResStrTableKey::NumberOfEntries)> entries;
104};
105