blob: 969258d408b1602710f27d5fe4517535aaad650d [file] [log] [blame]
William A. Kennington III0e844d52022-12-06 23:57:32 -08001#include <fmt/format.h>
2
3#include <stdplus/str/conv.hpp>
4
5#include <algorithm>
6#include <string_view>
7
8#include <gtest/gtest.h>
9
10namespace stdplus
11{
12
13struct TestValS
14{
15 static inline constexpr std::string_view value = "test";
16 static inline constexpr std::wstring_view wvalue = L"test";
17};
18
19template <>
20struct ToStr<TestValS>
21{
22 using type = TestValS;
23 static inline constexpr std::size_t buf_size = TestValS::value.size();
24
25 template <typename CharT>
26 constexpr std::basic_string_view<CharT> operator()(TestValS) const noexcept
27 {
28 if constexpr (std::is_same_v<char, CharT>)
29 {
30 return TestValS::value;
31 }
32 else
33 {
34 static_assert(std::is_same_v<wchar_t, CharT>);
35 return TestValS::wvalue;
36 }
37 }
38};
39
40static_assert(!detail::ToStrFixed<ToStr<TestValS>>);
41static_assert(detail::ToStrStatic<ToStr<TestValS>>);
42
43struct TestValF : TestValS
44{};
45
46template <>
47struct ToStr<TestValF>
48{
49 using type = TestValF;
50 static inline constexpr std::size_t buf_size = TestValF::value.size();
51
52 template <typename CharT>
53 constexpr CharT* operator()(CharT* buf, TestValF) const noexcept
54 {
55 return std::copy(TestValF::value.begin(), TestValF::value.end(), buf);
56 }
57};
58
59static_assert(detail::ToStrFixed<ToStr<TestValF>>);
60static_assert(!detail::ToStrStatic<ToStr<TestValF>>);
61
62struct TestValD : TestValS
63{};
64
65template <>
66struct ToStr<TestValD>
67{
68 using type = TestValD;
69
70 template <typename CharT>
71 constexpr void operator()(stdplus::BasicStrBuf<CharT>& buf, TestValD) const
72 {
73 auto ptr = buf.append(TestValD::value.size());
74 std::copy(TestValD::value.begin(), TestValD::value.end(), ptr);
75 }
76};
77
78static_assert(!detail::ToStrFixed<ToStr<TestValD>>);
79static_assert(!detail::ToStrStatic<ToStr<TestValD>>);
80
81} // namespace stdplus
82
83template <typename CharT>
84struct fmt::formatter<stdplus::TestValS, CharT> :
85 stdplus::Format<stdplus::ToStr<stdplus::TestValS>, CharT>
86{};
87
88template <typename CharT>
89struct fmt::formatter<stdplus::TestValF, CharT> :
90 stdplus::Format<stdplus::ToStr<stdplus::TestValF>, CharT>
91{};
92
93template <typename CharT>
94struct fmt::formatter<stdplus::TestValD, CharT> :
95 stdplus::Format<stdplus::ToStr<stdplus::TestValD>, CharT>
96{};
97
98namespace stdplus
99{
100
101TEST(ToStrAdapter, Static)
102{
103 StrBuf buf;
104 ToStrAdap<ToStr<TestValS>>{}(buf, TestValS{});
105 EXPECT_EQ("test", buf);
William A. Kennington III11572d22023-07-18 14:08:17 -0700106 buf.clear();
William A. Kennington III0e844d52022-12-06 23:57:32 -0800107 auto ptr = buf.append(4);
108 EXPECT_EQ(4, ToStrAdap<ToStr<TestValS>>{}(ptr, TestValS{}) - ptr);
109 EXPECT_EQ("test", std::string_view(ptr, 4));
110}
111
112TEST(ToStrAdapter, Fixed)
113{
114 StrBuf buf;
115 ToStrAdap<ToStr<TestValF>>{}(buf, TestValF{});
116 EXPECT_EQ("test", buf);
117}
118
119TEST(ToStrAdapter, Dynamic)
120{
121 StrBuf buf;
122 ToStrAdap<ToStr<TestValD>>{}(buf, TestValD{});
123 EXPECT_EQ("test", buf);
124}
125
126TEST(ToStrHandle, Basic)
127{
128 EXPECT_EQ("test", (ToStrHandle<ToStr<TestValS>>{}({})));
129 EXPECT_EQ(L"test", (ToStrHandle<ToStr<TestValS>, wchar_t>{}({})));
130 EXPECT_EQ("test", (ToStrHandle<ToStr<TestValF>>{}({})));
131 EXPECT_EQ(L"test", (ToStrHandle<ToStr<TestValF>, wchar_t>{}({})));
132 EXPECT_EQ("test", (ToStrHandle<ToStr<TestValD>>{}({})));
133 EXPECT_EQ(L"test", (ToStrHandle<ToStr<TestValD>, wchar_t>{}({})));
134}
135
136TEST(Format, Basic)
137{
138 EXPECT_EQ("t test", fmt::format("t {}", TestValS{}));
139 EXPECT_EQ("t test", fmt::format("t {}", TestValF{}));
140 EXPECT_EQ("t test", fmt::format("t {}", TestValD{}));
141}
142
143template <>
144struct FromStr<TestValS>
145{
146 template <typename CharT>
147 constexpr TestValS operator()(std::basic_string_view<CharT> sv) const
148 {
149 if (sv == TestValS::value)
150 {
151 return TestValS{};
152 }
153 throw std::runtime_error("Invalid TestValS");
154 }
155};
156
157TEST(FromStr, Basic)
158{
159 EXPECT_NO_THROW(fromStr<TestValS>("test"));
160 EXPECT_THROW(fromStr<TestValS>("hi"), std::runtime_error);
161}
162
163} // namespace stdplus