2727#include < fmt/xchar.h>
2828#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
2929#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
30+ #if defined(__cpp_concepts) && 202002 <= __cpp_concepts
31+ #include < concepts>
32+ #endif
3033
3134namespace LOG4CXX_NS
3235{
@@ -59,13 +62,53 @@ class LOG4CXX_EXPORT AsyncBuffer
5962 * @param value type must be copy-constructable
6063 * @return this buffer.
6164 */
62- template <typename T>
65+ template <typename T>
6366 AsyncBuffer& operator <<(const T& value)
6467 {
68+ #if defined(__cpp_concepts) && 202002 <= __cpp_concepts
69+ #if LOG4CXX_LOGCHAR_IS_UTF8
70+ if constexpr (requires (std::ostream& buf, T v) { buf << v; })
71+ {
72+ append ([value](CharMessageBuffer& msgBuf)
73+ {
74+ msgBuf << value;
75+ });
76+ }
77+ #if LOG4CXX_WCHAR_T_API
78+ else if constexpr (requires (std::wostream& buf, T v) { buf << v; })
79+ {
80+ append ([value](WideMessageBuffer& msgBuf)
81+ {
82+ msgBuf << value;
83+ });
84+ }
85+ #endif // LOG4CXX_WCHAR_T_API
86+ else
87+ static_assert (false , " operator<<(std::ostream&) overload must be provided" );
88+ #else // !LOG4CXX_LOGCHAR_IS_UTF8
89+ if constexpr (requires (std::wostream& buf, T v) { buf << v; })
90+ {
91+ append ([value](WideMessageBuffer& msgBuf)
92+ {
93+ msgBuf << value;
94+ });
95+ }
96+ else if constexpr (requires (std::ostream& buf, T v) { buf << v; })
97+ {
98+ append ([value](CharMessageBuffer& msgBuf)
99+ {
100+ msgBuf << value;
101+ });
102+ }
103+ else
104+ static_assert (false , " operator<<(std::wostream&) overload must be provided" );
105+ #endif // !LOG4CXX_LOGCHAR_IS_UTF8
106+ #else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
65107 append ([value](LogCharMessageBuffer& msgBuf)
66108 {
67109 msgBuf << value;
68110 });
111+ #endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
69112 return *this ;
70113 }
71114
@@ -74,16 +117,57 @@ class LOG4CXX_EXPORT AsyncBuffer
74117 * @param value type must be move-constructable
75118 * @return this buffer.
76119 */
77- template <typename T>
120+ template <typename T>
78121 AsyncBuffer& operator <<(const T&& rvalue)
79122 {
123+ #if defined(__cpp_concepts) && 202002 <= __cpp_concepts
124+ #if LOG4CXX_LOGCHAR_IS_UTF8
125+ if constexpr (requires (std::ostream& buf, T v) { buf << v; })
126+ {
127+ append ([value = std::move (rvalue)](CharMessageBuffer& msgBuf)
128+ {
129+ msgBuf << value;
130+ });
131+ }
132+ #if LOG4CXX_WCHAR_T_API
133+ else if constexpr (requires (std::wostream& buf, T v) { buf << v; })
134+ {
135+ append ([value = std::move (rvalue)](WideMessageBuffer& msgBuf)
136+ {
137+ msgBuf << value;
138+ });
139+ }
140+ #endif // LOG4CXX_WCHAR_T_API
141+ else
142+ static_assert (false , " operator<<(std::ostream&) overload must be provided" );
143+ #else // !LOG4CXX_LOGCHAR_IS_UTF8
144+ if constexpr (requires (std::wostream& buf, T v) { buf << v; })
145+ {
146+ append ([value = std::move (rvalue)](WideMessageBuffer& msgBuf)
147+ {
148+ msgBuf << value;
149+ });
150+ }
151+ else if constexpr (requires (std::ostream& buf, T v) { buf << v; })
152+ {
153+ append ([value = std::move (rvalue)](CharMessageBuffer& msgBuf)
154+ {
155+ msgBuf << value;
156+ });
157+ }
158+ else
159+ static_assert (false , " operator<<(std::wostream&) overload must be provided" );
160+ #endif // !LOG4CXX_LOGCHAR_IS_UTF8
161+ #else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
80162 append ([value = std::move (rvalue)](LogCharMessageBuffer& msgBuf)
81163 {
82164 msgBuf << value;
83165 });
166+ #endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
84167 return *this ;
85168 }
86- #endif
169+
170+ #endif // __cpp_init_captures
87171
88172public: // Accessors
89173 /* *
@@ -131,12 +215,30 @@ class LOG4CXX_EXPORT AsyncBuffer
131215 AsyncBuffer& operator =(const AsyncBuffer&) = delete ;
132216
133217 LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR (Private, m_priv)
218+ #if defined(__cpp_concepts) && 202002 <= __cpp_concepts
219+ using MessageBufferAppender = std::function<void (CharMessageBuffer&)>;
220+
221+ /* *
222+ * Append \c f to this buffer.
223+ */
224+ void append (const MessageBufferAppender& f);
225+
226+ #if LOG4CXX_WCHAR_T_API
227+ using WideMessageBufferAppender = std::function<void (WideMessageBuffer&)>;
228+
229+ /* *
230+ * Append \c f to this buffer.
231+ */
232+ void append (const WideMessageBufferAppender& f);
233+ #endif // LOG4CXX_WCHAR_T_API
234+ #else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
134235 using MessageBufferAppender = std::function<void (LogCharMessageBuffer&)>;
135236
136237 /* *
137- * Append \c function to this buffer.
238+ * Append \c f to this buffer.
138239 */
139240 void append (const MessageBufferAppender& f);
241+ #endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
140242
141243#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
142244 void initializeForFmt (StringViewType&& format_string, FmtArgStore&& args);
0 commit comments