C++ Library Extensions 2022.12.09
To help learn modern C++ programming
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
28-visit.cpp
Go to the documentation of this file.
1#include <tpf_output.hpp>
2
5
6namespace tpf::types
7{
8 template<size_t StartIndex, size_t EndIndex>
9 struct compile_time_loop
10 {
11 template<typename VisitorType, typename VariantType>
12 static void visit_variant(VisitorType&& visitor, VariantType&& vt)
13 {
14 if constexpr(StartIndex < EndIndex)
15 {
16 if(auto ptr = std::get_if<StartIndex>(&vt))
17 {
18 std::forward<VisitorType>(visitor)(*ptr);
19 return;
20 }
21 }
22
23 if constexpr (StartIndex + 1 < EndIndex)
24 {
26 visit_variant(std::forward<VisitorType>(visitor) , std::forward<VariantType>(vt));
27 }
28 }
29
30 }; // end of struct compile_time_loop
31
32 template<typename VisitorType, typename VariantType>
33 void visit(VisitorType&& visitor, VariantType&& vt)
34 {
35 using variant_t = remove_cv_ref_t<VariantType>;
36 // cppreference.com - std::variant_size_v
37 // https://en.cppreference.com/w/cpp/utility/variant/variant_size
38 constexpr size_t VariantSize = std::variant_size_v<variant_t>;
39
41 visit_variant(std::forward<VisitorType>(visitor), std::forward<VariantType>(vt));
42 }
43
44 template<typename... VisitorTypes>
45 struct overloaded: public VisitorTypes... // mixin
46 {
47 using VisitorTypes::operator()...;
48
49 overloaded(VisitorTypes... visitors):
50 VisitorTypes{visitors}... { }
51 };
52
53 // template argument deduction guide
54 // this feature was introduced to C++17 Standards
55 template<typename... VisitorTypes>
56 overloaded(VisitorTypes...) -> overloaded<VisitorTypes...>;
57
58} // end of namespace tpf::types
59
60namespace types = tpf::types;
61
63{
64 using name_t = const char*;
65 using age_t = int;
66 using weight_t = double;
67 using variant_t = std::variant<name_t, age_t, weight_t>;
68
69 using container_t = std::vector<variant_t>;
70
71 container_t info;
72
73 info.emplace_back("Thomas Kim");
74 info.emplace_back(30);
75 info.emplace_back(60.5);
76 info.emplace_back("Sophie Turner");
77 info.emplace_back(20);
78 info.emplace_back(56.7);
79
81 auto endl = tpf::endl;
82
83 types::overloaded handle_info_const_ref
84 {
85 [&stream, &endl](const name_t& name)
86 {
87 stream <<"Name is " << name << endl;
88 },
89
90 [&stream, &endl](const age_t& age)
91 {
92 stream <<"Age is " << age << endl;
93 },
94
95 [&stream, &endl](const weight_t& weight)
96 {
97 stream << "Weight is " << weight << endl;
98 },
99
100 // catch all if failed
101 [&stream, &endl](auto&& value)
102 {
103 stream << "Unclassified: " << value << endl;
104 stream << "Type: " << Tpf_GetTypeCategory(value) << endl;
105 }
106 };
107
108 types::overloaded handle_info_ref
109 {
110 [&stream, &endl](name_t& name)
111 {
112 stream <<"Name is " << name << endl;
113 },
114
115 [&stream, &endl](age_t& age)
116 {
117 stream <<"Age is " << age << endl;
118 },
119
120 [&stream, &endl](weight_t& weight)
121 {
122 stream << "Weight is " << weight << endl;
123 },
124
125 // catch all if failed
126 [&stream, &endl](auto&& value)
127 {
128 stream << "Unclassified: " << value << endl;
129 stream << "Type: " << Tpf_GetTypeCategory(value) << endl;
130 }
131 };
132
133 for(const auto& vt: info)
134 {
135 types::visit(handle_info_const_ref, vt);
136 }
137
138 stream << endl;
139
140 for(auto& vt: info)
141 {
142 types::visit(handle_info_ref, vt);
143 }
144
145 stream << endl;
146
148 for(const auto& vt: info)
149 {
150 std::visit(handle_info_const_ref, vt);
151 }
152
153 stream << endl;
154
155 for(auto& vt: info)
156 {
157 std::visit(handle_info_ref, vt);
158 }
159
160 stream << endl;
161}
162
163int main()
164{
166}
void test_visit_basic()
Definition: 28-visit.cpp:62
tpf::sstream stream
Definition: 28-visit.cpp:3
auto endl
Definition: 28-visit.cpp:4
int main()
Definition: 28-visit.cpp:163
Type to string name conversions are defined.
Definition: 31-visit.cpp:7
enable_if_variant_t< VariantType > visit(VisitorType &&visitor, VariantType &&vt)
Definition: 31-visit.cpp:118
overloaded(VisitorTypes...) -> overloaded< VisitorTypes... >
void visit(VisitorType &&visitor, VariantType &&vt)
Definition: 28-visit.cpp:33
std::enable_if_t< is_pair_of_variant_v< remove_cv_ref_t< PairType > > > visit_variant(VisitorType &&visit, PairType &&vpr)
Definition: tpf_types.hpp:7740
std::remove_cv_t< std::remove_reference_t< Type > > remove_cv_ref_t
Remove const volatile reference from Type.
Definition: tpf_types.hpp:151
constexpr auto endl
Definition: tpf_output.hpp:973
static void visit_variant(VisitorType &&visitor, VariantType &&vt)
Definition: 28-visit.cpp:12
static enable_if_variant_t< VariantType > visit_variant(VisitorType &&visitor, VariantType &&vt)
Definition: 31-visit.cpp:70
overloaded(VisitorTypes... visitors)
Definition: 28-visit.cpp:49
Stream output operators << are implemented.
#define Tpf_GetTypeCategory(instance_arg)
A macro that returns instance_arg's type category string name.
Definition: tpf_types.hpp:1428