Skip to content

Commit e07dd7f

Browse files
committed
Making operator<< not pollute global namespace
1 parent ee17d65 commit e07dd7f

File tree

2 files changed

+80
-80
lines changed

2 files changed

+80
-80
lines changed

lib/inc/sys_string/impl/misc.h

Lines changed: 54 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -80,92 +80,73 @@ namespace sysstr
8080

8181
return std::ranges::equal(test.begin(), test.end(), access.begin(), access.begin() + test_size);
8282
}
83+
}
84+
85+
template<class Storage>
86+
template<std::invocable<std::string_view> Func>
87+
inline
88+
auto sys_string_t<Storage>::print_with(Func func) const -> decltype(func(std::string_view{}))
89+
{
90+
if constexpr (std::ranges::contiguous_range<typename sys_string_t<Storage>::char_access> &&
91+
std::is_same_v<typename sys_string_t<Storage>::storage_type, char>)
92+
{
93+
typename sysstr::sys_string_t<Storage>::char_access access(*this);
94+
return func(std::string_view(access.data(), access.size()));
95+
}
96+
else
97+
{
98+
std::string out;
99+
typename sysstr::sys_string_t<Storage>::utf8_access(*this).each([&out](char c) {
100+
out += c;
101+
});
102+
return func(std::string_view(out));
103+
}
104+
}
83105

84-
template<class Storage, class Func>
106+
#if SYS_STRING_WCHAR_T_IS_UTF16
107+
template<class Storage>
108+
template<std::invocable<std::wstring_view> Func>
85109
inline
86-
decltype(auto) with_output_string(const sys_string_t<Storage> & val, Func func)
110+
auto sys_string_t<Storage>::wprint_with(Func func) const -> decltype(func(std::wstring_view{}))
87111
{
88112
if constexpr (std::ranges::contiguous_range<typename sys_string_t<Storage>::char_access> &&
89-
std::is_same_v<typename sys_string_t<Storage>::storage_type, char>)
113+
std::is_same_v<typename sys_string_t<Storage>::storage_type, char16_t>)
90114
{
91-
typename sysstr::sys_string_t<Storage>::char_access access(val);
92-
return func(std::string_view(access.data(), access.size()));
115+
typename sysstr::sys_string_t<Storage>::char_access access(*this);
116+
return func(std::wstring_view((const wchar_t *)access.data(), access.size()));
93117
}
94118
else
95119
{
96-
std::string out;
97-
typename sysstr::sys_string_t<Storage>::utf8_access(val).each([&out](char c) {
98-
out += c;
120+
std::wstring out;
121+
typename sysstr::sys_string_t<Storage>::utf16_access(*this).each([&out](char16_t c) {
122+
out += wchar_t(c);
99123
});
100-
return func(std::string_view(out));
124+
return func(std::wstring_view(out));
101125
}
102126
}
103-
104-
#if SYS_STRING_WCHAR_T_IS_UTF16
105-
template<class Storage, class Func>
106-
inline
107-
decltype(auto) with_output_wstring(const sys_string_t<Storage> & val, Func func)
127+
#elif SYS_STRING_WCHAR_T_IS_UTF32
128+
template<class Storage>
129+
template<std::invocable<std::wstring_view> Func>
130+
inline
131+
auto sys_string_t<Storage>::wprint_with(Func func) const -> decltype(func(std::wstring_view{}))
132+
{
133+
if constexpr (std::ranges::contiguous_range<typename sys_string_t<Storage>::char_access> &&
134+
std::is_same_v<typename sys_string_t<Storage>::storage_type, char32_t>)
108135
{
109-
if constexpr (std::ranges::contiguous_range<typename sys_string_t<Storage>::char_access> &&
110-
std::is_same_v<typename sys_string_t<Storage>::storage_type, char16_t>)
111-
{
112-
typename sysstr::sys_string_t<Storage>::char_access access(val);
113-
return func(std::wstring_view((const wchar_t *)access.data(), access.size()));
114-
}
115-
else
116-
{
117-
std::wstring out;
118-
typename sysstr::sys_string_t<Storage>::utf16_access(val).each([&out](char16_t c) {
119-
out += wchar_t(c);
120-
});
121-
return func(std::wstring_view(out));
122-
}
123-
}
124-
#elif SYS_STRING_WCHAR_T_IS_UTF32
125-
template<class Storage, class Func>
126-
inline
127-
decltype(auto) with_output_wstring(const sys_string_t<Storage> & val, Func func)
136+
typename sysstr::sys_string_t<Storage>::char_access access(*this);
137+
return func(std::wstring_view((const wchar_t *)access.data(), access.size()));
138+
}
139+
else
128140
{
129-
if constexpr (std::ranges::contiguous_range<typename sys_string_t<Storage>::char_access> &&
130-
std::is_same_v<typename sys_string_t<Storage>::storage_type, char32_t>)
131-
{
132-
typename sysstr::sys_string_t<Storage>::char_access access(val);
133-
return func(std::wstring_view((const wchar_t *)access.data(), access.size()));
134-
}
135-
else
136-
{
137-
std::wstring out;
138-
typename sysstr::sys_string_t<Storage>::utf32_access(val).each([&out](char32_t c) {
139-
out += wchar_t(c);
140-
});
141-
return func(std::wstring_view(out));
142-
}
141+
std::wstring out;
142+
typename sysstr::sys_string_t<Storage>::utf32_access(*this).each([&out](char32_t c) {
143+
out += wchar_t(c);
144+
});
145+
return func(std::wstring_view(out));
143146
}
144-
#endif
145-
}
146-
147-
148-
template<class Storage>
149-
inline
150-
auto operator<<(std::ostream & str, const sys_string_t<Storage> & val) -> std::ostream &
151-
{
152-
return util::with_output_string(val, [&](auto view) -> std::ostream & {
153-
return str << view;
154-
});
155-
}
156-
157-
#if SYS_STRING_WCHAR_T_IS_UTF16 || SYS_STRING_WCHAR_T_IS_UTF32
158-
159-
template<class Storage>
160-
inline
161-
auto operator<<(std::wostream & str, const sys_string_t<Storage> & val) -> std::wostream &
162-
{
163-
return util::with_output_wstring(val, [&](auto view) -> std::wostream & {
164-
return str << view;
165-
});
166-
}
147+
}
148+
#endif
167149

