Skip to content

Commit b199cb5

Browse files
committed
Add better documentation, and fix some floating point flag stuff
1 parent 6355735 commit b199cb5

File tree

3 files changed

+99
-55
lines changed

3 files changed

+99
-55
lines changed

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,7 @@ INCLUDE_FILE_PATTERNS =
15881588
# undefined via #undef or recursively expanded use the := operator
15891589
# instead of the = operator.
15901590

1591-
PREDEFINED =
1591+
PREDEFINED = BUILDING_DOXYGEN
15921592

15931593
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
15941594
# this tag can be used to specify a list of macro names that should be expanded.

Sources/Plasma/CoreLib/plFormat.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Mead, WA 99021
5050

5151
namespace plFormat_Private
5252
{
53-
static const char *_scanNextFormat(IFormatDataObject &data)
53+
static const char *_scanNextFormat(_IFormatDataObject &data)
5454
{
5555
hsAssert(data.fFormatStr, "Passed a null format string!");
5656

@@ -64,7 +64,7 @@ namespace plFormat_Private
6464
return ptr;
6565
}
6666

67-
static void _fetchPrefixChunk(IFormatDataObject &data)
67+
static void _fetchPrefixChunk(_IFormatDataObject &data)
6868
{
6969
do {
7070
const char *next = _scanNextFormat(data);
@@ -81,7 +81,7 @@ namespace plFormat_Private
8181
} while (0);
8282
}
8383

84-
FormatSpec FetchNextFormat(IFormatDataObject &data)
84+
FormatSpec _FetchNextFormat(_IFormatDataObject &data)
8585
{
8686
_fetchPrefixChunk(data);
8787
hsAssert(*data.fFormatStr == '{', "Too many actual parameters for format string");
@@ -135,13 +135,13 @@ namespace plFormat_Private
135135
spec.fDigitClass = kDigitChar;
136136
break;
137137
case 'f':
138-
spec.fFloatClass = kFloatF;
139-
break;
140-
case 'g':
141-
spec.fFloatClass = kFloatG;
138+
spec.fFloatClass = kFloatFixed;
142139
break;
143140
case 'e':
144-
spec.fFloatClass = kFloatE;
141+
spec.fFloatClass = kFloatExp;
142+
break;
143+
case 'E':
144+
spec.fFloatClass = kFloatExpUpper;
145145
break;
146146
case '0': case '1': case '2': case '3': case '4':
147147
case '5': case '6': case '7': case '8': case '9':
@@ -166,7 +166,7 @@ namespace plFormat_Private
166166
}
167167
}
168168

