Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Characters/Format.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Characters_Format_h_
5#define _Stroika_Foundation_Characters_Format_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
11#include "Stroika/Foundation/Common/Common.h"
12#include "Stroika/Foundation/Common/Concepts.h"
14
15/**
16 * \file
17 *
18 * \note Code-Status: <a href="Code-Status.md#Alpha">Alpha</a>
19 */
20
22
23 /**
24 * \brief Roughly equivalent to std::wformat_string, except that it can be constructed from 'char' string, and if 'char' require ASCII characters for format string
25 *
26 * \note - the lifetime of the string argument to FormatString is application-lifetime - because the string
27 * is typically saved by reference. This is meant to be used with "foo={}"_f syntax - with constant c strings.
28 *
29 * Sadly, I know of no way to check the lifetime of the argument, so this goes un-enforced.
30 *
31 * \note Types that can be formatted with FormatString (are formattable with it) are:
32 * Anything that is std::formattable<T,wchar_t> (see https://en.cppreference.com/w/cpp/utility/format/formatter)
33 * in particular:
34 * o any class with .ToString() method
35 * o std::type_index
36 * o std::is_enum<>
37 * o std::exception
38 * o std::filesystem::path
39 * o exception_ptr
40 * o POD types (int, bool, double, etc)
41 * o String, or any T IConvertibleToString<T> (such as std::wstring)
42 * o container (T) where T is a IToString (something you can call Characters::ToStirng() on), such as
43 * o is_array<T>
44 * o anything with .begin (), .end () - so any container/iterable
45 * o std::pair<T1,T2>
46 * o std::tuple<TN...>
47 * o std::optional<T>
48 * o KeyValuePair<T1,T2>
49 * o CountedValue<T>
50 * o atomic<T>
51 * o std::variant<TN....>
52 *
53 * \par Example Usage
54 * \code
55 * String a = FormatString<char>{"Internet Media Type {} not supported"sv}(mediaType);
56 * String sameAsA = "Internet Media Type {} not supported"_f (mediaType);
57 * DbgTrace ("prettyVersionString={}"_f, ppv);
58 * DbgTrace ("currentException={}"_f, current_exception ());
59 * DbgTrace ("seq={}"_f, Sequence<IO::Networking::URI>{...});
60 * \endcode
61 *
62 */
63 template </*Common::IAnyOf< char, wchar_t>*/ typename CHAR_T>
64 //requires (Common::IAnyOf<CHAR_T,char,wchar_t>)
65 struct FormatString {
66 static_assert (Common::IAnyOf<CHAR_T, char, wchar_t>); // not sure why this works but requires/concept applied in template not working...
67
68 public:
69 /**
70 */
71 FormatString () = delete;
72 FormatString (const FormatString&) = default;
73 constexpr FormatString (const basic_string_view<CHAR_T>& s);
74
75 public:
76 /**
77 * This retrieves the underlying string data - for the format string itself (regardless of how created, as a wstring_view).
78 */
79 constexpr wstring_view get () const;
80
81 public:
82 /**
83 * Hack for interfacing with fmtlib - dont use unless you need to interact directly with fmtlib
84 */
85 constexpr qStroika_Foundation_Characters_FMT_PREFIX_::wstring_view getx_ () const;
86
87 public:
88 /**
89 */
90 template <Common::StdCompat::formattable<wchar_t>... ARGS>
91 [[nodiscard]] inline String operator() (ARGS&&... args) const;
92 template <Common::StdCompat::formattable<wchar_t>... ARGS>
93 [[nodiscard]] inline String operator() (const locale& loc, ARGS&&... args) const;
94
95 private:
96 wstring_view fSV_; // maybe SB wformat_string here??
97 /// @todo - same CTOR magic to validate format string??? Maybe not needed? BUt dont in format_string<> template...
98 };
99 template <typename CHAR_T>
100 FormatString (const CHAR_T*) -> FormatString<CHAR_T>;
101 template <typename CHAR_T>
102 FormatString (const basic_string_view<CHAR_T>&) -> FormatString<CHAR_T>;
103 template <>
104 struct FormatString<char> {
105 private:
106 vector<wchar_t> fStringData_;
107 FormatString<wchar_t> fFmtStr_;
108
109 public:
110 FormatString () = delete;
111#if !qCompilerAndStdLib_vector_constexpr_Buggy
112 constexpr
113#endif
114 FormatString (const FormatString& src);
115#if !qCompilerAndStdLib_vector_constexpr_Buggy
116 constexpr
117#endif
118 FormatString (const basic_string_view<char>& s);
119
120 constexpr wstring_view get () const;
121 constexpr qStroika_Foundation_Characters_FMT_PREFIX_::wstring_view getx_ () const;
122 template <Stroika_Foundation_Common_formattable_FilterOnStringLitOp_BWA (Common::StdCompat::formattable<wchar_t>)... ARGS>
123 [[nodiscard]] inline String operator() (ARGS&&... args) const;
124 template <Stroika_Foundation_Common_formattable_FilterOnStringLitOp_BWA (Common::StdCompat::formattable<wchar_t>)... ARGS>
125 [[nodiscard]] inline String operator() (const locale& loc, ARGS&&... args) const;
126 };
127
128 /**
129 * \brief Create a format-string (see std::wformat_string or Stroika FormatString, or python 'f' strings
130 *
131 * \par Example Usage
132 * \code
133 * String a = "provider={}"_f (provider);
134 * DbgTrace ("provider={}"_f , provider);
135 * \endcode
136 */
137 inline namespace Literals {
138#if !qCompilerAndStdLib_vector_constexpr_Buggy
139 constexpr
140#endif
141 FormatString<char> operator"" _f (const char* str, size_t len);
142 constexpr FormatString<wchar_t> operator"" _f (const wchar_t * str, size_t len);
143 }
144
145 /**
146 * Same as vformat, except always produces valid UNICODE Stroika String...
147 * \brief same as std::vformat, except always uses wformat_args, and produces Stroika String (and maybe more - soon - ??? - add extra conversions if I can find how?)
148 *
149 * \note FormatString typically created with _f, as in "foo={}"_f
150 */
151 template <typename CHAR_T>
152 [[nodiscard]] String VFormat (const FormatString<CHAR_T>& f, const Common::StdCompat::wformat_args& args);
153 template <typename CHAR_T>
154 [[nodiscard]] String VFormat (const locale& loc, const FormatString<CHAR_T>& f, const Common::StdCompat::wformat_args& args);
155
156 /*
157 *
158 * &&& SOON TO BE OSBOLETE &&&& - NOT SURE IF/HOW MUCH WE WANT TO MAINTAIN THIS FUNCTIONALITY???
159 * MAYBE OK - since probably not intrinsically confusing?
160 *
161 * Format is the Stroika wrapper on sprintf().
162 * The main differences between sprintf () and Format are:
163 * (1) No need for buffer management. ANY sized buffer will be automatically allocated internally and returned as a
164 * String.
165 *
166 * (2) This version of format has a SUBTLE - but important difference from std::c++ / sprintf() in the interpretation of
167 * %s format strings in Format(const wchar_t*): %s is assumed to match a const wchar_t* string in the variable
168 * argument list.
169 *
170 * This deviation from the c++ standard (technically not a deviation because Stroika::Foundation::Characters::Format() isn't
171 * covered by the stdc++ ;-)) - is because of two reasons:
172 * a) Microsoft has this interpretation.
173 * b) Its a BETTER interpretation when using wide characters.
174 *
175 * \note The type of 'format' must be - basically a POD type - not String - due to:
176 * From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf
177 *
178 * If the parameter parmN is of a reference type, or of a type that is not compatible
179 * with the type that results when passing an argument for which there is no parameter,
180 * the behavior is undefined
181 *
182 * I have to say, I don't understand this. It makes sense for the parameters after paramN, but not for the parameter
183 * to va_start () - and BTW, I've used it with type String for a while, and except for compiler warnings, never saw
184 * a problem.
185 */
186 String FormatV (const wchar_t* format, va_list argsList);
187 [[deprecated ("Since Stroika v3.0d6 - use _f format strings - not old style c format strings - use CString::Format for old style C "
188 "format strings")]] String
189 Format (const wchar_t* format, ...);
190
191 /**
192 * \brief Like std::format, except returning stroika String, and taking _f (FormatString) string as argument (which can be ASCII, but still produce UNICODE output).
193 */
194 template <typename CHAR_T, Common::StdCompat::formattable<wchar_t>... ARGS>
195 String Format (const FormatString<CHAR_T>& f, ARGS&&... args);
196 template <typename CHAR_T, Common::StdCompat::formattable<wchar_t>... ARGS>
197 String Format (const locale& l, const FormatString<CHAR_T>& f, ARGS&&... args);
198
199}
200
201/*
202 ********************************************************************************
203 ***************************** Implementation Details ***************************
204 ********************************************************************************
205 */
206#include "Format.inl"
207
208#endif /*_Stroika_Foundation_Characters_Format_h_*/
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
concept - trivial shorthand for variadic same_as A or same_as B, or ...
Definition Concepts.h:175
String VFormat(const FormatString< CHAR_T > &f, const Common::StdCompat::wformat_args &args)
same as std::vformat, except always uses wformat_args, and produces Stroika String (and maybe more - ...
Roughly equivalent to std::wformat_string, except that it can be constructed from 'char' string,...
constexpr qStroika_Foundation_Characters_FMT_PREFIX_::wstring_view getx_() const