Skip to content

Commit bc09749

Browse files
committed
Change BasicFormatString to be templated on character types
1 parent 3823c4d commit bc09749

File tree

4 files changed

+81
-88
lines changed

4 files changed

+81
-88
lines changed

fly/types/string/detail/format_string.hpp

+30-30
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ namespace fly::detail {
2727
* @author Timothy Flynn ([email protected])
2828
* @version January 3, 2021
2929
*/
30-
template <typename StringType, typename... ParameterTypes>
30+
template <typename CharType, typename... ParameterTypes>
3131
class BasicFormatString
3232
{
33-
using traits = BasicStringTraits<StringType>;
34-
using char_type = typename traits::char_type;
35-
using lexer = fly::BasicLexer<char_type>;
33+
using string_type = std::basic_string<CharType>;
34+
using traits = BasicStringTraits<string_type>;
35+
using lexer = fly::BasicLexer<CharType>;
3636
using view_type = typename traits::view_type;
3737

38-
using FormatSpecifier = BasicFormatSpecifier<char_type>;
38+
using FormatSpecifier = BasicFormatSpecifier<CharType>;
3939

4040
enum class ParameterType : std::uint8_t
4141
{
@@ -59,7 +59,7 @@ class BasicFormatString
5959
* Constructor. Parse and validate a C-string literal as a format string.
6060
*/
6161
template <std::size_t N>
62-
FLY_CONSTEVAL BasicFormatString(const char_type (&format)[N]) noexcept;
62+
FLY_CONSTEVAL BasicFormatString(const CharType (&format)[N]) noexcept;
6363

6464
BasicFormatString(BasicFormatString &&) = default;
6565
BasicFormatString &operator=(BasicFormatString &&) = default;
@@ -91,7 +91,7 @@ class BasicFormatString
9191
std::optional<FormatSpecifier> next_specifier();
9292

9393
private:
94-
friend BasicFormatSpecifier<char_type>;
94+
friend BasicFormatSpecifier<CharType>;
9595

9696
BasicFormatString(const BasicFormatString &) = delete;
9797
BasicFormatString &operator=(const BasicFormatString &) = delete;
@@ -142,9 +142,9 @@ class BasicFormatString
142142
*/
143143
void on_error(const char *error);
144144

145-
static constexpr const auto s_left_brace = FLY_CHR(char_type, '{');
146-
static constexpr const auto s_right_brace = FLY_CHR(char_type, '}');
147-
static constexpr const auto s_colon = FLY_CHR(char_type, ':');
145+
static constexpr const auto s_left_brace = FLY_CHR(CharType, '{');
146+
static constexpr const auto s_right_brace = FLY_CHR(CharType, '}');
147+
static constexpr const auto s_colon = FLY_CHR(CharType, ':');
148148

149149
lexer m_lexer;
150150

@@ -160,13 +160,13 @@ class BasicFormatString
160160
};
161161

162162
//==================================================================================================
163-
template <typename StringType, typename... ParameterTypes>
163+
template <typename CharType, typename... ParameterTypes>
164164
template <std::size_t N>
165-
FLY_CONSTEVAL BasicFormatString<StringType, ParameterTypes...>::BasicFormatString(
166-
const char_type (&format)[N]) noexcept :
165+
FLY_CONSTEVAL BasicFormatString<CharType, ParameterTypes...>::BasicFormatString(
166+
const CharType (&format)[N]) noexcept :
167167
m_lexer(format)
168168
{
169-
std::optional<char_type> ch;
169+
std::optional<CharType> ch;
170170

171171
if constexpr (!(BasicFormatTraits::is_formattable_v<ParameterTypes> && ...))
172172
{
@@ -203,29 +203,29 @@ FLY_CONSTEVAL BasicFormatString<StringType, ParameterTypes...>::BasicFormatStrin
203203
}
204204

205205
//==================================================================================================
206-
template <typename StringType, typename... ParameterTypes>
207-
constexpr auto BasicFormatString<StringType, ParameterTypes...>::view() const -> view_type
206+
template <typename CharType, typename... ParameterTypes>
207+
constexpr auto BasicFormatString<CharType, ParameterTypes...>::view() const -> view_type
208208
{
209209
return m_lexer.view();
210210
}
211211

212212
//==================================================================================================
213-
template <typename StringType, typename... ParameterTypes>
214-
constexpr bool BasicFormatString<StringType, ParameterTypes...>::has_error() const
213+
template <typename CharType, typename... ParameterTypes>
214+
constexpr bool BasicFormatString<CharType, ParameterTypes...>::has_error() const
215215
{
216216
return !m_error.empty();
217217
}
218218

219219
//==================================================================================================
220-
template <typename StringType, typename... ParameterTypes>
221-
std::string BasicFormatString<StringType, ParameterTypes...>::error() const
220+
template <typename CharType, typename... ParameterTypes>
221+
std::string BasicFormatString<CharType, ParameterTypes...>::error() const
222222
{
223223
return std::string(m_error);
224224
}
225225

226226
//==================================================================================================
227-
template <typename StringType, typename... ParameterTypes>
228-
auto BasicFormatString<StringType, ParameterTypes...>::next_specifier()
227+
template <typename CharType, typename... ParameterTypes>
228+
auto BasicFormatString<CharType, ParameterTypes...>::next_specifier()
229229
-> std::optional<FormatSpecifier>
230230
{
231231
if (m_specifier_index >= m_specifier_count)
@@ -237,9 +237,9 @@ auto BasicFormatString<StringType, ParameterTypes...>::next_specifier()
237237
}
238238

239239
//==================================================================================================
240-
template <typename StringType, typename... ParameterTypes>
240+
template <typename CharType, typename... ParameterTypes>
241241
constexpr auto
242-
BasicFormatString<StringType, ParameterTypes...>::parse_specifier(SpecifierType specifier_type)
242+
BasicFormatString<CharType, ParameterTypes...>::parse_specifier(SpecifierType specifier_type)
243243
-> std::optional<FormatSpecifier>
244244
{
245245
// The opening { will have already been consumed, so the starting position is one less.
@@ -299,8 +299,8 @@ BasicFormatString<StringType, ParameterTypes...>::parse_specifier(SpecifierType
299299
}
300300

301301
//==================================================================================================
302-
template <typename StringType, typename... ParameterTypes>
303-
constexpr std::size_t BasicFormatString<StringType, ParameterTypes...>::parse_position()
302+
template <typename CharType, typename... ParameterTypes>
303+
constexpr std::size_t BasicFormatString<CharType, ParameterTypes...>::parse_position()
304304
{
305305
if (auto position = m_lexer.consume_number(); position)
306306
{
@@ -315,9 +315,9 @@ constexpr std::size_t BasicFormatString<StringType, ParameterTypes...>::parse_po
315315
}
316316

317317
//==================================================================================================
318-
template <typename StringType, typename... ParameterTypes>
318+
template <typename CharType, typename... ParameterTypes>
319319
template <size_t N>
320-
constexpr auto BasicFormatString<StringType, ParameterTypes...>::parameter_type(size_t index)
320+
constexpr auto BasicFormatString<CharType, ParameterTypes...>::parameter_type(size_t index)
321321
-> std::optional<ParameterType>
322322
{
323323
if constexpr (N < sizeof...(ParameterTypes))
@@ -366,8 +366,8 @@ constexpr auto BasicFormatString<StringType, ParameterTypes...>::parameter_type(
366366
}
367367

368368
//==================================================================================================
369-
template <typename StringType, typename... ParameterTypes>
370-
void BasicFormatString<StringType, ParameterTypes...>::on_error(const char *error)
369+
template <typename CharType, typename... ParameterTypes>
370+
void BasicFormatString<CharType, ParameterTypes...>::on_error(const char *error)
371371
{
372372
if (!has_error())
373373
{

fly/types/string/string.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class BasicString
6868

6969
template <typename... ParameterTypes>
7070
using FormatString =
71-
detail::BasicFormatString<StringType, std::type_identity_t<ParameterTypes>...>;
71+
detail::BasicFormatString<char_type, std::type_identity_t<ParameterTypes>...>;
7272

7373
/**
7474
* Determine the length of any string-like value. Accepts character arrays, std::basic_string

test/types/string/format_string.cpp

+13-19
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ class ConstructorCounter
9393
template <typename CharType, std::size_t N, typename... Types>
9494
FLY_CONSTEVAL auto make_format(const CharType (&format)[N], Types &&...)
9595
{
96-
using StringType = std::basic_string<CharType>;
97-
using FormatString = fly::detail::BasicFormatString<StringType, std::type_identity_t<Types>...>;
98-
96+
using FormatString = fly::detail::BasicFormatString<CharType, std::type_identity_t<Types>...>;
9997
return FormatString(format);
10098
}
10199

@@ -170,15 +168,13 @@ constexpr const char *s_bad_bool = "Boolean types must be formatted with {} or o
170168
CATCH_TEMPLATE_TEST_CASE(
171169
"BasicFormatString",
172170
"[string]",
173-
std::string,
174-
std::wstring,
175-
std::u8string,
176-
std::u16string,
177-
std::u32string)
171+
char,
172+
wchar_t,
173+
char8_t,
174+
char16_t,
175+
char32_t)
178176
{
179-
using StringType = TestType;
180-
181-
using char_type = typename StringType::value_type;
177+
using char_type = TestType;
182178
using Specifier = fly::detail::BasicFormatSpecifier<char_type>;
183179

184180
constexpr const GenericType g {};
@@ -679,15 +675,13 @@ CATCH_TEMPLATE_TEST_CASE(
679675
CATCH_TEMPLATE_TEST_CASE(
680676
"BasicFormatStringErrors",
681677
"[string]",
682-
std::string,
683-
std::wstring,
684-
std::u8string,
685-
std::u16string,
686-
std::u32string)
678+
char,
679+
wchar_t,
680+
char8_t,
681+
char16_t,
682+
char32_t)
687683
{
688-
using StringType = TestType;
689-
690-
using char_type = typename StringType::value_type;
684+
using char_type = TestType;
691685

692686
constexpr const GenericType g {};
693687
constexpr const auto c = FLY_CHR(char_type, 'a');

test/types/string/string_format.cpp

+37-38
Original file line numberDiff line numberDiff line change
@@ -48,42 +48,41 @@ enum class UserFormattedEnum
4848
return stream;
4949
}
5050

51-
template <typename StringType, typename... ParameterTypes>
52-
using FormatString = fly::detail::BasicFormatString<
53-
fly::detail::is_like_supported_string_t<StringType>,
54-
std::type_identity_t<ParameterTypes>...>;
51+
template <typename CharType, typename... ParameterTypes>
52+
using FormatString =
53+
fly::detail::BasicFormatString<CharType, std::type_identity_t<ParameterTypes>...>;
5554

5655
template <typename StringType, typename... ParameterTypes>
5756
void test_format(
58-
FormatString<StringType, ParameterTypes...> &&format,
57+
FormatString<
58+
typename fly::detail::is_like_supported_string_t<StringType>::value_type,
59+
ParameterTypes...> format,
5960
StringType &&expected,
6061
ParameterTypes &&...parameters)
6162
{
6263
using BasicString = fly::BasicString<fly::detail::is_like_supported_string_t<StringType>>;
6364

64-
auto result = BasicString::format(
65-
std::forward<FormatString<StringType, ParameterTypes...>>(format),
66-
std::forward<ParameterTypes>(parameters)...);
65+
auto result =
66+
BasicString::format(std::move(format), std::forward<ParameterTypes>(parameters)...);
6767

6868
CATCH_CHECK(result == expected);
6969
}
7070

71-
template <typename StringType>
72-
StringType reserved_codepoint()
71+
template <typename CharType>
72+
std::basic_string<CharType> reserved_codepoint()
7373
{
7474
static constexpr const std::uint32_t s_reserved = 0xd800;
75-
using char_type = typename StringType::value_type;
76-
StringType result;
75+
std::basic_string<CharType> result;
7776

78-
if constexpr (sizeof(char_type) == 1)
77+
if constexpr (sizeof(CharType) == 1)
7978
{
80-
result += static_cast<char_type>(0xe0 | (s_reserved >> 12));
81-
result += static_cast<char_type>(0x80 | ((s_reserved >> 6) & 0x3f));
82-
result += static_cast<char_type>(0x80 | (s_reserved & 0x3f));
79+
result += static_cast<CharType>(0xe0 | (s_reserved >> 12));
80+
result += static_cast<CharType>(0x80 | ((s_reserved >> 6) & 0x3f));
81+
result += static_cast<CharType>(0x80 | (s_reserved & 0x3f));
8382
}
8483
else
8584
{
86-
result = StringType(1, static_cast<char_type>(s_reserved));
85+
result = std::basic_string<CharType>(1, static_cast<CharType>(s_reserved));
8786
}
8887

8988
return result;
@@ -94,15 +93,15 @@ StringType reserved_codepoint()
9493
CATCH_TEMPLATE_TEST_CASE(
9594
"BasicStringFormatter",
9695
"[string]",
97-
std::string,
98-
std::wstring,
99-
std::u8string,
100-
std::u16string,
101-
std::u32string)
96+
char,
97+
wchar_t,
98+
char8_t,
99+
char16_t,
100+
char32_t)
102101
{
103-
using StringType = TestType;
104-
using BasicString = fly::BasicString<StringType>;
105-
using char_type = typename BasicString::char_type;
102+
using char_type = TestType;
103+
using string_type = std::basic_string<char_type>;
104+
using BasicString = fly::BasicString<string_type>;
106105
using view_type = typename BasicString::view_type;
107106

108107
auto is_all_hex = [](view_type value)
@@ -484,10 +483,10 @@ CATCH_TEMPLATE_TEST_CASE(
484483
test_format(FMT("{:c}"), FMT("a"), 0x61);
485484
test_format(
486485
FMT("{:c}"),
487-
StringType(1, static_cast<char_type>(DefaultFormattedEnum::One)),
486+
string_type(1, static_cast<char_type>(DefaultFormattedEnum::One)),
488487
DefaultFormattedEnum::One);
489-
test_format(FMT("{:c}"), StringType(1, static_cast<char_type>(true)), true);
490-
test_format(FMT("{:c}"), StringType(1, static_cast<char_type>(false)), false);
488+
test_format(FMT("{:c}"), string_type(1, static_cast<char_type>(true)), true);
489+
test_format(FMT("{:c}"), string_type(1, static_cast<char_type>(false)), false);
491490
}
492491

493492
CATCH_SECTION("Presentation type may be set (string)")
@@ -753,37 +752,37 @@ CATCH_TEMPLATE_TEST_CASE(
753752

754753
CATCH_SECTION("Invalid Unicode string cannot be formatted")
755754
{
756-
if constexpr (!std::is_same_v<StringType, std::string>)
755+
if constexpr (!std::is_same_v<char_type, char>)
757756
{
758-
const auto reserved = reserved_codepoint<std::string>();
757+
const auto reserved = reserved_codepoint<char>();
759758
test_format(FMT("{}"), FMT(""), reserved);
760759
test_format(FMT("ab {} ab"), FMT("ab ab"), reserved);
761760
test_format(FMT("ab {} ab"), FMT("ab ab"), "ab" + reserved);
762761
}
763-
if constexpr (!std::is_same_v<StringType, std::wstring>)
762+
if constexpr (!std::is_same_v<char_type, wchar_t>)
764763
{
765-
const auto reserved = reserved_codepoint<std::wstring>();
764+
const auto reserved = reserved_codepoint<wchar_t>();
766765
test_format(FMT("{}"), FMT(""), reserved);
767766
test_format(FMT("ab {} ab"), FMT("ab ab"), reserved);
768767
test_format(FMT("ab {} ab"), FMT("ab ab"), L"ab" + reserved);
769768
}
770-
if constexpr (!std::is_same_v<StringType, std::u8string>)
769+
if constexpr (!std::is_same_v<char_type, char8_t>)
771770
{
772-
const auto reserved = reserved_codepoint<std::u8string>();
771+
const auto reserved = reserved_codepoint<char8_t>();
773772
test_format(FMT("{}"), FMT(""), reserved);
774773
test_format(FMT("ab {} ab"), FMT("ab ab"), reserved);
775774
test_format(FMT("ab {} ab"), FMT("ab ab"), u8"ab" + reserved);
776775
}
777-
if constexpr (!std::is_same_v<StringType, std::u16string>)
776+
if constexpr (!std::is_same_v<char_type, char16_t>)
778777
{
779-
const auto reserved = reserved_codepoint<std::u16string>();
778+
const auto reserved = reserved_codepoint<char16_t>();
780779
test_format(FMT("{}"), FMT(""), reserved);
781780
test_format(FMT("ab {} ab"), FMT("ab ab"), reserved);
782781
test_format(FMT("ab {} ab"), FMT("ab ab"), u"ab" + reserved);
783782
}
784-
if constexpr (!std::is_same_v<StringType, std::u32string>)
783+
if constexpr (!std::is_same_v<char_type, char32_t>)
785784
{
786-
const auto reserved = reserved_codepoint<std::u32string>();
785+
const auto reserved = reserved_codepoint<char32_t>();
787786
test_format(FMT("{}"), FMT(""), reserved);
788787
test_format(FMT("ab {} ab"), FMT("ab ab"), reserved);
789788
test_format(FMT("ab {} ab"), FMT("ab ab"), U"ab" + reserved);

0 commit comments

Comments
 (0)