@@ -40,9 +40,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4040#include < format>
4141#else
4242// Use fmt library as fallback when std::format is not available
43+ #ifndef FMT_HEADER_ONLY
44+ #define FMT_HEADER_ONLY
45+ #endif
4346#include < fmt/format.h>
44- #include < sstream>
45- #include < iomanip>
47+ #include < fmt/xchar.h> // For wide character support
4648#endif
4749
4850namespace utility_module
@@ -103,9 +105,14 @@ namespace utility_module
103105 return std::format_to (out, " {}" , Converter{}(value));
104106 }
105107#else
106- // Fallback implementation using std::to_string
107- auto converted = Converter{}(value);
108- return std::copy (converted.begin (), converted.end (), out);
108+ if constexpr (std::is_same_v<CharT, wchar_t >)
109+ {
110+ return fmt::format_to (out, L" {}" , Converter{}(value));
111+ }
112+ else
113+ {
114+ return fmt::format_to (out, " {}" , Converter{}(value));
115+ }
109116#endif
110117 }
111118
@@ -178,80 +185,10 @@ namespace utility_module
178185#ifdef USE_STD_FORMAT
179186 return std::vformat (formats, std::make_format_args (args...));
180187#else
181- // Fallback implementation using ostringstream
182- std::ostringstream oss;
183- format_impl (oss, formats, args...);
184- return oss.str ();
188+ return fmt::vformat (formats, fmt::make_format_args (args...));
185189#endif
186190 }
187191
188- private:
189- // Helper to output arguments with proper conversion
190- template <typename Stream, typename T>
191- static void output_arg (Stream& stream, const T& arg) {
192- if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view> ||
193- std::is_same_v<T, const char *>) {
194- stream << arg;
195- } else if constexpr (std::is_same_v<T, std::wstring> || std::is_same_v<T, std::wstring_view> ||
196- std::is_same_v<T, const wchar_t *>) {
197- stream << arg;
198- } else if constexpr (std::is_array_v<T> && std::is_same_v<std::remove_extent_t <T>, char >) {
199- // Handle char arrays (string literals)
200- stream << arg;
201- } else if constexpr (std::is_array_v<T> && std::is_same_v<std::remove_extent_t <T>, wchar_t >) {
202- // Handle wchar_t arrays (wide string literals)
203- stream << arg;
204- } else if constexpr (std::is_arithmetic_v<T>) {
205- stream << arg;
206- } else if constexpr (std::is_enum_v<T>) {
207- // For enum types, try to use to_string function
208- stream << to_string (arg);
209- } else {
210- // For other custom types with to_string method
211- stream << arg.to_string ();
212- }
213- }
214-
215- // Simple fallback formatting implementation
216- template <typename Stream>
217- static void format_impl (Stream& stream, const char * format) {
218- stream << format;
219- }
220-
221- template <typename Stream, typename T, typename ... Args>
222- static void format_impl (Stream& stream, const char * format, const T& arg, const Args&... args) {
223- while (*format) {
224- if (*format == ' {' && *(format + 1 ) == ' }' ) {
225- output_arg (stream, arg);
226- format += 2 ;
227- format_impl (stream, format, args...);
228- return ;
229- }
230- stream << *format++;
231- }
232- }
233-
234- // Wide character version
235- template <typename Stream>
236- static void wformat_impl (Stream& stream, const wchar_t * format) {
237- stream << format;
238- }
239-
240- template <typename Stream, typename T, typename ... Args>
241- static void wformat_impl (Stream& stream, const wchar_t * format, const T& arg, const Args&... args) {
242- while (*format) {
243- if (*format == L' {' && *(format + 1 ) == L' }' ) {
244- output_arg (stream, arg);
245- format += 2 ;
246- wformat_impl (stream, format, args...);
247- return ;
248- }
249- stream << *format++;
250- }
251- }
252-
253- public:
254-
255192 /* *
256193 * @brief Formats a wide-character string with the given arguments.
257194 * @tparam FormatArgs Parameter pack of argument types.
@@ -265,10 +202,7 @@ namespace utility_module
265202#ifdef USE_STD_FORMAT
266203 return std::vformat (formats, std::make_wformat_args (args...));
267204#else
268- // Fallback implementation using wostringstream
269- std::wostringstream woss;
270- wformat_impl (woss, formats, args...);
271- return woss.str ();
205+ return fmt::vformat (fmt::wstring_view (formats), fmt::make_wformat_args (args...));
272206#endif
273207 }
274208
@@ -290,9 +224,7 @@ namespace utility_module
290224#ifdef USE_STD_FORMAT
291225 return std::vformat_to (out, formats, std::make_format_args (args...));
292226#else
293- // Fallback implementation
294- std::string result = format (formats, args...);
295- return std::copy (result.begin (), result.end (), out);
227+ return fmt::vformat_to (out, formats, fmt::make_format_args (args...));
296228#endif
297229 }
298230
@@ -312,9 +244,7 @@ namespace utility_module
312244#ifdef USE_STD_FORMAT
313245 return std::vformat_to (out, formats, std::make_wformat_args (args...));
314246#else
315- // Fallback implementation
316- std::wstring result = format (formats, args...);
317- return std::copy (result.begin (), result.end (), out);
247+ return fmt::vformat_to (out, fmt::wstring_view (formats), fmt::make_wformat_args (args...));
318248#endif
319249 }
320250 };
0 commit comments