C++ Library Extensions 2022.12.09
To help learn modern C++ programming
32-containers_for_variants.cpp
Go to the documentation of this file.
1#include <tpf_output.hpp>
2
3// clang++ -std=c++17 -Xclang -flto-visibility-public-std 32-containers_for_variants.cpp
4// g++ -std=c++17 32-containers_for_variants.cpp
5// cl /EHsc /std:c++17 32-containers_for_variants.cpp /Fe: a.exe
6
7namespace types = tpf::types;
8
9tpf::sstream stream; // string stream
10auto nl = tpf::nl; // "\n"
11auto endl = tpf::endl; // for flushing to console oupt
12
14{
15 using name_t = std::string;
16 using age_t = int;
17 using weight_t = double;
18
19 // container_t = std::vector< std::variant<name_t, age_t, weight_t> >
20 // container_t = std::vector< std::variant<std::string, int, double> >
21 // container_t = types::vector_of_variants_t<name_t, age_t, weight_t, age_t>;
23 using value_type = typename container_t::value_type;
24
25 stream << Tpf_GetTypeName(value_type) << endl;
26
27 container_t container; // std::vector< std::variant<std::string, int, double> >
28
29 container.emplace_back("Thomas Kim");
30 container.emplace_back(19);
31 container.emplace_back(22.0 /7.0);
32 container.emplace_back(30);
33 container.emplace_back(21.0 /7.0);
34 container.emplace_back("James Park");
35
36 auto& stream = ::stream;
37 auto& nl = ::nl;
38
39 // we are creating an instance of types::variant_visitors
40 auto handle_elements = types::make_variant_visitors
41 (
42 [&stream, &nl](auto&& name)
43 {
44 stream << "Name is " << name << nl;
45 },
46
47 [&stream, &nl](auto&& age)
48 {
49 stream << "Age is " << age << nl;
50 },
51
52 [&stream, &nl](auto&& weight)
53 {
54 stream << "Weight is " << weight << nl;
55 }
56 );
57
58 handle_elements.for_each(container);
59 stream << endl;
60
61 handle_elements.for_each_reverse(container);
62 stream << endl;
63
64 handle_elements.for_each( types::reverse(container) );
65 stream << endl;
66
67 // we are creating an instance of types::variant_visitors
68 auto handle_elements_with_iterator = types::make_variant_visitors
69 (
70 [&stream, &nl](auto&& itr, auto&& name)
71 {
72 stream << "Name is " << name << nl;
73
74 stream << "Type of iterator: "
75 << Tpf_GetTypeCategory(*itr) << nl;
76 },
77
78 [&stream, &nl](auto&& itr, auto&& age)
79 {
80 stream << "Age is " << age << nl;
81
82 stream << "Type of iterator: "
83 << Tpf_GetTypeCategory(*itr) << nl;
84 },
85
86 [&stream, &nl](auto&& itr, auto&& weight)
87 {
88 stream << "Weight is " << weight << nl;
89
90 stream << "Type of iterator: "
91 << Tpf_GetTypeCategory(*itr) << nl;
92 }
93 );
94
95 handle_elements_with_iterator.for_each_iterator(container);
96
97 stream << endl;
98
99 // we are creating an instance of types::variant_visitors
100 auto handle_elements_with_index = types::make_variant_visitors
101 (
102 [&stream, &nl, &container](auto index, auto&& name)
103 {
104 stream << index <<" - Name is " << name << nl;
105 },
106
107 [&stream, &nl, &container](auto index, auto&& age)
108 {
109 stream << index << " - Age is " << age << nl;
110 },
111
112 [&stream, &nl, &container](auto index, auto&& weight)
113 {
114 stream << index << " - Weight is " << weight << nl;
115 }
116 );
117
118 handle_elements_with_index.for_each_index(container);
119 stream << endl;
120
121 handle_elements_with_index.for_each_reverse_index(container);
122 stream << endl;
123
124 handle_elements_with_index.for_each_index(types::reverse(container));
125 stream << endl;
126
127 for(auto& vt: container)
128 {
129 //handle_elements(std::forward<decltype(vt)>(vt));
130 handle_elements(vt);
131 }
132
133 stream << endl;
134
135 for(auto& vt: types::reverse(container))
136 {
137 //handle_elements(std::forward<decltype(vt)>(vt));
138 handle_elements(vt);
139 }
140
141 stream << endl;
142}
143
146{
147 using name_t = std::string;
148 using age_t = int;
149 using weight_t = double;
150
151 // container_t = std::set< std::variant<name_t, age_t, weight_t> >
152 // container_t = std::set< std::variant<std::string, int, double> >
153 // container_t = types::set_of_variants_t<name_t, age_t, weight_t, age_t>;
155 using value_type = typename container_t::value_type;
156
157 stream << Tpf_GetTypeName(value_type) << endl;
158
159 container_t container; // std::set< std::variant<std::string, int, double> >
160
161 container.emplace("Thomas Kim");
162 container.emplace(19);
163 container.emplace(22.0 /7.0);
164 container.emplace(30);
165 container.emplace(21.0 /7.0);
166 container.emplace("James Park");
167
168 auto& stream = ::stream;
169 auto& nl = ::nl;
170
171 // we are creating an instance of types::variant_visitors
172 auto handle_elements = types::make_variant_visitors
173 (
174 [&stream, &nl](auto&& name)
175 {
176 stream << "Name is " << name << nl;
177 },
178
179 [&stream, &nl](auto&& age)
180 {
181 stream << "Age is " << age << nl;
182 },
183
184 [&stream, &nl](auto&& weight)
185 {
186 stream << "Weight is " << weight << nl;
187 }
188 );
189
190 handle_elements.for_each(container);
191 stream << endl;
192
193 handle_elements.for_each_reverse(container);
194 stream << endl;
195
196 handle_elements.for_each( types::reverse(container) );
197 stream << endl;
198
199 // we are creating an instance of types::variant_visitors
200 auto handle_elements_with_iterator = types::make_variant_visitors
201 (
202 [&stream, &nl](auto&& itr, auto&& name)
203 {
204 stream << "Name is " << name << nl;
205
206 stream << "Type of iterator: "
207 << Tpf_GetTypeCategory(*itr) << nl;
208 },
209
210 [&stream, &nl](auto&& itr, auto&& age)
211 {
212 stream << "Age is " << age << nl;
213
214 stream << "Type of iterator: "
215 << Tpf_GetTypeCategory(*itr) << nl;
216 },
217
218 [&stream, &nl](auto&& itr, auto&& weight)
219 {
220 stream << "Weight is " << weight << nl;
221
222 stream << "Type of iterator: "
223 << Tpf_GetTypeCategory(*itr) << nl;
224 }
225 );
226
227 handle_elements_with_iterator.for_each_iterator(container);
228
229 stream << endl;
230
231 // we are creating an instance of types::variant_visitors
232 auto handle_elements_with_index = types::make_variant_visitors
233 (
234 [&stream, &nl, &container](auto index, auto&& name)
235 {
236 stream << index <<" - Name is " << name << nl;
237 },
238
239 [&stream, &nl, &container](auto index, auto&& age)
240 {
241 stream << index << " - Age is " << age << nl;
242 },
243
244 [&stream, &nl, &container](auto index, auto&& weight)
245 {
246 stream << index << " - Weight is " << weight << nl;
247 }
248 );
249
250 handle_elements_with_index.for_each_index(container);
251 stream << endl;
252
253 handle_elements_with_index.for_each_reverse_index(container);
254 stream << endl;
255
256 handle_elements_with_index.for_each_index(types::reverse(container));
257 stream << endl;
258
259 for(auto& vt: container)
260 {
261 //handle_elements(std::forward<decltype(vt)>(vt));
262 handle_elements(vt);
263 }
264
265 stream << endl;
266
267 for(auto& vt: types::reverse(container))
268 {
269 //handle_elements(std::forward<decltype(vt)>(vt));
270 handle_elements(vt);
271 }
272
273 stream << endl;
274}
275
277{
278 using name_t = std::string;
279 using age_t = int;
280 using weight_t = double;
281
282 using vctr_t = std::vector<name_t>;
283
284 // using vctr_vt_t = types::deque_of_variants_t<age_t, weight_t>;
286
287 // container_t = std::vector< std::variant<name_t, age_t, weight_t> >
288 // container_t = std::vector< std::variant<std::string, int, double> >
289 // container_t = types::vector_of_variants_t<name_t, age_t, weight_t, vctr_t>;
291 using value_type = typename container_t::value_type;
292
293 // stream << Tpf_GetTypeName(value_type) << endl;
294
295 container_t container; // std::vector< std::variant<std::string, int, double> >
296
297 container.emplace_back("Thomas Kim");
298 container.emplace_back(19);
299 container.emplace_back(22.0 /7.0);
300 container.emplace_back(vctr_t{ "Sophie Turner", "Robert Park", "The Programmer"} );
301 container.emplace_back(30);
302 container.emplace_back(21.1 /7.0);
303 container.emplace_back("James Park");
304 container.emplace_back(vctr_vt_t{ 1, 2, 3, 1.5, 2.3, 4.6 } );
305
306
307
308 auto& stream = ::stream;
309 auto& nl = ::nl;
310
311 // we are creating an instance of types::variant_visitors
312 auto handle_elements = types::make_variant_visitors
313 (
314 [&stream, &nl](auto&& name)
315 {
316 stream << "Name is " << name << nl;
317 },
318
319 [&stream, &nl](auto&& age)
320 {
321 stream << "Age is " << age << nl;
322 },
323
324 [&stream, &nl](auto&& weight)
325 {
326 stream << "Weight is " << weight << nl;
327 },
328
329 [&stream, &nl](auto&& names) // vctr_t = std::vector<std::string>
330 {
331 stream << "Names: " << names << nl;
332 },
333
334 [&stream, &nl](auto&& vctr_vt) // vctr_vc_t = std::vector<std::variant<age_t, weight_t>>
335 {
337 (
338 [&stream, &nl](auto&& age)
339 {
340 stream <<"vctr_vc_t - age: " << age << nl;
341 },
342
343 [&stream, &nl](auto&& weight)
344 {
345 stream <<"vctr_vc_t - weight: " << weight << nl;
346 }
347
348 ).for_each(vctr_vt);
349 }
350 );
351
352 handle_elements.for_each(container);
353 stream << endl;
354
355}
356
358{
359 using key_t = const char*;
360 using name_t = std::string;
361 using age_t = int;
362 using weight_t = double;
363
364 using list_t = std::list<std::string>;
365
366 // container_t = std::map<key_t, std::variant<name_t, age_t, weight_t>>
368
369 container_t container;
370
371 container["Programmer"] = "Thomas Kim";
372 container["Age"] = 19;
373 container["Weight"] = 61.5;
374
375 container["Friend"] = "Sophie Turner";
376 container["Her Age"] = 17;
377 container["Her Weight"] = 55.5;
378
379 container["Old Buddies"] = list_t{"James", "Amie", "Robert", "Michelle"};
380
381 auto& stream = ::stream;
382 auto& nl = ::nl;
383
384 auto visitors = types::make_variant_visitors
385 (
386 [&stream, &nl](auto&& key, auto&& list)
387 {
388 stream << "\nIn the list: " << nl;
389
390 for(auto& n: list)
391 {
392 stream << key <<" is " << n << nl;
393 }
394
395 stream <<"End of list"<<nl << nl;
396 },
397
398 [&stream, &nl](auto&& key, auto&& name)
399 {
400 stream << key << " is " << name << nl;
401 },
402
403 [&stream, &nl](auto&& key, auto&& age)
404 {
405 stream << key << " is " << age << nl;
406 },
407
408 [&stream, &nl](auto&& key, auto&& weight)
409 {
410 stream << key << " is " << weight << nl;
411 }
412
413 );
414
415 visitors.for_each(container);
416 // flush to console
417 stream << endl;
418
419 visitors.for_each_reverse(container);
420 // flush to console
421 stream << endl;
422
423 for(auto& vt: container)
424 {
425 visitors(vt);
426 }
427
428 stream << endl;
429
430 auto visitors_with_iterator = types::make_variant_visitors
431 (
432 [&stream, &nl](auto&& itr, auto&& key, auto&& list)
433 {
434 // stream << "\nIn the list: " << nl;
435
436 // for(auto& n: list)
437 // {
438 // stream << key <<" is " << n << nl;
439 // }
440
441 // stream <<"End of list"<<nl << nl;
442
443 stream << "In the list: " << list << nl;
444 // stream << "Type of the element: "
445 // << Tpf_GetTypeCategory(*itr) << nl << nl;
446 },
447
448 [&stream, &nl](auto&& itr, auto&& key, auto&& name)
449 {
450 stream << key << " is " << name << nl;
451 // stream << "Type of the element: "
452 // << Tpf_GetTypeCategory(*itr) << nl << nl;
453 },
454
455 [&stream, &nl](auto&& itr, auto&& key, auto&& age)
456 {
457 stream << key << " is " << age << nl;
458 // stream << "Type of the element: "
459 // << Tpf_GetTypeCategory(*itr) << nl << nl;
460 },
461
462 [&stream, &nl](auto&& itr, auto&& key, auto&& weight)
463 {
464 stream << key << " is " << weight << nl;
465 // stream << "Type of the element: "
466 // << Tpf_GetTypeCategory(*itr) << nl << nl;
467 }
468 );
469
470 visitors_with_iterator.for_each_iterator(container);
471
472 stream << endl;
473}
474
477{
478 using key_t = const char*;
479 using name_t = std::string;
480 using age_t = int;
481 using weight_t = double;
482
483 using list_t = std::list<std::string>;
484
485 // container_t = std::unordered_map<key_t, std::variant<name_t, age_t, weight_t>>
487
488 /*
489 std::unordered_map does not support
490 reverse iterators
491 */
492
493 container_t container;
494
495 container["Programmer"] = "Thomas Kim";
496 container["Age"] = 19;
497 container["Weight"] = 61.5;
498
499 container["Friend"] = "Sophie Turner";
500 container["Her Age"] = 17;
501 container["Her Weight"] = 55.5;
502
503 container["Old Buddies"] = list_t{"James", "Amie", "Robert", "Michelle"};
504
505 auto& stream = ::stream;
506 auto& nl = ::nl;
507
508 auto visitors = types::make_variant_visitors
509 (
510 [&stream, &nl](auto&& key, auto&& list)
511 {
512 stream << "\nIn the list: " << nl;
513
514 for(auto& n: list)
515 {
516 stream << key <<" is " << n << nl;
517 }
518
519 stream <<"End of list"<<nl << nl;
520 },
521
522 [&stream, &nl](auto&& key, auto&& name)
523 {
524 stream << key << " is " << name << nl;
525 },
526
527 [&stream, &nl](auto&& key, auto&& age)
528 {
529 stream << key << " is " << age << nl;
530 },
531
532 [&stream, &nl](auto&& key, auto&& weight)
533 {
534 stream << key << " is " << weight << nl;
535 }
536
537 );
538
539 visitors.for_each(container);
540 // flush to console
541 stream << endl;
542
543 // visitors.for_each_reverse(container);
544 // // flush to console
545 // stream << endl;
546
547 for(auto& vt: container)
548 {
549 visitors(vt);
550 }
551
552 stream << endl;
553
554 auto visitors_with_iterator = types::make_variant_visitors
555 (
556 [&stream, &nl](auto&& itr, auto&& key, auto&& list)
557 {
558 // stream << "\nIn the list: " << nl;
559
560 // for(auto& n: list)
561 // {
562 // stream << key <<" is " << n << nl;
563 // }
564
565 // stream <<"End of list"<<nl << nl;
566
567 stream << "In the list: " << list << nl;
568 // stream << "Type of the element: "
569 // << Tpf_GetTypeCategory(*itr) << nl << nl;
570 },
571
572 [&stream, &nl](auto&& itr, auto&& key, auto&& name)
573 {
574 stream << key << " is " << name << nl;
575 // stream << "Type of the element: "
576 // << Tpf_GetTypeCategory(*itr) << nl << nl;
577 },
578
579 [&stream, &nl](auto&& itr, auto&& key, auto&& age)
580 {
581 stream << key << " is " << age << nl;
582 // stream << "Type of the element: "
583 // << Tpf_GetTypeCategory(*itr) << nl << nl;
584 },
585
586 [&stream, &nl](auto&& itr, auto&& key, auto&& weight)
587 {
588 stream << key << " is " << weight << nl;
589 // stream << "Type of the element: "
590 // << Tpf_GetTypeCategory(*itr) << nl << nl;
591 }
592 );
593
594 visitors_with_iterator.for_each_iterator(container);
595
596 stream << endl;
597}
598
599
600int main()
601{
602 // test_vector_of_variants();
603
604 // test_set_of_variants();
605
606 // test_vector_of_variant_with_vector();
607
608 // test_map_of_variants();
609
611}
std::list< Type > list_t
tpf::sstream stream
void test_vector_of_variant_with_vector()
void test_map_of_variants()
void test_unordered_map_of_variants()
void test_vector_of_variants()
void test_set_of_variants()
constexpr auto reverse(sequence< ms... > mm, sequence< rs... >)
Definition: cpg_types.hpp:4248
Type to string name conversions are defined.
Definition: 31-visit.cpp:7
hidden::vector_of_variants_t< ElementTypes... > vector_of_variants_t
Definition: tpf_types.hpp:6621
hidden::map_of_variants_t< KeyType, ElementTypes... > map_of_variants_t
Definition: tpf_types.hpp:6645
hidden::set_of_variants_t< ElementTypes... > set_of_variants_t
Definition: tpf_types.hpp:6630
variant_visitors< remove_cv_ref_t< CallbackTypes >... > make_variant_visitors(CallbackTypes &&... visitors)
Definition: tpf_types.hpp:7891
hidden::unordered_map_of_variants_t< KeyType, ElementTypes... > unordered_map_of_variants_t
Definition: tpf_types.hpp:6651
hidden::container_of_variants_t< ContainerType, ElementTypes... > container_of_variants_t
Definition: tpf_types.hpp:6618
constexpr auto endl
Definition: tpf_output.hpp:973
constexpr auto nl
Definition: tpf_output.hpp:971
Stream output operators << are implemented.
#define Tpf_GetTypeName(type_arg)
A macro that returns type_arg's string name.
Definition: tpf_types.hpp:1422
#define Tpf_GetTypeCategory(instance_arg)
A macro that returns instance_arg's type category string name.
Definition: tpf_types.hpp:1428