5
5
#include " fly/types/string/string_literal.hpp"
6
6
7
7
#include < cctype>
8
- #include < cmath>
9
8
#include < cstdint>
10
9
#include < ios>
11
10
#include < locale>
@@ -49,14 +48,14 @@ struct BasicStringStreamer
49
48
* All other types are dropped.
50
49
*
51
50
* @tparam T The type of the value to stream.
52
- * @tparam PreferredPresentationType If given, the type T will be cast to this type.
53
51
*
54
52
* @param stream The stream to insert the value into.
55
53
* @param value The value to stream.
56
54
*/
57
- template <typename T, typename PreferredPresentationType = T >
55
+ template <typename T>
58
56
static void stream_value (ostream_type &stream, T &&value);
59
57
58
+ private:
60
59
/* *
61
60
* Stream a string-like value into the given stream. If the type corresponds to the stream type,
62
61
* then the string is streamed as-is. Other string-like types are converted to the Unicode
@@ -66,10 +65,9 @@ struct BasicStringStreamer
66
65
*
67
66
* @param stream The stream to insert the value into.
68
67
* @param value The string-like value to stream.
69
- * @param max_string_length The maximum number of characters from the string to stream.
70
68
*/
71
69
template <typename T>
72
- static void stream_string (ostream_type &stream, T &&value, std:: size_t max_string_length );
70
+ static void stream_string (ostream_type &stream, T &&value);
73
71
};
74
72
75
73
/* *
@@ -186,85 +184,16 @@ class PositivePaddingFacet : public std::ctype<CharType>
186
184
static constexpr const auto s_space = FLY_CHR(CharType, ' ' );
187
185
};
188
186
189
- /* *
190
- * Helper facet to support BasicFormatSpecifier::Type::Binary. Overrides std::num_put::do_put for
191
- * all integral types to write a value in a binary format, respecting any specified stream width,
192
- * alignment, and alternate form.
193
- *
194
- * @author Timothy Flynn ([email protected] )
195
- * @version January 3, 2021
196
- */
197
- template <typename CharType>
198
- class BinaryFacet : public std ::num_put<CharType>
199
- {
200
- using iter_type = typename std::num_put<CharType>::iter_type;
201
-
202
- protected:
203
- iter_type
204
- do_put (iter_type out, std::ios_base &stream, CharType fill, std::intmax_t value) const override ;
205
-
206
- iter_type do_put (iter_type out, std::ios_base &stream, CharType fill, std::uintmax_t value)
207
- const override ;
208
-
209
- private:
210
- /* *
211
- * Concrete implementation of the facet. Writes the minimum number of bits required to represent
212
- * the given value. If the stream's alternate form is specified, the bits are prefixed with
213
- * either '0b' or '0B', depending on whether the stream has specified uppercase formatting.
214
- * Space permitting, if a stream width is specified, padding is inserted using the provided fill
215
- * character. The location on the padding depends on whether left, right, or internal alignment
216
- * are specified.
217
- */
218
- template <typename T>
219
- iter_type do_put_impl (iter_type out, std::ios_base &stream, CharType fill, T value) const ;
220
-
221
- /* *
222
- * Count the number of significant bits in the given value. This is the total number of bits in
223
- * the value excluding any leading zero bits.
224
- *
225
- * @tparam T Type of the value. Must be an unsigned, integral type.
226
- *
227
- * @param value The value to count.
228
- *
229
- * @return The number of significant bits counted.
230
- */
231
- template <typename T>
232
- static constexpr std::size_t count_bits (T value);
233
-
234
- /* *
235
- * Potentially insert padding symbols into the output iterator.
236
- */
237
- void maybe_fill (
238
- iter_type out,
239
- std::ios_base &stream,
240
- CharType fill,
241
- std::ios_base::fmtflags alignment,
242
- std::size_t bits) const ;
243
-
244
- static constexpr const auto s_zero = FLY_CHR(CharType, ' 0' );
245
- static constexpr const auto s_one = FLY_CHR(CharType, ' 1' );
246
- static constexpr const auto s_upper_b = FLY_CHR(CharType, ' B' );
247
- static constexpr const auto s_lower_b = FLY_CHR(CharType, ' b' );
248
- };
249
-
250
187
// ==================================================================================================
251
188
template <typename StringType>
252
- template <typename T, typename PreferredPresentationType >
189
+ template <typename T>
253
190
void BasicStringStreamer<StringType>::stream_value(ostream_type &stream, T &&value)
254
191
{
255
192
using U = std::remove_cvref_t <T>;
256
- using P = std::remove_cvref_t <PreferredPresentationType>;
257
193
258
- if constexpr (!std::is_same_v<U, P>)
259
- {
260
- if constexpr (std::is_convertible_v<U, P>)
261
- {
262
- stream << static_cast <PreferredPresentationType>(std::forward<T>(value));
263
- }
264
- }
265
- else if constexpr (detail::is_like_supported_string_v<U>)
194
+ if constexpr (detail::is_like_supported_string_v<U>)
266
195
{
267
- stream_string (stream, std::forward<T>(value), StringType::npos );
196
+ stream_string (stream, std::forward<T>(value));
268
197
}
269
198
else if constexpr (detail::is_supported_character_v<T>)
270
199
{
@@ -280,31 +209,27 @@ void BasicStringStreamer<StringType>::stream_value(ostream_type &stream, T &&val
280
209
// ==================================================================================================
281
210
template <typename StringType>
282
211
template <typename T>
283
- void BasicStringStreamer<StringType>::stream_string(
284
- ostream_type &stream,
285
- T &&value,
286
- std::size_t max_string_length)
212
+ void BasicStringStreamer<StringType>::stream_string(ostream_type &stream, T &&value)
287
213
{
288
214
using string_like_type = detail::is_like_supported_string_t <T>;
289
215
using string_like_traits = BasicStringTraits<string_like_type>;
290
216
291
- typename string_like_traits::view_type view (std::forward<T>(value));
292
-
293
217
if constexpr (std::is_same_v<streamed_type, string_like_type>)
294
218
{
295
- stream << view. substr ( 0 , max_string_length) ;
219
+ stream << value ;
296
220
}
297
221
else
298
222
{
299
223
using unicode = BasicStringUnicode<string_like_type>;
300
224
using streamer = BasicStringStreamer<streamed_type>;
301
225
226
+ typename string_like_traits::view_type view (std::forward<T>(value));
302
227
auto it = view.cbegin ();
303
228
const auto end = view.cend ();
304
229
305
230
if (auto converted = unicode::template convert_encoding<streamed_type>(it, end); converted)
306
231
{
307
- streamer::stream_string (stream, *std::move (converted), max_string_length );
232
+ streamer::stream_value (stream, *std::move (converted));
308
233
}
309
234
}
310
235
}
@@ -417,100 +342,4 @@ PositivePaddingFacet<CharType>::do_widen(const char *begin, const char *end, Cha
417
342
return end;
418
343
}
419
344
420
- // ==================================================================================================
421
- template <typename CharType>
422
- inline auto BinaryFacet<CharType>::do_put(
423
- iter_type out,
424
- std::ios_base &stream,
425
- CharType fill,
426
- std::intmax_t value) const -> iter_type
427
- {
428
- return do_put_impl (out, stream, fill, value);
429
- }
430
-
431
- // ==================================================================================================
432
- template <typename CharType>
433
- inline auto BinaryFacet<CharType>::do_put(
434
- iter_type out,
435
- std::ios_base &stream,
436
- CharType fill,
437
- std::uintmax_t value) const -> iter_type
438
- {
439
- return do_put_impl (out, stream, fill, value);
440
- }
441
-
442
- // ==================================================================================================
443
- template <typename CharType>
444
- template <typename T>
445
- auto BinaryFacet<CharType>::do_put_impl(
446
- iter_type out,
447
- std::ios_base &stream,
448
- CharType fill,
449
- T value) const -> iter_type
450
- {
451
- using unsigned_type = std::make_unsigned_t <T>;
452
-
453
- const auto unsigned_value = static_cast <unsigned_type>(value);
454
- const auto bits = count_bits (unsigned_value);
455
-
456
- maybe_fill (out, stream, fill, std::ios_base::right, bits);
457
-
458
- if (stream.flags () & std::ios_base::showbase)
459
- {
460
- *out++ = s_zero;
461
- *out++ = (stream.flags () & std::ios_base::uppercase) ? s_upper_b : s_lower_b;
462
- }
463
-
464
- maybe_fill (out, stream, fill, std::ios_base::internal, bits);
465
-
466
- for (std::size_t bit = bits; bit > 0 ; --bit)
467
- {
468
- *out++ = ((unsigned_value >> (bit - 1 )) & 0x1 ) ? s_one : s_zero;
469
- }
470
-
471
- maybe_fill (out, stream, fill, std::ios_base::left, bits);
472
-
473
- return out;
474
- }
475
-
476
- // ==================================================================================================
477
- template <typename CharType>
478
- template <typename T>
479
- inline constexpr std::size_t BinaryFacet<CharType>::count_bits(T value)
480
- {
481
- static_assert (
482
- std::is_unsigned_v<T> && std::is_integral_v<T>,
483
- " An unsigned integral type is required for count_bits" );
484
-
485
- std::size_t bits = 0 ;
486
-
487
- do
488
- {
489
- ++bits;
490
- } while ((value >>= 1 ) != 0 );
491
-
492
- return bits;
493
- }
494
-
495
- // ==================================================================================================
496
- template <typename CharType>
497
- void BinaryFacet<CharType>::maybe_fill(
498
- iter_type out,
499
- std::ios_base &stream,
500
- CharType fill,
501
- std::ios_base::fmtflags alignment,
502
- std::size_t bits) const
503
- {
504
- if ((stream.flags () & std::ios_base::adjustfield) == alignment)
505
- {
506
- std::streamsize fill_bits = stream.width () - static_cast <std::streamsize>(bits);
507
- fill_bits -= (stream.flags () & std::ios_base::showbase) ? 2 : 0 ;
508
-
509
- for (std::streamsize i = 0 ; i < fill_bits; ++i)
510
- {
511
- *out++ = fill;
512
- }
513
- }
514
- }
515
-
516
345
} // namespace fly::detail
0 commit comments