Skip to content

Commit cd4a85c

Browse files
committed
Move replacement fields into the standard formatters
Rather than storing a reference to the replacement field in the format context, just pass it into the formatters.
1 parent cc22d1b commit cd4a85c

File tree

5 files changed

+226
-117
lines changed

5 files changed

+226
-117
lines changed

fly/types/string/detail/format_context.hpp

-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include "fly/types/string/detail/format_parameters.hpp"
4-
#include "fly/types/string/detail/format_specifier.hpp"
54

65
#include <cstddef>
76

@@ -18,7 +17,6 @@ template <typename OutputIterator, typename CharType>
1817
class BasicFormatContext
1918
{
2019
using FormatParameter = BasicFormatParameter<BasicFormatContext>;
21-
using FormatSpecifier = BasicFormatSpecifier<CharType>;
2220

2321
public:
2422
using char_type = CharType;
@@ -49,11 +47,6 @@ class BasicFormatContext
4947
*/
5048
OutputIterator &out();
5149

52-
/**
53-
* @return The formatting replacement field currently being used for formatting.
54-
*/
55-
FormatSpecifier &spec();
56-
5750
private:
5851
BasicFormatContext(const BasicFormatContext &) = delete;
5952
BasicFormatContext &operator=(const BasicFormatContext &) = delete;
@@ -62,8 +55,6 @@ class BasicFormatContext
6255

6356
const FormatParameter *m_parameters;
6457
const std::size_t m_parameters_size;
65-
66-
FormatSpecifier m_specifier {};
6758
};
6859

6960
//==================================================================================================
@@ -98,11 +89,4 @@ inline OutputIterator &BasicFormatContext<OutputIterator, CharType>::out()
9889
return m_out;
9990
}
10091

101-
//==================================================================================================
102-
template <typename OutputIterator, typename CharType>
103-
inline auto BasicFormatContext<OutputIterator, CharType>::spec() -> FormatSpecifier &
104-
{
105-
return m_specifier;
106-
}
107-
10892
} // namespace fly::detail

fly/types/string/detail/format_parameters.hpp

+57-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "fly/types/string/detail/classifier.hpp"
4+
#include "fly/types/string/detail/format_specifier.hpp"
45
#include "fly/types/string/detail/string_traits.hpp"
56
#include "fly/types/string/string_formatters.hpp"
67

@@ -39,7 +40,11 @@ struct StringValue
3940
const void *m_value;
4041
std::size_t m_size;
4142

42-
void (*m_format)(const void *value, std::size_t size, FormatContext &context);
43+
void (*m_format)(
44+
const void *value,
45+
std::size_t size,
46+
FormatContext &context,
47+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier);
4348
};
4449

4550
/**
@@ -59,7 +64,10 @@ struct StandardValue
5964
bool m_bool;
6065
};
6166

62-
void (*m_format)(StandardValue value, FormatContext &context);
67+
void (*m_format)(
68+
StandardValue value,
69+
FormatContext &context,
70+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier);
6371
};
6472

6573
/**
@@ -83,9 +91,14 @@ void format_user_defined_value(const void *value, FormatContext &context);
8391
* @param value A pointer to the type-erased string to format.
8492
* @param size The size of the string to format.
8593
* @param context The context holding the formatting state.
94+
* @param specifier The replacement field to be replaced.
8695
*/
8796
template <typename FormatContext, typename T>
88-
void format_string_value(const void *value, std::size_t size, FormatContext &context);
97+
void format_string_value(
98+
const void *value,
99+
std::size_t size,
100+
FormatContext &context,
101+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier);
89102

90103
/**
91104
* Re-form a type-erased standard value and format that value.
@@ -95,9 +108,13 @@ void format_string_value(const void *value, std::size_t size, FormatContext &con
95108
*
96109
* @param value The container holding the type-erased value.
97110
* @param context The context holding the formatting state.
111+
* @param specifier The replacement field to be replaced.
98112
*/
99113
template <typename FormatContext, typename T>
100-
void format_standard_value(StandardValue<FormatContext> value, FormatContext &context);
114+
void format_standard_value(
115+
StandardValue<FormatContext> value,
116+
FormatContext &context,
117+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier);
101118

102119
/**
103120
* A container to hold a single type-erased format parameter.
@@ -108,6 +125,8 @@ void format_standard_value(StandardValue<FormatContext> value, FormatContext &co
108125
template <typename FormatContext>
109126
class BasicFormatParameter
110127
{
128+
using char_type = typename FormatContext::char_type;
129+
111130
public:
112131
/**
113132
* Constructor. Initialize the format parameter to an invalid state.
@@ -169,8 +188,10 @@ class BasicFormatParameter
169188
* Apply the type-erased formatting function to the stored format parameter.
170189
*
171190
* @param context The context holding the formatting state.
191+
* @param specifier The replacement field to be replaced.
172192
*/
173-
constexpr void format(FormatContext &context) const;
193+
constexpr void
194+
format(FormatContext &context, BasicFormatSpecifier<char_type> &&specifier) const;
174195

