C++ Library Extensions 2022.12.09
To help learn modern C++ programming
tpf_output.hpp
Go to the documentation of this file.
1
12#ifndef _TPF_OUTPUT_HPP
13#define _TPF_OUTPUT_HPP
14
15#ifndef TBB_SUPPRESS_DEPRECATED_MESSAGES
16 #define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
17#endif // end of TBB_SUPPRESS_DEPRECATED_MESSAGES
18
19#ifndef NOMINMAX
20#define NOMINMAX
21#endif
22
23#ifdef _MSVC_LANG
24 #if _MSVC_LANG < 201703L
25 #error This libary requires C++17 Standard (Visual Studio 2017).
26 #endif
27#else
28
29 #if __cplusplus < 201703
30 #error This library requires C++17 Standard (GNU g++ version 8.0 or clang++ version 8.0 above)
31 #endif // end of __cplusplus
32
33#endif // end of _MSVC_LANG
34
35#include <tpf_conversion.hpp>
36#include <tpf_any.hpp>
37#include <tpf_bitwise.hpp>
38#include <tpf_parallel.hpp>
39#include <iostream>
40#include <sstream>
41#include <functional>
42
43#if defined(TPF_USE_STD_EXTENSION_ARRAY_TUPLE)
44 #include <tpf_std_extensions.hpp>
45#endif
46
51namespace tpf
52{
57 namespace output
58 {
59 template<typename CharType, typename T>
60 std::basic_ostream<CharType>& operator<<
61 (std::basic_ostream<CharType>& os, const tpf::bitwise::bit_pattern<T>& a);
62
63 template<typename CharType, typename... ElementTypes>
64 std::basic_ostream<CharType>& operator<<
65 (std::basic_ostream<CharType>& os, const tpf::types::any<ElementTypes...>& a);
66
67 template<typename CharType, typename T>
68 std::basic_ostream<CharType>&
69 operator<<(std::basic_ostream<CharType>& os, const std::optional<T>& opt);
70
71 template<typename CharType, auto N, auto D>
72 std::basic_ostream<CharType>&
73 operator<<(std::basic_ostream<CharType>& os, const std::ratio<N, D>& r)
74 {
75 if(r.num == 0)
76 os <<"< 0 >";
77 else if(r.den == 1)
78 os <<"< "<< r.num <<" >";
79 else
80 os <<"< " << r.num << " / " << r.den <<" > ";
81
82 return os;
83 }
84
85 template<typename CharType>
86 std::basic_ostream<CharType>&
87 operator<<(std::basic_ostream<CharType>& os, const std::byte& b)
88 {
89 os << tpf::bitwise::to_bits<char>(std::to_integer<char>(b));
90
91 return os;
92 }
93
94 template<typename CharType, auto IndexValue>
95 std::basic_ostream<CharType>&
96 operator<<(std::basic_ostream<CharType>& os,
97 const types::indexer_t<IndexValue>& indexer)
98 {
99 os << "< " << indexer.Index << " >" ; return os;
100 }
101
102 template<typename CharType, auto RowValue, auto ColumnValue>
103 std::basic_ostream<CharType>&
104 operator<<(std::basic_ostream<CharType>& os,
106 {
107 os << "< " << indexer.Row <<", " << indexer.Column<<" >"; return os;
108 }
109
110 template<typename CharType, auto HeightValue, auto RowValue, auto ColumnValue>
111 std::basic_ostream<CharType>&
112 operator<<(std::basic_ostream<CharType>& os,
114 {
115 os << "< " << indexer.Height <<", "<< indexer.Row <<", " << indexer.Column<<" >"; return os;
116 }
117
118 template<typename CharType, typename Type, int Tag>
119 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
120 const types::tag_type<Type, Tag>& ncw);
121
122 template<typename CharType, typename Type>
123 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
124 const std::initializer_list<Type>& init_list);
125
126 template<typename CharType, template<auto...>class ContainerType,
127 auto... Ints> std::basic_ostream<CharType>&
128 operator>>(std::basic_ostream<CharType>& os, const ContainerType<Ints...>& seq);
129
130 template<typename CharType, typename T, auto FirstValue, auto LastValue, size_t CountValue, bool stack_order>
131 std::basic_ostream<CharType>&
132 operator<<(std::basic_ostream<CharType>& os,
134 {
135 os << "{ " << Tpf_GetTypeName(T)<<", Begin: " << seq.Begin<<", Last: "
136 << seq.Last<<", End: "<< seq.End <<", Span: " << seq.Span
137 <<", Count: " << seq.Count<<", InOrder: " << seq.InOrder <<" }";
138
139 return os;
140 }
141
142 template<typename CharType,
143 typename T, T... Ints> std::basic_ostream<CharType>&
144 operator<<(std::basic_ostream<CharType>& os, const std::integer_sequence<T, Ints...>& seq)
145 {
146 constexpr auto Size = sizeof...(Ints);
147
148 if(Size == 0)
149 {
150 os <<"< >";
151 }
152 else
153 {
154 std::array<T, Size> array{ Ints...};
155
156 types::indexer_t<Size> dimension;
157
158 os <<"< ";
159
160 for(size_t i = 0; i < Size; ++i)
161 {
162 os << array[i];
163
164 if(i + 1 != Size) os <<", ";
165 }
166
167 os <<" >";
168 }
169
170 return os;
171 }
172
173 template<typename CharType, template<auto...>class ContainerType,
174 auto... Ints> std::basic_ostream<CharType>&
175 operator>>(std::basic_ostream<CharType>& os, const ContainerType<Ints...>& seq)
176 {
177 constexpr auto Size = sizeof...(Ints);
178
179 std::array array{ Ints...};
180
181 types::indexer_t<Size> dimension;
182
183 if(Size == 0)
184 {
185 os <<"< >";
186 }
187 else
188 {
189 os << "< " ;
190
191 for(size_t i = 0; i < Size; ++i)
192 {
193 os << array[i];
194
195 if(i + 1 != Size) os <<", ";
196 }
197
198 os <<" >";
199 }
200
201 return os;
202 }
203
204
205 template<typename CharType,
206 typename T, T... Ints> std::basic_ostream<CharType>&
207 operator>>(std::basic_ostream<CharType>& os, const std::integer_sequence<T, Ints...>& seq)
208 {
209 constexpr auto Size = sizeof...(Ints);
210
211 std::array array{ Ints...};
212
213 types::indexer_t<Size> dimension;
214
215 if(Size == 0)
216 {
217 os <<"{ "<<Tpf_GetTypeName(T)<<" }";
218 }
219 else
220 {
221 os <<"{ "<<Tpf_GetTypeName(T)<<": ";
222
223 for(size_t i = 0; i < Size; ++i)
224 {
225 os << array[i];
226
227 if(i + 1 != Size) os <<", ";
228 }
229
230 os <<" }";
231 }
232
233 return os;
234 }
235
236 template<typename CharType> std::basic_ostream<CharType>&
237 operator<<(std::basic_ostream<CharType>& os, types::TemplateCategory tc)
238 {
239 switch(tc)
240 {
241 case types::TemplateCategory::Type: os <<"Type"; return os;
242
243 case types::TemplateCategory::Type_Value: os <<"Type_Value"; return os;
244
245 case types::TemplateCategory::Value: os <<"Value"; return os;
246
247 case types::TemplateCategory::Value_Type: os <<"Value_Type"; return os;
248
249 default:
250 os <<"Unknown"; return os;
251 }
252 }
253
261 inline std::ostream& operator<<(std::ostream& os, const std::wstring& str)
262 {
263 os << conversion::source_to_target<char, wchar_t>(str);
264 return os;
265 }
266
274 inline std::ostream& operator<<(std::ostream& os, const wchar_t* str)
275 {
276 os << conversion::source_to_target<char, wchar_t>(str);
277 return os;
278 }
279
287 inline std::wostream& operator<<(std::wostream& os, const std::string& str)
288 {
289 os << conversion::source_to_target<wchar_t, char>(str);
290 return os;
291 }
292
298 namespace hidden
299 {
300 template<typename CharType, template<typename, typename...> class ContainerType,
301 typename Type, typename... Types>
303 types::is_empty_available_v<ContainerType<Type, Types...>> &&
304 !types::is_basic_string_v<ContainerType<Type, Types...>>,
305 std::basic_ostream<CharType>&>;
306
307 } // end of namespace hidden
308
309 template<typename CharType, typename FirstType, typename SecondType>
310 std::basic_ostream<CharType>&
311 operator<<(std::basic_ostream<CharType>& os, const std::pair<FirstType, SecondType>& pr);
312
313 template<typename CharType, typename... Types>
314 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
315 const std::tuple<Types...>& tuple);
316
317 template<typename CharType, typename Type, typename... Types>
318 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
319 const std::variant<Type, Types...>& variant);
320
321 template<typename CharType, typename Type_1, typename Type_2>
322 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
323 const std::unique_ptr<Type_1, Type_2>& ptr);
324
325 template<typename CharType, typename Type>
326 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
327 const std::shared_ptr<Type>& ptr);
328
329 template<typename CharType, typename ElementType, size_t Size>
330 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
331 const std::array<ElementType, Size>& array);
332
333 #ifdef _TPF_CUDA_EXTENSIONS_HPP
334 template<typename CharType, typename... Types>
335 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
336 thrust::tuple<Types...> const& tuple);
337 #endif
338
350 template<typename CharType, template<typename, typename...> class ContainerType,
351 typename Type, typename... Types>
352 hidden::enable_stream_if_not_string_t<CharType, ContainerType, Type, Types...>
353 operator<<(std::basic_ostream<CharType>& os, const ContainerType<Type, Types...>& container)
354 {
355 using namespace conversion;
356
357 if(container.empty())
358 {
359 os << smart_encode("{ }");
360 return os;
361 }
362 else
363 {
364 auto last_element = container.cend();
365
366 os << "{ ";
367
368 for(auto itr = container.cbegin(); itr != container.cend(); )
369 {
370 os << *itr;
371
372 ++itr;
373
374 if(itr == container.cend())
375 os << " }";
376 else
377 os << ", ";
378 }
379
380 return os;
381 }
382 }
383
384 template<typename CharType, typename ElementType, size_t Size>
385 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os, const std::array<ElementType, Size>& array)
386 {
387 if(array.empty())
388 {
389 os <<"< >"; return os;
390 }
391 else
392 {
393 auto last = array.end();
394 --last;
395
396 os << "< ";
397 for(auto itr = array.begin(); itr != last; ++itr)
398 os << *itr <<", "; // if the type of *itr or ElementType is std::array
399 // operator<<() is called recursively
400
401 os << *last <<" >";
402
403 return os;
404 }
405 }
406
407 template<typename CharType, typename Type, int Tag>
408 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
410 {
411 os << ncw.get(); return os;
412 }
413
424 template<typename CharType, typename FirstType, typename SecondType>
425 std::basic_ostream<CharType>&
426 operator<<(std::basic_ostream<CharType>& os, const std::pair<FirstType, SecondType>& pr)
427 {
428 os << "{ " << pr.first << ", " << pr.second << " }";
429 return os;
430 }
431
432 template<typename CharType, typename FirstType, typename SecondType>
433 std::basic_ostream<CharType>&
434 operator<<(std::basic_ostream<CharType>& os,
436 {
437 auto [ptr, size] = array;
438
439 if(types::is_string_v<FirstType> &&
441 os << ptr ;
442 else
443 {
444 os << "{ ";
445
446 for(size_t i = 0; i < (size_t)size-1; ++i)
447 os << *(ptr+i) << ", ";
448
449 os << *(ptr+size-1) << " }";
450 }
451
452 return os;
453 }
454
455 template<typename CharType, typename... Types>
456 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
457 const types::type_list_t<Types...>& typelist);
458
459 namespace hidden
460 {
461 // dummy function
462 template<typename CharType>
463 static void print_type_list(std::basic_ostream<CharType>& os) { }
464
465 template<typename CharType, typename Type, typename... Types>
466 static void print_type_list(std::basic_ostream<CharType>& os)
467 {
468 if constexpr (types::is_type_list_v<Type>)
469 {
470 os << Type{};
471 }
472 else
473 {
474 os << Tpf_GetTypeName(Type);
475 }
476 if constexpr(sizeof...(Types) != 0)
477 {
478 os << ", ";
479 print_type_list<CharType, Types...>(os);
480 }
481 }
482
483 template<typename CharType, typename... Types>
484 void print_type_list(std::basic_ostream<CharType>& os,
485 const types::type_list_t<Types...>& typelist)
486 {
487 if constexpr(sizeof...(Types)==0)
488 os << conversion::smart_encode("< >");
489 else
490 {
491 os << "< ";
492 print_type_list<CharType, Types...>(os);
493 os<< " >";
494 }
495 }
496
497 } // end of namespace hidden
498
499 template<typename CharType, typename... Types>
500 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
501 const types::type_list_t<Types...>& typelist)
502 {
503 hidden::print_type_list(os, typelist);
504 return os;
505 }
506
507 template<typename CharType>
508 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
509 const std::exception& expt)
510 {
511 os << expt.what();
512 return os;
513 }
514
515 template<typename CharType, typename... Types>
516 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
517 const std::tuple<Types...>& tuple)
518 {
519 constexpr int Size = sizeof...(Types);
520
521 if constexpr(Size == 0)
522 {
523 os <<"[ ]"; return os;
524 }
525 else
526 {
527 os <<"[ ";
528
529 types::for_workhorse<Size>([&os, &tuple](auto i, auto info)
530 {
531 os << std::get<i.Index>(tuple);
532
533 if(i.Index != info.Last)
534 os <<", ";
535 });
536
537 os <<" ]";
538
539 return os;
540 }
541 }
542
543 template<typename CharType, typename Type, typename... Types>
544 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
545 const std::variant<Type, Types...>& variant)
546 {
547
548 if(std::variant_npos == variant.index())
549 return os;
550 else
551 {
552 constexpr int Size = sizeof...(Types) + 1;
553
554 types::for_workhorse<Size>([&os, &variant](auto i)
555 {
556 if(i.Index == variant.index())
557 {
558 if constexpr( std::is_same_v<std::monostate,
559 std::variant_alternative_t<i.Index, std::variant<Type, Types...>>>)
560 {
561 os << "monostate";
562 }
563 else
564 {
565 os << std::get<i.Index>(variant);
566 }
567 }
568 });
569
570 return os;
571 }
572 }
573
574 template<typename CharType, typename Type_1, typename Type_2>
575 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
576 const std::unique_ptr<Type_1, Type_2>& ptr)
577 {
578 if(ptr) os << *ptr;
579 return os;
580 }
581
582 template<typename CharType, typename Type>
583 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
584 const std::shared_ptr<Type>& ptr)
585 {
586 if(ptr) os << *ptr;
587 return os;
588 }
589
590 template<typename CharType, template<typename, typename...> class ContainerType,
591 typename... ElementTypes>
592 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
593 const types::hidden::container_of_variants_class<ContainerType, ElementTypes...>& container)
594 {
595 using namespace conversion;
596
597 if(container.empty())
598 {
599 os << smart_encode("{ }");
600 return os;
601 }
602 else
603 {
604 auto last_element = container.cend();
605
606 os << "{ ";
607
608 for(auto itr = container.cbegin(); itr != container.cend(); )
609 {
610 os << *itr;
611
612 ++itr;
613
614 if(itr == container.cend())
615 os << " }";
616 else
617 os << ", ";
618 }
619
620 return os;
621 }
622 }
623
624 template<typename CharType, template<typename, typename...> class ContainerType,
625 typename... ElementTypes>
626 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
627 const types::hidden::container_of_tuples_class<ContainerType, ElementTypes...>& container)
628 {
629 using namespace conversion;
630
631 if(container.empty())
632 {
633 os << smart_encode("{ }");
634 return os;
635 }
636 else
637 {
638 auto last_element = container.cend();
639
640 os << "{ ";
641
642 for(auto itr = container.cbegin(); itr != container.cend(); )
643 {
644 os << *itr;
645
646 ++itr;
647
648 if(itr == container.cend())
649 os << " }";
650 else
651 os << ", ";
652 }
653
654 return os;
655 }
656 }
657
658 template<typename CharType, typename ContainerType>
659 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
660 const types::reverse_st<ContainerType>& container)
661 {
662 using namespace conversion;
663
664 if(container.empty())
665 {
666 os << smart_encode("{ }");
667 return os;
668 }
669 else
670 {
671 auto last_element = container.cend();
672
673 os << "{ ";
674
675 for(auto itr = container.cbegin(); itr != container.cend(); )
676 {
677 os << *itr;
678
679 ++itr;
680
681 if(itr == container.cend())
682 os << " }";
683 else
684 os << ", ";
685 }
686
687 return os;
688 }
689 }
690
691 template<typename CharType, size_t ElementCount>
692 std::basic_ostream<CharType>&
693 operator<<(std::basic_ostream<CharType>& os, const std::byte(&array)[ElementCount])
694 {
695 using namespace conversion;
696
697 if(ElementCount == 0)
698 {
699 os << smart_encode(" ");
700 return os;
701 }
702 else
703 {
704 auto last_idx = ElementCount-1;
705
706 for(int idx = last_idx; idx > 0; --idx )
707 {
708 os << array[idx] << '\'';
709 }
710
711 os << array[0];
712
713 return os;
714 }
715 }
716
717 template<typename CharType, typename T>
718 std::basic_ostream<CharType>& operator<<
719 (std::basic_ostream<CharType>& os, const tpf::bitwise::bit_pattern<T>& a)
720 {
721 if constexpr(std::is_same_v<T, unsigned char> || std::is_same_v<T, char> )
722 os << (unsigned short)a.n <<"\t(" << tpf::bitwise::to_hex(a.n) <<")\t"<<a.b;
723 else
724 os << a.n <<"\t(" << tpf::bitwise::to_hex(a.n) <<")\t"<<a.b;
725
726 return os;
727 }
728
729 template<typename CharType, typename ElementType, size_t ElementCount>
730 std::enable_if_t<!types::is_char_v<ElementType>, std::basic_ostream<CharType>&>
731 operator<<(std::basic_ostream<CharType>& os, const ElementType(&array)[ElementCount])
732 {
733 using namespace conversion;
734
735 if(ElementCount == 0)
736 {
737 os << smart_encode("< >");
738 return os;
739 }
740 else
741 {
742 os << "< ";
743
744 auto last_idx = ElementCount-1;
745
746 for(size_t idx = 0; idx < last_idx; ++idx )
747 {
748 os << array[idx] << ", ";
749 }
750
751 os << array[last_idx] << " >";
752
753 return os;
754 }
755 }
756
757 // template<typename ElementType, size_t ElementCount>
758 // class reverse_st<ElementType(&)[ElementCount]>
759 template<typename CharType, typename ElementType, size_t ElementCount>
760 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
761 const types::reverse_st<ElementType(&)[ElementCount]>& container)
762 {
763 using namespace conversion;
764
765 if(container.empty())
766 {
767 os << smart_encode("{ }");
768 return os;
769 }
770 else
771 {
772 auto last_element = container.cend();
773
774 os << "{ ";
775
776 for(auto itr = container.cbegin(); itr != container.cend(); )
777 {
778 os << *itr;
779
780 ++itr;
781
782 if(itr == container.cend())
783 os << " }";
784 else
785 os << ", ";
786 }
787
788 return os;
789 }
790 }
791
792 template<typename CharType, typename Type>
793 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
794 const std::initializer_list<Type>& init_list)
795 {
796 std::vector<Type> vctr{init_list.begin(), init_list.end()};
797 os << vctr; return os;
798 }
799
800 #ifdef _TPF_CUDA_EXTENSIONS_HPP
801 template<typename CharType, typename... Types>
802 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
803 thrust::tuple<Types...> const& tuple)
804 {
805 constexpr auto N =
806 thrust::tuple_size<thrust::tuple<Types...>>::value;
807
808 os <<"[ ";
809
810 types::for_workhorse<N>([&tuple, &os](auto i)
811 {
812 constexpr auto N =
813 thrust::tuple_size<thrust::tuple<Types...>>::value;
814
815 os << thrust::get<i.Index>(tuple);
816
817 if constexpr( i.Index != N - 1) os << ", ";
818 });
819
820 os <<" ]"; return os;
821 }
822
823 template<typename CharType, typename Type1, typename Type2>
824 std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& os,
825 thrust::pair<Type1, Type2> const& pair)
826 {
827 os <<"( "<<pair.first<<", " << pair.second<<" )"; return os;
828 }
829 #endif
830
831 struct new_line{};
832 struct new_Line{};
833 struct flush_stream{};
836
837 constexpr new_line nl(){ return new_line{}; }
838 constexpr new_Line nL(){ return new_Line{}; }
839 constexpr flush_stream flush() { return flush_stream{}; };
840 constexpr new_line_flush endl() { return new_line_flush{}; };
841 constexpr new_Line_flush endL() { return new_Line_flush{}; };
842
843 class string_stream: public std::ostringstream
844 {
845 public:
846 using base_t = std::ostringstream;
847
848 public:
849
851 {
852 return static_cast<base_t&>(*this);
853 }
854
855 const base_t& std() const
856 {
857 return static_cast<const base_t&>(*this);
858 }
859
861 {
862 std() << std::boolalpha;
863 // static_cast<base_t&>(*this).imbue(std::locale(""));
864 }
865
866 string_stream(const string_stream&) = default;
867
869
870 string_stream& operator << (const char* arg)
871 {
873 return *this;
874 }
875
876 string_stream& operator << (const wchar_t* arg)
877 {
879 return *this;
880 }
881
882 // template<typename ArgCharType>
883 // string_stream& operator << (const std::basic_string<ArgCharType>& arg)
884 // {
885 // std() << arg.c_str();
886 // return *this;
887 // }
888
889 #ifndef _TPF_CUDA_EXTENSIONS_HPP
890 template<typename ArgCharType>
891 string_stream& operator << (const ArgCharType& arg)
892 {
893 std() << arg;
894 return *this;
895 }
896 #endif
897
898 template<std::size_t N, typename T, typename deleter>
900 {
901 std() << upw.ref(); return *this;
902 }
903
905 {
906 std() << "\n";
907 return *this;
908 }
909
911 {
912 std() << "\n\n";
913 return *this;
914 }
915
917 {
918 std().clear(); std().str("");
919 return *this;
920 }
921
923 {
924 std::cout << std().str(); std::cout.flush();
925 std().clear(); std().str("");
926 return *this;
927 }
928
930 {
931 std::cout << std().str() << std::endl;
932
933 std().clear(); std().str("");
934
935 return *this;
936 }
937
939 {
940 std() << "\n";
941 std::cout << std().str() << std::endl;
942 std().clear(); std().str("");
943 return *this;
944 }
945
946 operator std::string() const
947 {
948 return this->std().str();
949 }
950
951 std::string str() const
952 {
953 return this->std().str();
954 }
955
956 operator std::wstring() const
957 {
958 return conversion::utf8_to_utf16(this->std().str());
959 }
960
961 operator const char*() const
962 {
963 return this->std().str().c_str();
964 }
965 };
966
967 } // end of namespace output
968
970 constexpr auto flush = output::flush_stream{};
971 constexpr auto nl = output::new_line{};
972 constexpr auto nL = output::new_Line{};
973 constexpr auto endl = output::new_line_flush{};
974 constexpr auto endL = output::new_Line_flush{};
975
976 namespace output
977 {
978 using namespace tpf::types;
979
980 template< typename T, typename = std::enable_if_t<!(types::is_tag_type_v<T> || types::is_numbers_type_v<T>)>>
982 {
983 os << "(decayed)" << Tpf_GetTypeName(T);
984
985 return os;
986 }
987
988 template< template<typename...> class TemplateType, typename... Types>
989 sstream& operator >> (sstream& os, const TemplateType<Types...>& arg)
990 {
991 using element_list_t = types::to_recursive_type_list_t<TemplateType<Types...>>;
992
993 os <<element_list_t{} ;
994
995 return os;
996 }
997
998 template<typename Type, int Tag>
1000 {
1001 os <<"tag< "<< Tpf_GetTypeName(Type)
1002 << ", " << Tag <<" >"; return os;
1003 }
1004
1005 template<template<auto...> class ContainerType, auto... Ints>
1006 sstream& operator>>(sstream& os, const ContainerType<Ints...>& arg)
1007 {
1008 os.std() >> arg ; return os;
1009 }
1010
1011 template< template<typename T, T...> class TemplateType, typename Type, Type... Args,
1012 typename = std::enable_if_t<!types::is_tag_type_v<TemplateType<Type, Args...>>>>
1013 sstream& operator >> (sstream& os, const TemplateType<Type, Args...>&)
1014 {
1015 os.std() >> std::integer_sequence<Type, Args...>{};
1016 return os;
1017 }
1018
1019 template<typename Type>
1021 {
1022 os << arg <<", "; return os;
1023 }
1024
1025 template<typename Type>
1027 {
1028 os << arg ; return os;
1029 }
1030
1031 template<typename CharType, typename T>
1032 std::basic_ostream<CharType>&
1033 operator<<(std::basic_ostream<CharType>& os, const std::optional<T>& opt)
1034 {
1035 if(opt.has_value())
1036 {
1037 os << *opt;
1038 }
1039
1040 return os;
1041 }
1042
1043 template<typename CharType, typename... ElementTypes>
1044 std::basic_ostream<CharType>& operator<<
1045 (std::basic_ostream<CharType>& os, const tpf::types::any<ElementTypes...>& a)
1046 {
1047 if(!a.std().has_value())
1048 {
1049 os << "no_value"; return os;
1050 }
1051 else
1052 {
1053 constexpr int Size = sizeof...(ElementTypes);
1054
1055 try
1056 {
1057 types::for_workhorse<Size>([&os, &a](auto i)
1058 {
1059 using element_types_t = typename any<ElementTypes...>::element_types_t;
1060
1061 using element_t = select_nth_type_t<i.Index, element_types_t>;
1062
1063 if(auto ptr = std::any_cast<element_t>(&a.std()))
1064 {
1065 os << *ptr;
1066
1067 // operation successful
1068 throw types::no_type_t{};
1069 }
1070 });
1071
1072 }catch(const types::no_type_t&) { }
1073
1074 return os;
1075 }
1076 }
1077
1078 template<typename Type, size_t CacheSize>
1081 {
1082 os.std() << cw.get(); return os;
1083 }
1084
1085 } // end of namespace output
1086
1087} // end of namespace tpf
1088
1089#endif // end of file _TPF_OUTPUT_HPP
auto & cout
typename enable_if< predicate, ReturnType >::type enable_if_t
Definition: 12_sfinae.cpp:23
string_stream & operator=(const string_stream &)=default
std::string str() const
Definition: tpf_output.hpp:951
string_stream & clear()
Definition: tpf_output.hpp:916
string_stream(const string_stream &)=default
std::ostringstream base_t
Definition: tpf_output.hpp:846
const base_t & std() const
Definition: tpf_output.hpp:855
decltype(auto) cbegin() const noexcept
Definition: tpf_types.hpp:7525
auto empty() const noexcept
Definition: tpf_types.hpp:7509
decltype(auto) cend() const noexcept
Definition: tpf_types.hpp:7530
const Type & get() const noexcept
Definition: tpf_types.hpp:325
std::string smart_encode(const char *arg)
constexpr decltype(auto) get(T(&c_array)[N]) noexcept
std::string to_hex(T v)
String conversions are implemented.
std::string smart_encode(const char *arg)
std::wstring utf8_to_utf16(const std::string &utf8str)
Converts UTF8 std::string to UTF16 std::wstring.
std::enable_if_t< types::is_empty_available_v< ContainerType< Type, Types... > > &&!types::is_basic_string_v< ContainerType< Type, Types... > >, std::basic_ostream< CharType > & > enable_stream_if_not_string_t
Definition: tpf_output.hpp:305
Stream output operators are defined.
Definition: tpf_output.hpp:58
string_stream & operator>(string_stream &os, Type &&arg)
constexpr new_line_flush endl()
Definition: tpf_output.hpp:840
sstream & operator>>(sstream &os, const TemplateType< Type, Args... > &)
string_stream & operator<(string_stream &os, Type &&arg)
std::basic_ostream< CharType > & operator>>(std::basic_ostream< CharType > &os, const ContainerType< Ints... > &seq)
Definition: tpf_output.hpp:175
constexpr flush_stream flush()
Definition: tpf_output.hpp:839
constexpr new_Line nL()
Definition: tpf_output.hpp:838
constexpr new_line nl()
Definition: tpf_output.hpp:837
std::basic_ostream< CharType > & operator<<(std::basic_ostream< CharType > &os, const tpf::bitwise::bit_pattern< T > &a)
Definition: tpf_output.hpp:719
constexpr new_Line_flush endL()
Definition: tpf_output.hpp:841
sstream & operator<<(sstream &os, const tpf::parallel::cache_wrapper< Type, CacheSize > &cw)
constexpr bool is_tag_type_v
Definition: tpf_types.hpp:347
Type to string name conversions are defined.
Definition: 31-visit.cpp:7
constexpr bool is_empty_available_v
Definition: tpf_types.hpp:5332
constexpr auto is_basic_string_v
Definition: tpf_types.hpp:1930
hidden::to_recursive_type_list_t< remove_cv_ref_t< T > > to_recursive_type_list_t
Definition: tpf_types.hpp:1037
hidden::select_nth_type_t< SelectIndex, Types... > select_nth_type_t
Definition: tpf_types.hpp:5585
Includes subnamespace conversion.
Definition: 31-visit.cpp:7
constexpr auto flush
Definition: tpf_output.hpp:970
constexpr auto endL
Definition: tpf_output.hpp:974
remove_cv_ref_t< std::remove_pointer_t< decay_remove_cv_ref_t< Type > > > primitive_type_t
Decay, remove const, volatile, reference, then remove pointer and remove const and volatile.
Definition: tpf_types.hpp:178
constexpr auto nL
Definition: tpf_output.hpp:972
constexpr auto endl
Definition: tpf_output.hpp:973
constexpr auto nl
Definition: tpf_output.hpp:971
const Type & get() const noexcept
static constexpr size_t Count
Definition: tpf_types.hpp:2494
static constexpr T Row
Definition: tpf_types.hpp:2232
static constexpr T Column
Definition: tpf_types.hpp:2234
static constexpr T Column
Definition: tpf_types.hpp:2261
static constexpr T Row
Definition: tpf_types.hpp:2259
static constexpr T Height
Definition: tpf_types.hpp:2257
static constexpr T Index
Definition: tpf_types.hpp:2221
This type is used to test validity of a type.
Definition: tpf_types.hpp:2020
This type is used to manipulate type list.
Definition: tpf_types.hpp:956
Stream output operators << are implemented.
String conversions are implemented.
Type functions are implemented.
#define Tpf_GetTypeName(type_arg)
A macro that returns type_arg's string name.
Definition: tpf_types.hpp:1422