MCRO
C++23 utilities for Unreal Engine.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
TextMacros.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12/**
13 * @file
14 * @brief
15 * Use leading `TEXT_` without parenthesis for Unreal compatible text literals.
16 */
17
18#pragma once
19
20#include <string>
21
22#include "CoreMinimal.h"
23#include "Mcro/FunctionTraits.h"
24
25#define UTF8TEXT_PASTE_ u8""
26#define UTF16TEXT_PASTE_ u""
27
28#if PLATFORM_WIDECHAR_IS_CHAR16
29 #define WIDETEXT_PASTE_ UTF16TEXT_PASTE_
30#else
31 #define WIDETEXT_PASTE_ L""
32#endif
33
34#define UTF8TEXT_ UTF8TEXT_PASTE_ // TODO: UE::Core::Private::ToUTF8Literal with operator?
35#define UTF16TEXT_ UTF16TEXT_PASTE_
36#define WIDETEXT_ WIDETEXT_PASTE_
37
38#if PLATFORM_TCHAR_IS_UTF8CHAR
39 #define TEXT_PASTE_ UTF8TEXT_
40#else
41 #define TEXT_PASTE_ WIDETEXT_
42#endif
43
44/**
45 * @brief
46 * A convenience alternative to Unreal's own `TEXT` macro but this one doesn't require parenthesis around the text
47 * literal, relying on string literal concatenation rules of C++.
48 *
49 * This operation is resolved entirely in compile time
50 */
51#define TEXT_ TEXT_PASTE_
52
53/** @brief This namespace is used by MCRO text literal macros, don't use it directly! */
55{
56 using namespace Mcro::FunctionTraits;
57
58 FORCEINLINE FText AsLocalizable_Advanced(const FTextKey& Namespace, const FTextKey& Key, const TCHAR* String)
59 {
60 return FText::AsLocalizable_Advanced(Namespace, Key, String);
61 }
63 {
64 FORCEINLINE FText operator % (const TCHAR* literal)
65 {
66 return (*this)(literal);
67 }
68 };
69
71 {
72 FORCEINLINE FText operator % (const TCHAR* str) const
73 {
74 return FText::AsCultureInvariant(str);
75 }
76 };
77
79 {
80 template <size_t N>
81 consteval FStringView operator % (const TCHAR(& str)[N]) const
82 {
83 return FStringView(str, N-1);
84 }
85 };
86
88 {
89 template <size_t N>
90 FString operator % (const TCHAR(& str)[N]) const
91 {
92 return FString::ConstructFromPtrSize(str, N-1);
93 }
94 };
95
97 {
98 template <size_t N>
99 FName operator % (const TCHAR(& str)[N]) const
100 {
101 return FName(N-1, str);
102 }
103 };
104
106 {
107 template <size_t N>
108 consteval std::basic_string_view<TCHAR> operator % (const TCHAR(& str)[N]) const
109 {
110 return std::basic_string_view<TCHAR>(str, N-1);
111 }
112 };
113
114 template <typename... Args>
116 {
117 using Arguments = TTuple<Args...>;
118 TStringPrintfLiteral(Args&&... args) : Storage(Forward<Args>(args)...) {}
119
120 private:
121 template <size_t CharN, size_t... Sequence>
122 FString Invoke_Impl(const TCHAR(& format)[CharN], std::index_sequence<Sequence...>&&)
123 {
124 return FString::Printf(
125 format,
126 Forward<
127 typename TTupleElement<Sequence, Arguments>::Type
128 >(
129 Storage.template Get<Sequence>()
130 )...
131 );
132 }
133
134 public:
135 template <size_t CharN>
136 FString Invoke(const TCHAR(& format)[CharN])
137 {
138 return Invoke_Impl(format, std::make_index_sequence<sizeof...(Args)>());
139 }
140
141 template <size_t N>
142 friend FString operator % (const TCHAR(& format)[N], TStringPrintfLiteral&& tag)
143 {
144 return tag.Invoke(format);
145 }
146
147 template <size_t N>
148 friend FString operator % (TStringPrintfLiteral&& tag, const TCHAR(& format)[N])
149 {
150 return tag.Invoke(format);
151 }
152
154 };
155
156 template <typename... Args>
158 {
159 return TStringPrintfLiteral<Args...>(Forward<Args>(args)...);
160 }
161}
162
163/**
164 * @brief
165 * A convenience alternative to Unreal's own `LOCTEXT` macro but this one doesn't require parenthesis around the text
166 * literal
167 *
168 * This operation allocates an argument deferring struct and FText in runtime
169 */
170#define LOCTEXT_(key) \
171 Mcro::Text::Macros::FDefer_AsLocalizable_Advanced(TEXT(LOCTEXT_NAMESPACE), TEXT(key)) % TEXT_
172
173/**
174 * @brief
175 * A convenience alternative to Unreal's own `NSLOCTEXT` macro but this one doesn't require parenthesis around the text
176 * literal
177 *
178 * This operation allocates an argument deferring struct and FText in runtime
179 */
180#define NSLOCTEXT_(ns, key) \
181 Mcro::Text::Macros::FDefer_AsLocalizable_Advanced(TEXT(ns), TEXT(key)) % TEXT_
182
183/**
184 * @brief
185 * A convenience alternative to Unreal's own `INVTEXT` macro but this one doesn't require parenthesis around the text
186 * literal
187 *
188 * This operation allocates FText in runtime and an empty tag struct
189 */
190#define INVTEXT_ \
191 Mcro::Text::Macros::FInvTextFakeLiteralTag() % TEXT_
192
193/**
194 * @brief
195 * A convenience alternative to Unreal's own `TEXTVIEW` macro but this one doesn't require parenthesis around the text
196 * literal.
197 *
198 * This operation creates an FStringView in consteval time. This is not a custom string literal because they're not
199 * available for concatenated groups of string literals of mixed encodings.
200 */
201#define TEXTVIEW_ Mcro::Text::Macros::FStringViewFakeLiteralTag() % TEXT_
202
203/**
204 * @brief
205 * A convenience alternative to Unreal's own `TEXTVIEW` macro but this one doesn't require parenthesis around the text
206 * literal and it returns an STL string view.
207 *
208 * This operation creates a `std::[w]string_view` in consteval time. This is not a custom string literal because
209 * they're not available for concatenated groups of string literals of mixed encodings.
210 */
211#define STDVIEW_ Mcro::Text::Macros::FStdStringLiteralTag() % TEXT_
212
213/**
214 * @brief
215 * A convenience macro to allocate an FString directly.
216 *
217 * This operation allocates FString in runtime and an empty tag struct. This is not a custom string literal because
218 * they're not available for concatenated groups of string literals of mixed encodings.
219 */
220#define STRING_ Mcro::Text::Macros::FStringFakeLiteralTag() % TEXT_
221
222/**
223 * @brief
224 * A convenience macro to allocate an FName directly.
225 *
226 * This operation allocates FName in runtime and an empty tag struct. This is not a custom string literal because
227 * they're not available for concatenated groups of string literals of mixed encodings.
228 */
229#define NAME_ Mcro::Text::Macros::FNameFakeLiteralTag() % TEXT_
230
231/**
232 * @brief
233 * Trailing fake text literal which shortens down the `FString::Printf(TEXT("..."), ...);` expression.
234 *
235 * Usage:
236 * @code
237 * int count, FString type;
238 * TEXT_"My format literal with %d and %s" _PRINTF(count, type);
239 * // ^ this space is important
240 * @endcode
241 *
242 * This operation runs `FString::Printf` in runtime and allocates a struct which stores the format arguments
243 * (preserving CV-ref qualifiers).
244 */
245#define _PRINTF(...) % Mcro::Text::Macros::MakePrintfLiteral(__VA_ARGS__)
246
247/**
248 * @brief
249 * Leading fake text literal which shortens down the `FString::Printf(TEXT("..."), ...);` expression.
250 *
251 * Usage:
252 * @code
253 * int count, FString type;
254 * PRINTF_(count, type) "My format literal with %d and %s";
255 * // ^ this space is optional
256 * @endcode
257 *
258 * This operation runs `FString::Printf` in runtime and allocates a struct which stores the format arguments
259 * (preserving CV-ref qualifiers).
260 */
261#define PRINTF_(...) Mcro::Text::Macros::MakePrintfLiteral(__VA_ARGS__) % TEXT_
This namespace is used by MCRO text literal macros, don't use it directly!
Definition TextMacros.h:55
FORCEINLINE FText AsLocalizable_Advanced(const FTextKey &Namespace, const FTextKey &Key, const TCHAR *String)
Definition TextMacros.h:58
TStringPrintfLiteral< Args... > MakePrintfLiteral(Args &&... args)
Definition TextMacros.h:157
Defers a set of arguments for a function call later with its first argument. This is useful for devel...
FORCEINLINE FText operator%(const TCHAR *literal)
Definition TextMacros.h:64
FORCEINLINE FText operator%(const TCHAR *str) const
Definition TextMacros.h:72
FName operator%(const TCHAR(&str)[N]) const
Definition TextMacros.h:99
consteval std::basic_string_view< TCHAR > operator%(const TCHAR(&str)[N]) const
Definition TextMacros.h:108
FString operator%(const TCHAR(&str)[N]) const
Definition TextMacros.h:90
consteval FStringView operator%(const TCHAR(&str)[N]) const
Definition TextMacros.h:81
FString Invoke(const TCHAR(&format)[CharN])
Definition TextMacros.h:136
friend FString operator%(const TCHAR(&format)[N], TStringPrintfLiteral &&tag)
Definition TextMacros.h:142