175196
/**
176197
* Apply the provided visitor to the stored format parameter.
@@ -265,19 +286,28 @@ inline void format_user_defined_value(const void *value, FormatContext &context)
265286

266287
//==================================================================================================
267288
template <typename FormatContext, typename T>
268-
inline void format_string_value(const void *value, std::size_t size, FormatContext &context)
289+
inline void format_string_value(
290+
const void *value,
291+
std::size_t size,
292+
FormatContext &context,
293+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier)
269294
{
270-
static_assert(detail::is_supported_character_v<T>);
295+
using view_type = std::basic_string_view<T>;
296+
297+
Formatter<view_type, typename FormatContext::char_type> formatter(std::move(specifier));
271298

272-
std::basic_string_view<T> view(static_cast<const T *>(value), size);
273-
Formatter<decltype(view), typename FormatContext::char_type>().format(view, context);
299+
view_type view(static_cast<const T *>(value), size);
300+
formatter.format(view, context);
274301
}
275302

276303
//==================================================================================================
277304
template <typename FormatContext, typename T>
278-
inline void format_standard_value(StandardValue<FormatContext> value, FormatContext &context)
305+
inline void format_standard_value(
306+
StandardValue<FormatContext> value,
307+
FormatContext &context,
308+
BasicFormatSpecifier<typename FormatContext::char_type> &&specifier)
279309
{
280-
Formatter<T, typename FormatContext::char_type> formatter {};
310+
Formatter<T, typename FormatContext::char_type> formatter(std::move(specifier));
281311

282312
if constexpr (BasicFormatTraits::is_pointer_v<T>)
283313
{
@@ -347,25 +377,25 @@ constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter(const
347377
{
348378
using U = std::remove_cvref_t<T>;
349379

350-
using string_type = fly::detail::is_like_supported_string_t<T>;
351-
using char_type = typename string_type::value_type;
352-
using view_type = typename fly::detail::BasicStringTraits<char_type>::view_type;
380+
using string_like_type = fly::detail::is_like_supported_string_t<T>;
381+
using char_like_type = typename string_like_type::value_type;
382+
using view_like_type = typename fly::detail::BasicStringTraits<char_like_type>::view_type;
353383

354-
view_type view;
384+
view_like_type view;
355385

356386
if constexpr (std::is_array_v<U> || std::is_pointer_v<U>)
357387
{
358-
view = view_type(value, BasicClassifier<char_type>::size(value));
388+
view = view_like_type(value, BasicClassifier<char_like_type>::size(value));
359389
}
360390
else
361391
{
362-
view = view_type(value);
392+
view = view_like_type(value);
363393
}
364394

365395
m_value.m_string = {
366396
static_cast<const void *>(view.data()),
367397
view.size(),
368-
format_string_value<FormatContext, char_type>};
398+
format_string_value<FormatContext, char_like_type>};
369399
}
370400

371401
//==================================================================================================
@@ -426,15 +456,21 @@ constexpr inline BasicFormatParameter<FormatContext>::BasicFormatParameter(T val
426456

427457
//==================================================================================================
428458
template <typename FormatContext>
429-
constexpr inline void BasicFormatParameter<FormatContext>::format(FormatContext &context) const
459+
constexpr inline void BasicFormatParameter<FormatContext>::format(
460+
FormatContext &context,
461+
BasicFormatSpecifier<char_type> &&specifier) const
430462
{
431463
switch (m_type)
432464
{
433465
case Type::UserDefined:
434466
m_value.m_user_defined.m_format(m_value.m_user_defined.m_value, context);
435467
break;
436468
case Type::String:
437-
m_value.m_string.m_format(m_value.m_string.m_value, m_value.m_string.m_size, context);
469+
m_value.m_string.m_format(
470+
m_value.m_string.m_value,
471+
m_value.m_string.m_size,
472+
context,
473+
std::move(specifier));
438474
break;
439475
case Type::Pointer:
440476
case Type::SignedInt:
@@ -443,7 +479,7 @@ constexpr inline void BasicFormatParameter<FormatContext>::format(FormatContext
443479
case Type::Double:
444480
case Type::LongDouble:
445481
case Type::Bool:
446-
m_value.m_standard.m_format(m_value.m_standard, context);
482+
m_value.m_standard.m_format(m_value.m_standard, context, std::move(specifier));
447483
break;
448484
default:
449485
break;

fly/types/string/string.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,11 @@ auto BasicString<CharType>::format(
882882
}
883883
else
884884
{
885-
context.spec() = *std::move(fmt.next_specifier());
886-
pos += context.spec().m_size;
885+
auto specifier = *std::move(fmt.next_specifier());
886+
pos += specifier.m_size;
887887

888-
const auto parameter = context.arg(context.spec().m_position);
889-
parameter.format(context);
888+
const auto parameter = context.arg(specifier.m_position);
889+
parameter.format(context, std::move(specifier));
890890
}
891891
break;
892892

0 commit comments

Comments
 (0)