169-
plString _IFormat(plFormat_Private::IFormatDataObject &data)
169+
plString _IFormat(plFormat_Private::_IFormatDataObject &data)
170170
{
171171
_fetchPrefixChunk(data);
172172
hsAssert(*data.fFormatStr == 0, "Not enough actual parameters for format string");

Sources/Plasma/CoreLib/plFormat.h

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -47,103 +47,147 @@ Mead, WA 99021
4747
#include <list>
4848
#include <string>
4949

50-
/* (TODO: Make this table doxygen-friendly)
50+
#ifdef BUILDING_DOXYGEN // Doxygen doesn't appear to support variadic templates yet
51+
/** Format a string using type-safe arguments
52+
* \param format The format string -- see below for details
5153
*
52-
* FORMAT SPECIFICATION
54+
* Character Sequence | Description
55+
* ------------------ | -----------
56+
* `{}` | Format a value (using defaults)
57+
* `{{` | Escape for a single '{' char
58+
* `{options}` | Format a value, with the specified options (see below)
5359
*
54-
* {} - format a value (defaults)
55-
* {{ - Escape for a single '{' char
56-
* {options} - Format a value, with the specified options (see below)
60+
* Formatting Options
61+
* ------------------
5762
*
58-
* Options:
59-
* < - Align left
60-
* > - Align right
61-
* NNN - Pad to NNN characters (minimum - can be more)
62-
* + - Show a '+' char for positive signed values (decimal only)
63-
* _C - Use C as the pad character (only '\001'..'\177' supported for now)
64-
* x - Hex (lower-case)
65-
* X - Hex (upper-case)
66-
* o - Octal
67-
* b - Binary
68-
* d - Decimal (default) -- when used with char types, outputs a
69-
* number instead of the UTF representation of the char
70-
* c - UTF character (default for character types)
71-
* FFF.EEE - Use FFF.EEE floating point precision
72-
* f - Use 'f' format for floating point numbers
73-
* g - Use 'g' format for floating point numbers
74-
* e - Use 'e' format for floating point numbers
63+
* Format Option | Description
64+
* ------------- | -----------
65+
* `<` | Align left
66+
* `>` | Align right
67+
* `NNN` | Pad to NNN characters (minimum - can be more)
68+
* `+` | Show a '+' char for positive signed values (decimal only)
69+
* `_C` | Use C as the pad character (only '\001'..'\177' supported for now)
70+
* `x` | Hex (lower-case)
71+
* `X` | Hex (upper-case)
72+
* `o` | Octal
73+
* `b` | Binary
74+
* `d` | Decimal (default) -- when used with char types, outputs a number instead of the UTF representation of the char
75+
* `c` | UTF character (default for character types)
76+
* `FFF.EEE` | Use FFF.EEE floating point precision
77+
* `f` | Fixed floating point format (ddd.ddd)
78+
* `e` | Exponent notation for floating point (d.ddde[+/-]dd)
79+
* `E` | Same as 'e' format, but with upper case E (d.dddE[+/-]dd)
7580
*/
81+
plString plFormat(const char *format, ...);
82+
#endif
83+
7684

77-
// For internal use by plFormat and its helper function
7885
namespace plFormat_Private
7986
{
8087
enum Alignment : unsigned char
8188
{
82-
kAlignDefault, kAlignLeft, kAlignRight
89+
kAlignDefault, /**< Left for strings, right for numbers */
90+
kAlignLeft, /**< Left alignment */
91+
kAlignRight /**< Right alignment */
8392
};
8493

8594
enum DigitClass : unsigned char
8695
{
87-
kDigitDefault, kDigitDec, kDigitDecAlwaysSigned,
88-
kDigitHex, kDigitHexUpper, kDigitOct, kDigitBin, kDigitChar
96+
kDigitDefault, /**< Default digit formatting */
97+
kDigitDec, /**< Format as decimal integer */
98+
kDigitDecAlwaysSigned, /**< Same as `kDigitDec`, but include a '+' for positive numbers too */
99+
kDigitHex, /**< Hex integer (assume unsigned) */
100+
kDigitHexUpper, /**< Hex integer with upper-case digits */
101+
kDigitOct, /**< Octal integer (assume unsigned) */
102+
kDigitBin, /**< Binary integer (assume unsigned) */
103+
kDigitChar /**< Single unicode character (as UTF-8) */
89104
};
90105

91106
enum FloatClass : unsigned char
92107
{
93-
kFloatDefault, kFloatE, kFloatF, kFloatG
108+
kFloatDefault, /**< Use Fixed or Exp format depending on value */
109+
kFloatFixed, /**< Use Fixed notation (ddd.ddd) */
110+
kFloatExp, /**< Use Exp notation (d.ddde[+/-]dd) */
111+
kFloatExpUpper /**< Same as `kFloatExp`, but with an upper-case E */
94112
};
95113

114+
/** Represents a parsed format tag, for use in formatter implementations. */
96115
struct FormatSpec
97116
{
98-
int fPrecisionLeft = 0; // Also used for padding
99-
int fPrecisionRight = 0;
117+
int fPrecisionLeft = 0; /**< Requested padding and/or precision */
118+
int fPrecisionRight = 0; /**< Requested precision after the . for floating-point */
100119

101-
char fPadChar = 0;
102-
Alignment fAlignment = kAlignDefault;
103-
DigitClass fDigitClass = kDigitDefault;
104-
FloatClass fFloatClass = kFloatDefault;
120+
char fPadChar = 0; /**< Explicit padding char (default is space) */
121+
Alignment fAlignment = kAlignDefault; /**< Requested pad alignment */
122+
DigitClass fDigitClass = kDigitDefault; /**< Requested int formatting */
123+
FloatClass fFloatClass = kFloatDefault; /**< Requested float formatting */
105124
};
106125

107-
struct IFormatDataObject
126+
// These need to be publically visible for the macros below, but shouldn't
127+
// be used directly outside of plFormat and its macros
128+
struct _IFormatDataObject
108129
{
109130
const char *fFormatStr;
110131
std::list<plStringBuffer<char>> fOutput;
111132
};
112133

113-
extern FormatSpec FetchNextFormat(IFormatDataObject &data);
134+
extern FormatSpec _FetchNextFormat(_IFormatDataObject &data);
114135
}
115136

116-
// Fun fact: You can add your own formatters by declaring
117-
// PL_FORMAT_TYPE(mytype) in a header, and
118-
// PL_FORMAT_IMPL(mytype) { ... } in a source file
119-
137+
/** Declare a formattable type for `plFormat`.
138+
* \sa PL_FORMAT_IMPL()
139+
*/
120140
#define PL_FORMAT_TYPE(_type) \
121141
extern plStringBuffer<char> _impl_plFormat_DataHandler( \
122142
const plFormat_Private::FormatSpec &format, _type value); \
123143
namespace plFormat_Private \
124144
{ \
125145
template <typename... _Args> \
126-
plString _IFormat(IFormatDataObject &data, _type value, _Args... args) \
146+
plString _IFormat(_IFormatDataObject &data, _type value, _Args... args) \
127147
{ \
128-
plFormat_Private::FormatSpec format = plFormat_Private::FetchNextFormat(data); \
148+
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data); \
129149
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value)); \
130150
return _IFormat(data, args...); \
131151
} \
132152
} \
133153
template <typename... _Args> \
134154
plString plFormat(const char *fmt_str, _type value, _Args... args) \
135155
{ \
136-
plFormat_Private::IFormatDataObject data; \
156+
plFormat_Private::_IFormatDataObject data; \
137157
data.fFormatStr = fmt_str; \
138-
plFormat_Private::FormatSpec format = plFormat_Private::FetchNextFormat(data); \
158+
plFormat_Private::FormatSpec format = plFormat_Private::_FetchNextFormat(data); \
139159
data.fOutput.push_back(_impl_plFormat_DataHandler(format, value)); \
140160
return plFormat_Private::_IFormat(data, args...); \
141161
}
142162