168-
#endif
169150
}
170151

171152
#if SYS_STRING_SUPPORTS_STD_FORMAT
@@ -180,7 +161,7 @@ template<class Storage> struct std::formatter<sysstr::sys_string_t<Storage>> : p
180161
template <typename FormatContext>
181162
auto format(const sysstr::sys_string_t<Storage> & str, FormatContext & ctx) const -> decltype(ctx.out())
182163
{
183-
return sysstr::util::with_output_string(str, [&](auto view) {
164+
return str.print_with([&](auto view) -> decltype(ctx.out()) {
184165
return super::format(view, ctx);
185166
});
186167
}
@@ -198,7 +179,7 @@ template<class Storage> struct std::formatter<sysstr::sys_string_t<Storage>, wch
198179
template <typename FormatContext>
199180
auto format(const sysstr::sys_string_t<Storage> & str, FormatContext & ctx) const -> decltype(ctx.out())
200181
{
201-
return sysstr::util::with_output_wstring(str, [&](auto view) {
182+
return str.wprint_with([&](auto view) -> decltype(ctx.out()) {
202183
return super::format(view, ctx);
203184
});
204185
}

lib/inc/sys_string/sys_string.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ namespace sysstr
6565
template<class Storage>
6666
class sys_string_t : public Storage
6767
{
68-
friend std::hash<sys_string_t>;
69-
friend typename Storage::char_access;
68+
friend std::hash<sys_string_t>;
69+
friend typename Storage::char_access;
70+
friend std::formatter<sysstr::sys_string_t<Storage>>;
71+
#if SYS_STRING_WCHAR_T_IS_UTF16 || SYS_STRING_WCHAR_T_IS_UTF32
72+
friend std::formatter<sysstr::sys_string_t<Storage>, wchar_t>;
73+
#endif
7074
private:
7175
using storage = Storage;
7276
public:
@@ -240,11 +244,19 @@ namespace sysstr
240244
static auto std_vformat(std::string_view fmt, std::format_args args) -> sys_string_t;
241245
#endif
242246

243-
template<class S>
244-
friend auto operator<<(std::ostream & str, const sys_string_t<S> & val) -> std::ostream &;
247+
friend auto operator<<(std::ostream & str, const sys_string_t & val) -> std::ostream &
248+
{
249+
return val.print_with([&](auto view) -> std::ostream & {
250+
return str << view;
251+
});
252+
}
245253
#if SYS_STRING_WCHAR_T_IS_UTF16 || SYS_STRING_WCHAR_T_IS_UTF32
246-
template<class S>
247-
friend auto operator<<(std::wostream & str, const sys_string_t<S> & val) -> std::wostream &;
254+
friend auto operator<<(std::wostream & str, const sys_string_t & val) -> std::wostream &
255+
{
256+
return val.wprint_with([&](auto view) -> std::ostream & {
257+
return str << view;
258+
});
259+
}
248260
#endif
249261

250262
auto swap(sys_string_t & other) noexcept -> void
@@ -339,7 +351,14 @@ namespace sysstr
339351
private:
340352
static auto compare(const sys_string_t & lhs, const sys_string_t & rhs) noexcept -> std::strong_ordering;
341353
static auto compare_no_case(const sys_string_t lhs, const sys_string_t & rhs) noexcept -> std::strong_ordering;
342-
354+
355+
template <std::invocable<std::string_view> Func>
356+
auto print_with(Func func) const -> decltype(func(std::string_view{}));
357+
358+
#if SYS_STRING_WCHAR_T_IS_UTF16 || SYS_STRING_WCHAR_T_IS_UTF32
359+
template <std::invocable<std::wstring_view> Func>
360+
auto wprint_with(Func func) const -> decltype(func(std::wstring_view{}));
361+
#endif
343362
};
344363

345364
}

0 commit comments

Comments
 (0)