MCRO
C++23 utilities for Unreal Engine.
Toggle main menu visibility
Main Page
Related Pages
Namespaces
Namespace List
Namespace Members
All
a
c
d
e
f
g
h
i
j
l
m
n
o
p
r
s
t
u
w
z
Functions
a
c
d
e
f
g
h
i
j
l
m
n
o
p
r
s
t
u
w
z
Variables
Typedefs
f
i
t
Enumerations
Concepts
Data Structures
Data Structures
Data Structure Index
Class Hierarchy
Data Fields
All
a
b
c
d
e
f
g
h
i
m
n
o
p
r
s
t
v
w
~
Functions
a
b
c
d
e
f
g
h
i
m
n
o
p
r
s
t
w
~
Variables
a
b
c
d
e
f
h
i
m
n
o
p
r
s
t
v
w
Typedefs
a
c
d
e
f
i
m
p
r
s
t
v
w
Enumerations
Enumerator
Related Symbols
o
Files
File List
Globals
All
_
a
b
d
e
f
g
h
i
l
m
n
o
p
s
t
u
w
Functions
b
d
e
g
i
o
s
Typedefs
Macros
_
a
e
f
h
i
l
m
n
p
s
t
u
w
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
Concepts
Loading...
Searching...
No Matches
FmtMacros.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 `FMT_` or trailing `_FMT` fake text literals to create modern formatted strings with a better API.
16
*
17
* The major difference from `PRINTF_` or `FString::Printf(...)` is that `FMT` macros can take user defined string
18
* conversions into account, so more types can be used directly as arguments.
19
*/
20
21
#pragma once
22
23
#include <string>
24
25
#include "CoreMinimal.h"
26
#include "
Mcro/Text.h
"
27
#include "
Mcro/TextMacros.h
"
28
#include "
Mcro/Enums.h
"
29
#include "
Mcro/Macros.h
"
30
31
template
<
size_t
N>
32
FString
operator %
(FStringFormatOrderedArguments&& args,
const
TCHAR(& format)[N])
33
{
34
FString result = FString::Format(format, args);
35
result.TrimToNullTerminator();
36
return
result;
37
}
32
FString
operator %
(FStringFormatOrderedArguments&& args,
const
TCHAR(& format)[N]) {
…
}
38
39
template
<
size_t
N>
40
FString
operator %
(
const
TCHAR(& format)[N], FStringFormatOrderedArguments&& args)
41
{
42
FString result = FString::Format(format, args);
43
result.TrimToNullTerminator();
44
return
result;
45
}
40
FString
operator %
(
const
TCHAR(& format)[N], FStringFormatOrderedArguments&& args) {
…
}
46
47
template
<
size_t
N>
48
FString
operator %
(FStringFormatNamedArguments&& args,
const
TCHAR(& format)[N])
49
{
50
FString result = FString::Format(format, args);
51
result.TrimToNullTerminator();
52
return
result;
53
}
48
FString
operator %
(FStringFormatNamedArguments&& args,
const
TCHAR(& format)[N]) {
…
}
54
55
template
<
size_t
N>
56
FString
operator %
(
const
TCHAR(& format)[N], FStringFormatNamedArguments&& args)
57
{
58
FString result = FString::Format(format, args);
59
result.TrimToNullTerminator();
60
return
result;
61
}
56
FString
operator %
(
const
TCHAR(& format)[N], FStringFormatNamedArguments&& args) {
…
}
62
63
#define MCRO_FMT_NAMED_ARG_TRANSFORM(s, data, elem) BOOST_PP_EXPAND(MCRO_FMT_NAMED_ARG elem)
64
#define MCRO_FMT_NAMED_ARG(key, value) MakeTuple(FString(TEXT(#key)), value)
65
66
#define MCRO_FMT_NAMED(seq) \
67
BOOST_PP_IIF(BOOST_PP_IS_BEGIN_PARENS(seq), \
68
MCRO_FMT_NAMED_0, \
69
BOOST_PP_IDENTITY_N(, 1) \
70
)(seq)
//
66
#define MCRO_FMT_NAMED(seq) \
…
71
72
#define MCRO_FMT_NAMED_0(seq) \
73
Mcro::Text::NamedArguments( \
74
BOOST_PP_SEQ_ENUM( \
75
BOOST_PP_SEQ_TRANSFORM( \
76
MCRO_FMT_NAMED_ARG_TRANSFORM, , \
77
BOOST_PP_VARIADIC_SEQ_TO_SEQ(seq) \
78
) \
79
) \
80
)
//
72
#define MCRO_FMT_NAMED_0(seq) \
…
81
82
#define MCRO_FMT_ORDERED(...) Mcro::Text::OrderedArguments(__VA_ARGS__)
83
84
#define MCRO_FMT_ARGS(...) \
85
BOOST_PP_IIF(BOOST_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
86
MCRO_FMT_NAMED(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)), \
87
MCRO_FMT_ORDERED(__VA_ARGS__) \
88
)
//
84
#define MCRO_FMT_ARGS(...) \
…
89
90
/**
91
* @brief
92
* Leading fake text literal which makes using `FString::Format(...);` much more comfortable.
93
*
94
* `FMT` macros allow more types to be used directly in the format arguments expression because `Mcro::Text` has
95
* a couple of conversion utilities. If the first argument of `FMT_` is a sequence of `("key", value)` pairs enclosed
96
* in parentheses, then named format arguments are assumed. Ordered format arguments are assumed otherwise. The two
97
* modes cannot be mixed.
98
*
99
* Usage:
100
* @code
101
* EPixelFormat format = PF_Unknown; int32 num = 42;
102
*
103
* FString ordered = FMT_(format, num) "Hi {0}, your number is {1}";
104
* // -> "Hi PF_Unknown, your number is 42"
105
*
106
* // | Notice the lack of comma here
107
* // V
108
* FString named = FMT_((Type, format) (Count, num)) "Hi {Type}, your number is {Count}";
109
* // -> "Hi PF_Unknown, your number is 42"
110
* @endcode
111
*
112
* The following argument types are supported out-of-box:
113
* - Originally supported by `FStringFormatArg` and what's implicitly convertable to
114
* - `FString, FStringView, int32, uint32, int64, uint64, float, double`
115
* - `ANSICHAR, WIDECHAR, UCS2CHAR, UTF8CHAR` pointer strings
116
* - Anything which has a `ToString()` member method which produces one of the above type
117
* - Including but not exclusively `FText` and `FName` for example
118
* - STL strings and views of any encoding
119
* - Enums where their entries are serialized as human-readable names
120
*
121
* @remarks
122
* To add more supported types specialize the `TAsFormatArgument` template functor for your preferred type and return
123
* a value which is implicitly convertible to `FStringFormatArg` in the `Mcro::Text` namespace. For example check
124
* `Enums.h` to see how that's done with enums. For your own types you can also implement a `ToString()` member
125
* method to get automatic support.
126
*
127
* @warning
128
* The **named arguments** overload (`FMT_((A, a) (B, b) (C, c))`) must not have comma `,` between the individual
129
* pairs. This is because named argument pairs are passed into this macro as a "sequence" instead of variadic arguments.
130
* Ordered format arguments however should be passed in as regular variadic arguments separated by comma `,` as
131
* nature intended.
132
*
133
* @note
134
* `FMT` macros are the only things in MCRO where excessive preprocessing is used
135
*/
136
#define FMT_(...) MCRO_FMT_ARGS(__VA_ARGS__) % TEXT_
137
138
/**
139
* @brief
140
* Trailing fake text literal which makes using `FString::Format(...);` much more comfortable.
141
*
142
* `FMT` macros allow more types to be used directly in the format arguments expression because `Mcro::Text` has
143
* a couple of conversion utilities. If the first argument of `_FMT` is a sequence of `("key", value)` pairs enclosed
144
* in parentheses, then named format arguments are assumed. Ordered format arguments are assumed otherwise. The two
145
* modes cannot be mixed.
146
*
147
* Usage:
148
* @code
149
* EPixelFormat format = PF_Unknown; int32 num = 42;
150
*
151
* FString ordered = TEXT_"Hi {0}, your number is {1}" _FMT(format, num);
152
* // -> "Hi PF_Unknown, your number is 42" ^ this space is important
153
*
154
* // Named arguments look better with multiple lines on this version
155
* FString named = TEXT_"Hi {Type}, your number is {Count}" _FMT(
156
* (Type, format) // <- Notice the lack of comma here ^ this space is important
157
* (Count, num)
158
* );
159
* // -> "Hi PF_Unknown, your number is 42"
160
* @endcode
161
*
162
* The following argument types are supported out-of-box:
163
* - Originally supported by `FStringFormatArg` and what's implicitly convertable to
164
* - `FString, FStringView, int32, uint32, int64, uint64, float, double`
165
* - `ANSICHAR, WIDECHAR, UCS2CHAR, UTF8CHAR` pointer strings
166
* - Anything which has a `ToString()` member method which produces one of the above type
167
* - Including but not exclusively `FText` and `FName` for example
168
* - STL strings and views of any encoding
169
* - Enums where their entries are serialized as human-readable names
170
*
171
* @remarks
172
* To add more supported types specialize the `TAsFormatArgument` template functor for your preferred type and return
173
* a value which is implicitly convertible to `FStringFormatArg` in the `Mcro::Text` namespace. For example check
174
* `Enums.h` to see how that's done with enums. For your own types you can also implement a `ToString()` member
175
* method to get automatic support.
176
*
177
* @warning
178
* The **named arguments** overload (`_FMT((A, a) (B, b) (C, c))`) must not have comma `,` between the individual
179
* pairs. This is because named argument pairs are passed into this macro as a "sequence" instead of variadic arguments.
180
* Ordered format arguments however should be passed in as regular variadic arguments separated by comma `,` as
181
* nature intended.
182
*
183
* @note
184
* `FMT` macros are the only things in MCRO where excessive preprocessing is used
185
*/
186
#define _FMT(...) % MCRO_FMT_ARGS(__VA_ARGS__)
Enums.h
operator%
FString operator%(FStringFormatOrderedArguments &&args, const TCHAR(&format)[N])
Definition
FmtMacros.h:32
Macros.h
TextMacros.h
Use leading TEXT_ without parenthesis for Unreal compatible text literals.
Text.h
Mcro_Origin
Public
Mcro
FmtMacros.h
Generated by
1.12.0