163+
/** Provide the implementation for a formattable type for `plFormat`.
164+
* \sa PL_FORMAT_TYPE(), PL_FORMAT_FORWARD()
165+
*
166+
* Example:
167+
*
168+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169+
* PL_FORMAT_IMPL(const MyType &)
170+
* {
171+
* return plFormat("MyType[data={},count={}]", value.data, value.count);
172+
* }
173+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
174+
*/
143175
#define PL_FORMAT_IMPL(_type) \
144176
plStringBuffer<char> _impl_plFormat_DataHandler( \
145177
const plFormat_Private::FormatSpec &format, _type value)
146178

179+
/** Shortcut to call another `PL_FORMAT_IMPL` formatter.
180+
* \sa PL_FORMAT_IMPL()
181+
*
182+
* Example:
183+
*
184+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185+
* PL_FORMAT_IMPL(const MyType &)
186+
* {
187+
* return PL_FORMAT_FORWARD(format, value.ToString());
188+
* }
189+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190+
*/
147191
#define PL_FORMAT_FORWARD(format, fwd_value) \
148192
_impl_plFormat_DataHandler((format), (fwd_value))
149193

@@ -174,10 +218,10 @@ PL_FORMAT_TYPE(const std::wstring &)
174218
// To use other formats, don't pass us a bool directly...
175219
PL_FORMAT_TYPE(bool)
176220

177-
// End of the chain -- emits the last piece (if any) and builds the final string
178221
namespace plFormat_Private
179222
{
180-
plString _IFormat(IFormatDataObject &data);
223+
// End of the chain -- emits the last piece (if any) and builds the final string
224+
plString _IFormat(_IFormatDataObject &data);
181225
}
182226

183227
#endif // plFormat_Defined

0 commit comments

Comments
 (0)