KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_ki_any.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20// Tests taken from GCC:
21// Copyright (C) 2014-2024 Free Software Foundation, Inc.
22//
23// This file is part of the GNU ISO C++ Library. This library is free
24// software; you can redistribute it and/or modify it under the
25// terms of the GNU General Public License as published by the
26// Free Software Foundation; either version 3, or (at your option)
27// any later version.
28
29// This library is distributed in the hope that it will be useful,
30// but WITHOUT ANY WARRANTY; without even the implied warranty of
31// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32// GNU General Public License for more details.
33
34// Under Section 7 of GPL version 3, you are granted additional
35// permissions described in the GCC Runtime Library Exception, version
36// 3.1, as published by the Free Software Foundation.
37
38// You should have received a copy of the GNU General Public License and
39// a copy of the GCC Runtime Library Exception along with this program;
40// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
41// <http://www.gnu.org/licenses/>.
42
43#include <boost/test/unit_test.hpp>
44
45#include <cstdint>
46#include <memory>
47#include <set>
48#include <utility>
49#include <type_traits>
50
51#include <ki_any.h>
52
53using ki::any;
54using ki::any_cast;
55
57// Exception hierarchy
60static_assert(std::is_base_of<std::bad_cast, ki::bad_any_cast>::value,
61 "ki::bad_any_cast must derive from std::bad_cast");
62
64// Type requirements
66
67static_assert(std::is_assignable<any&, int>::value);
68static_assert(!std::is_assignable<any&, std::unique_ptr<int>>::value);
69static_assert(std::is_constructible<any, int>::value);
70static_assert(!std::is_constructible<any, std::unique_ptr<int>>::value);
71static_assert(!std::is_assignable<any&, const std::unique_ptr<int>&>::value);
72static_assert(!std::is_constructible<any&, const std::unique_ptr<int>&>::value);
73static_assert(!std::is_assignable<any&, std::unique_ptr<int>&>::value);
74static_assert(!std::is_constructible<any&, std::unique_ptr<int>&>::value);
75
77{
78 NoDefaultCtor() = delete;
79};
80
81static_assert(!std::is_constructible_v<any,
82 std::in_place_type_t<NoDefaultCtor>>);
83
84static_assert(!std::is_constructible_v<any,
85 std::in_place_type_t<NoDefaultCtor>&>);
86
87static_assert(!std::is_constructible_v<any,
88 std::in_place_type_t<NoDefaultCtor>&&>);
89
90static_assert(!std::is_constructible_v<any,
91 const std::in_place_type_t<NoDefaultCtor>&>);
92
93static_assert(!std::is_constructible_v<any,
94 const std::in_place_type_t<NoDefaultCtor>&&>);
95
96static_assert( std::is_copy_constructible_v<std::tuple<any>> );
97
98struct A {
99 A(const A&) = default;
100 explicit A(any value);
101};
102static_assert(std::is_copy_constructible_v<A>);
103
104BOOST_AUTO_TEST_SUITE( ki_any )
105
106struct combined {
107 std::vector<int> v;
108 std::tuple<int, int> t;
109 template<class... Args>
110 combined(std::initializer_list<int> il, Args&&... args)
111 : v(il), t(std::forward<Args>(args)...)
112 {
113 }
114};
115
116
118{
119 using std::string;
120 using std::strcmp;
121
122 any x(5); // x holds int
123 BOOST_CHECK(any_cast<int>(x) == 5); // cast to value
124 any_cast<int&>(x) = 10; // cast to reference
125 BOOST_CHECK(any_cast<int>(x) == 10);
126
127 x = "Meow"; // x holds const char*
128 BOOST_CHECK(strcmp(any_cast<const char*>(x), "Meow") == 0);
129 any_cast<const char*&>(x) = "Harry";
130 BOOST_CHECK(strcmp(any_cast<const char*>(x), "Harry") == 0);
131
132 x = string("Meow"); // x holds string
133 string s, s2("Jane");
134 s = std::move(any_cast<string&>(x)); // move from any
135 BOOST_CHECK(s == "Meow");
136 any_cast<string&>(x) = std::move(s2); // move to any
137 BOOST_CHECK(any_cast<const string&>(x) == "Jane");
138
139 string cat("Meow");
140 const any y(cat); // const y holds string
141 BOOST_CHECK(any_cast<const string&>(y) == cat);
142}
143
144
146{
147 using ki::bad_any_cast;
148 any x(1);
149 auto p = any_cast<double>(&x);
150 BOOST_CHECK(p == nullptr);
151
152 x = 1.0;
153 p = any_cast<double>(&x);
154 BOOST_CHECK(p != nullptr);
155
156 x = any();
157 p = any_cast<double>(&x);
158 BOOST_CHECK(p == nullptr);
159
160 try {
161 any_cast<double>(x);
162 BOOST_CHECK(false);
163 } catch (const bad_any_cast&) {
164 }
165}
166
167static int move_count = 0;
168
170{
171 struct MoveEnabled
172 {
173 MoveEnabled(MoveEnabled&&)
174 {
175 ++move_count;
176 }
177 MoveEnabled() = default;
178 MoveEnabled(const MoveEnabled&) = default;
179 };
180 MoveEnabled m;
181 MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
182 BOOST_CHECK(move_count == 1);
183 MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
184 BOOST_CHECK(move_count == 1);
185}
186
187
189{
190 struct ExplicitCopy
191 {
192 ExplicitCopy() = default;
193 explicit ExplicitCopy(const ExplicitCopy&) = default;
194 };
195 any x = ExplicitCopy();
196 ExplicitCopy ec{any_cast<ExplicitCopy>(x)};
197 ExplicitCopy ec2{any_cast<ExplicitCopy>(std::move(x))};
198}
199
200
202{
203 struct noncopyable {
204 noncopyable(noncopyable const&) = delete;
205 };
206
207 any a;
208 auto p = any_cast<noncopyable>(&a);
209 BOOST_CHECK( p == nullptr );
210}
211
212
214{
215 // The contained value of a std::any is always an object type,
216 // but any_cast does not forbid checking for function types.
217
218 any a(1);
219 void (*p1)() = any_cast<void()>(&a);
220 BOOST_CHECK( p1 == nullptr );
221 int (*p2)(int) = any_cast<int(int)>(&a);
222 BOOST_CHECK( p2 == nullptr );
223 int (*p3)() = any_cast<int()>(&std::as_const(a));
224 BOOST_CHECK( p3 == nullptr );
225
226 try {
227 any_cast<int(&)()>(a);
228 BOOST_CHECK( false );
229 } catch (const ki::bad_any_cast&) {
230 }
231
232 try {
233 any_cast<int(&)()>(std::move(a));
234 BOOST_CHECK( false );
235 } catch (const ki::bad_any_cast&) {
236 }
237
238 try {
239 any_cast<int(&)()>(std::as_const(a));
240 BOOST_CHECK( false );
241 } catch (const ki::bad_any_cast&) {
242 }
243}
244
245
247{
248 int arr[3];
249 any a(arr);
250
251 BOOST_CHECK( a.type() == typeid(int*) ); // contained value is decayed
252 int (*p1)[3] = any_cast<int[3]>(&a);
253 BOOST_CHECK( a.type() != typeid(int[3]) ); // so any_cast should return nullptr
254 BOOST_CHECK( p1 == nullptr );
255 int (*p2)[] = any_cast<int[]>(&a);
256 BOOST_CHECK( a.type() != typeid(int[]) ); // so any_cast should return nullptr
257 BOOST_CHECK( p2 == nullptr );
258 const int (*p3)[] = any_cast<int[]>(&std::as_const(a));
259 BOOST_CHECK( p3 == nullptr );
260}
261
262
264{
266 ~LocationAware() { BOOST_CHECK(self == this); }
268 LocationAware& operator=(const LocationAware&) { return *this; }
270 LocationAware& operator=(LocationAware&&) noexcept { return *this; }
271
272 void* const self = this;
273};
274static_assert(std::is_nothrow_move_constructible<LocationAware>::value, "");
275static_assert(!std::is_trivially_copyable<LocationAware>::value, "");
276
277
278BOOST_AUTO_TEST_CASE( NonTrivialType_1 )
279{
281 any a = l;
282}
283
284
285BOOST_AUTO_TEST_CASE( NonTrivialType_2 )
286{
288 any a = l;
289 any b = a;
290 {
291 any tmp = std::move(a);
292 a = std::move(b);
293 b = std::move(tmp);
294 }
295}
296
297
298BOOST_AUTO_TEST_CASE( NonTrivialType_3 )
299{
301 any a = l;
302 any b = a;
303 swap(a, b);
304}
305
306
308{
309 const int i = 42;
310 auto o = ki::make_any<int>(i);
311 int& i2 = any_cast<int&>(o);
312 BOOST_CHECK( i2 == 42 );
313 BOOST_CHECK( &i2 != &i );
314 auto o2 = ki::make_any<std::tuple<int, int>>(1, 2);
315 std::tuple<int, int>& t = any_cast<std::tuple<int, int>&>(o2);
316 BOOST_CHECK( std::get<0>(t) == 1 && std::get<1>(t) == 2);
317 auto o3 = ki::make_any<std::vector<int>>({42, 666});
318 std::vector<int>& v = any_cast<std::vector<int>&>(o3);
319 BOOST_CHECK(v[0] == 42 && v[1] == 666);
320 auto o4 = ki::make_any<combined>({42, 666});
321 combined& c = any_cast<combined&>(o4);
322 BOOST_CHECK(c.v[0] == 42 && c.v[1] == 666
323 && std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
324 auto o5 = ki::make_any<combined>({1, 2}, 3, 4);
325 combined& c2 = any_cast<combined&>(o5);
326 BOOST_CHECK(c2.v[0] == 1 && c2.v[1] == 2
327 && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
328}
329
330
331BOOST_AUTO_TEST_CASE( TypeObserver )
332{
333 any x;
334 BOOST_CHECK( x.type() == typeid(void) );
335 x = 1;
336 BOOST_CHECK( x.type() == typeid(int) );
337 x = any();
338 BOOST_CHECK( x.type() == typeid(void) );
339}
340
341
343{
344 any x(1);
345 any y;
346 swap(x, y);
347 BOOST_CHECK( !x.has_value() );
348 BOOST_CHECK( y.has_value() );
349}
350
351
353{
354 any x(1);
355 any y;
356 x.swap(y);
357 BOOST_CHECK( !x.has_value() );
358 BOOST_CHECK( y.has_value() );
359 x.swap(y);
360 BOOST_CHECK( x.has_value() );
361 BOOST_CHECK( !y.has_value() );
362
363 x.reset();
364 BOOST_CHECK( !x.has_value() );
365}
366
367
368BOOST_AUTO_TEST_CASE( Construction_InPlace_1 )
369{
370 const int i = 42;
371 any o(std::in_place_type<int>, i);
372 int& i2 = any_cast<int&>(o);
373 BOOST_CHECK( i2 == 42 );
374 BOOST_CHECK( &i2 != &i );
375 any o2(std::in_place_type<std::tuple<int, int>>, 1, 2);
376 std::tuple<int, int>& t = any_cast<std::tuple<int, int>&>(o2);
377 BOOST_CHECK( std::get<0>(t) == 1 && std::get<1>(t) == 2);
378 any o3(std::in_place_type<std::vector<int>>, {42, 666});
379 std::vector<int>& v = any_cast<std::vector<int>&>(o3);
380 BOOST_CHECK(v[0] == 42 && v[1] == 666);
381 any o4(std::in_place_type<combined>, {42, 666});
382 combined& c = any_cast<combined&>(o4);
383 BOOST_CHECK(c.v[0] == 42 && c.v[1] == 666
384 && std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
385 any o5(std::in_place_type<combined>, {1, 2}, 3, 4);
386 combined& c2 = any_cast<combined&>(o5);
387 BOOST_CHECK(c2.v[0] == 1 && c2.v[1] == 2
388 && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
389 any o6(std::in_place_type<int&>, i);
390 BOOST_CHECK(o6.type() == o.type());
391 any o7(std::in_place_type<void()>, nullptr);
392 any o8(std::in_place_type<void(*)()>, nullptr);
393 BOOST_CHECK(o7.type() == o8.type());
394 any o9(std::in_place_type<char(&)[42]>, nullptr);
395 any o10(std::in_place_type<char*>, nullptr);
396 BOOST_CHECK(o9.type() == o10.type());
397}
398
399bool moved = false;
400bool copied = false;
401
402struct X
403{
404 X() = default;
405 X(const X&) { copied = true; }
406 X(X&&) { moved = true; }
407};
408
409struct X2
410{
411 X2() = default;
412 X2(const X2&) { copied = true; }
413 X2(X2&&) noexcept { moved = true; }
414};
415
416
417BOOST_AUTO_TEST_CASE( Construction_Basic_1 )
418{
419 moved = false;
420 X x;
421 any a1(x);
422 BOOST_CHECK(moved == false);
423 any a2(std::move(x));
424 BOOST_CHECK(moved == true);
425}
426
427
428BOOST_AUTO_TEST_CASE( Construction_Basic_2 )
429{
430 moved = false;
431 X x;
432 any a1(x);
433 BOOST_CHECK(moved == false);
434 copied = false;
435 any a2(std::move(a1));
436 BOOST_CHECK(copied == false);
437}
438
439
440BOOST_AUTO_TEST_CASE( Construction_Basic_3 )
441{
442 moved = false;
443 X2 x;
444 any a1(x);
445 BOOST_CHECK(moved == false);
446 copied = false;
447 any a2(std::move(a1));
448 BOOST_CHECK(copied == false);
449 BOOST_CHECK(moved == true);
450}
451
452
453BOOST_AUTO_TEST_CASE( Construction_Basic_4)
454{
455 any x;
456 BOOST_CHECK( !x.has_value() );
457
458 any y(x);
459 BOOST_CHECK( !x.has_value() );
460 BOOST_CHECK( !y.has_value() );
461
462 any z(std::move(y));
463 BOOST_CHECK( !y.has_value() );
464 BOOST_CHECK( !z.has_value() );
465}
466
467
468BOOST_AUTO_TEST_CASE( Construction_Basic_5)
469{
470 any x(1);
471 BOOST_CHECK( x.has_value() );
472
473 any y(x);
474 BOOST_CHECK( x.has_value() );
475 BOOST_CHECK( y.has_value() );
476
477 any z(std::move(y));
478 BOOST_CHECK( !y.has_value() );
479 BOOST_CHECK( z.has_value() );
480}
481
482
483BOOST_AUTO_TEST_CASE( Construction_InPlace_2 )
484{
485 auto a = any(std::in_place_type<any>, 5);
486 BOOST_CHECK( any_cast<int>(any_cast<any>(a)) == 5 );
487}
488
489
490BOOST_AUTO_TEST_CASE( Construction_Pair )
491{
492 any p = std::pair<any, any>(1, 1);
493 auto pt = any_cast<std::pair<any, any>>(p);
494 BOOST_CHECK( any_cast<int>(pt.first) == 1 );
495 BOOST_CHECK( any_cast<int>(pt.second) == 1 );
496
497 any t = std::tuple<any>(1);
498 auto tt = any_cast<std::tuple<any>>(t);
499 BOOST_CHECK( any_cast<int>(std::get<0>(tt)) == 1 );
500}
501
502
503// Alignment requiremnts of this type prevent it being stored in 'any'
504struct alignas(2 * alignof(void*)) X3 { };
505
506bool
507stored_internally(void* obj, const ki::any& a)
508{
509 std::uintptr_t a_addr = reinterpret_cast<std::uintptr_t>(&a);
510 std::uintptr_t a_end = a_addr + sizeof(a);
511 std::uintptr_t obj_addr = reinterpret_cast<std::uintptr_t>(obj);
512 return (a_addr <= obj_addr) && (obj_addr < a_end);
513}
514
515
516BOOST_AUTO_TEST_CASE( Construction_Alignment )
517{
518 any a = X3{};
519 X3& x = any_cast<X3&>(a);
520 BOOST_CHECK( !stored_internally(&x, a) );
521
522 a = 'X';
523 char& c = any_cast<char&>(a);
524 BOOST_CHECK( stored_internally(&c, a) );
525}
526
528{
529 wrapper() = default;
530
531 wrapper(const any& t);
532
533 wrapper(const wrapper& w);
534
535 auto& operator=(const any& t);
536
537 auto& operator=(const wrapper& w)
538 {
539 value = w.value;
540 return *this;
541 }
542
544};
545
546BOOST_AUTO_TEST_CASE( Construction_Wrapper )
547{
548 wrapper a, b;
549 a = b;
550}
551
552// Following tests commented out until Apple Clang build version >= 16
553/*
554struct aggressive_aggregate
555{
556 int a;
557 int b;
558};
559
560BOOST_AUTO_TEST_CASE( Construction_Aggregate_1 )
561{
562 any x{std::in_place_type<aggressive_aggregate>, 1, 2};
563 BOOST_CHECK(any_cast<aggressive_aggregate>(x).a == 1);
564 BOOST_CHECK(any_cast<aggressive_aggregate>(x).b == 2);
565 any y{std::in_place_type<aggressive_aggregate>, 1};
566 BOOST_CHECK(any_cast<aggressive_aggregate>(y).a == 1);
567 BOOST_CHECK(any_cast<aggressive_aggregate>(y).b == 0);
568 any z{std::in_place_type<aggressive_aggregate>};
569 BOOST_CHECK(any_cast<aggressive_aggregate>(z).a == 0);
570 BOOST_CHECK(any_cast<aggressive_aggregate>(z).b == 0);
571}
572
573BOOST_AUTO_TEST_CASE( Construction_Aggregate_2 )
574{
575 any x;
576 x.emplace<aggressive_aggregate>(1, 2);
577 BOOST_CHECK(any_cast<aggressive_aggregate>(x).a == 1);
578 BOOST_CHECK(any_cast<aggressive_aggregate>(x).b == 2);
579 x.emplace<aggressive_aggregate>(1);
580 BOOST_CHECK(any_cast<aggressive_aggregate>(x).a == 1);
581 BOOST_CHECK(any_cast<aggressive_aggregate>(x).b == 0);
582 x.emplace<aggressive_aggregate>();
583 BOOST_CHECK(any_cast<aggressive_aggregate>(x).a == 0);
584 BOOST_CHECK(any_cast<aggressive_aggregate>(x).b == 0);
585}
586
587*/
588
589std::set<const void*> live_objects;
590
591struct A {
592 A() { live_objects.insert(this); }
593 ~A() { live_objects.erase(this); }
594 A(const A& a) { BOOST_CHECK(live_objects.count(&a)); live_objects.insert(this); }
595};
596
598{
599 any a;
600 a = a;
601 BOOST_CHECK( !a.has_value() );
602
603 a = A{};
604 a = a;
605 BOOST_CHECK( a.has_value() );
606
607 a.reset();
608 BOOST_CHECK( live_objects.empty() );
609}
610
611
613{
614 struct X {
615 any a;
616 };
617
618 X x;
619 std::swap(x, x); // results in "self-move-assignment" of X::a
620 BOOST_CHECK( !x.a.has_value() );
621
622 x.a = A{};
623 std::swap(x, x); // results in "self-move-assignment" of X::a
624 BOOST_CHECK( x.a.has_value() );
625
626 x.a.reset();
627 BOOST_CHECK( live_objects.empty() );
628}
629
630
632{
633 any a;
634 a.swap(a);
635 BOOST_CHECK( !a.has_value() );
636
637 a = A{};
638 a.swap(a);
639 BOOST_CHECK( a.has_value() );
640
641 a.reset();
642 BOOST_CHECK( live_objects.empty() );
643}
644
645
647{
648 moved = false;
649 X x;
650 any a1;
651 a1 = x;
652 BOOST_CHECK(moved == false);
653 any a2;
654 copied = false;
655 a2 = std::move(x);
656 BOOST_CHECK(moved == true);
657 BOOST_CHECK(copied == false);
658}
659
660
662{
663 moved = false;
664 X x;
665 any a1;
666 a1 = x;
667 BOOST_CHECK(moved == false);
668 any a2;
669 copied = false;
670 a2 = std::move(a1);
671 BOOST_CHECK(moved == false);
672 BOOST_CHECK(copied == false);
673}
674
675
677{
678 moved = false;
679 X2 x;
680 any a1;
681 a1 = x;
682 BOOST_CHECK(copied && moved);
683 any a2;
684 moved = false;
685 copied = false;
686 a2 = std::move(a1);
687 BOOST_CHECK(moved == true);
688 BOOST_CHECK(copied == false);
689}
690
692{
693 any x;
694 any y;
695 y = x;
696 BOOST_CHECK( !x.has_value() );
697 BOOST_CHECK( !y.has_value() );
698
699 y = std::move(x);
700 BOOST_CHECK( !x.has_value() );
701 BOOST_CHECK( !y.has_value() );
702}
703
705{
706 any x(1);
707 any y;
708 y = x;
709 BOOST_CHECK( x.has_value() );
710 BOOST_CHECK( y.has_value() );
711
712 x = std::move(y);
713 BOOST_CHECK( x.has_value() );
714 BOOST_CHECK( !y.has_value() );
715
716 x = y;
717 BOOST_CHECK( !x.has_value() );
718 BOOST_CHECK( !y.has_value() );
719}
720
721
722bool should_throw = false;
723struct Bad
724{
725 Bad() = default;
726 Bad(const Bad&) {if (should_throw) throw 666;}
727};
728
729struct Bad2
730{
731 Bad2() = default;
732 Bad2(const Bad2&) {if (should_throw) throw 666;}
733 Bad2(Bad2&&) noexcept {}
734};
735
736int del_count = 0;
737struct Good
738{
739 Good() = default;
740 Good(const Good&) = default;
741 Good(Good&&) = default;
743};
744
746{
747 any a1 = Good();
748 del_count = 0;
749 try {
750 Bad b;
751 any a2 = b;
752 should_throw = true;
753 a1 = a2;
754 } catch (...) {
755 auto x = any_cast<Good>(a1);
756 BOOST_CHECK( del_count == 0 );
757 BOOST_CHECK( a1.has_value() );
758 any_cast<Good>(a1);
759 }
760 any a3 = Good();
761 del_count = 0;
762 try {
763 Bad2 b;
764 any a4 = b;
765 should_throw = true;
766 a3 = a4;
767 } catch (...) {
768 auto x = any_cast<Good>(a1);
769 BOOST_CHECK( del_count == 0 );
770 BOOST_CHECK( a1.has_value() );
771 any_cast<Good>(a1);
772 }
773}
774
775
777{
778 const int i = 42;
779 any o;
780 o.emplace<int>(i);
781 int& i2 = any_cast<int&>(o);
782 BOOST_CHECK( i2 == 42 );
783 BOOST_CHECK( &i2 != &i );
784 any o2;
785 o2.emplace<std::tuple<int, int>>(1, 2);
786 std::tuple<int, int>& t = any_cast<std::tuple<int, int>&>(o2);
787 BOOST_CHECK( std::get<0>(t) == 1 && std::get<1>(t) == 2);
788 any o3;
789 o3.emplace<std::vector<int>>({42, 666});
790 std::vector<int>& v = any_cast<std::vector<int>&>(o3);
791 BOOST_CHECK(v[0] == 42 && v[1] == 666);
792 any o4;
793 o4.emplace<combined>({42, 666});
794 combined& c = any_cast<combined&>(o4);
795 BOOST_CHECK(c.v[0] == 42 && c.v[1] == 666
796 && std::get<0>(c.t) == 0 && std::get<1>(c.t) == 0 );
797 any o5;
798 o5.emplace<combined>({1, 2}, 3, 4);
799 combined& c2 = any_cast<combined&>(o5);
800 BOOST_CHECK(c2.v[0] == 1 && c2.v[1] == 2
801 && std::get<0>(c2.t) == 3 && std::get<1>(c2.t) == 4 );
802 any o6;
803 o6.emplace<const int&>(i);
804 BOOST_CHECK(o6.type() == o.type());
805 any o7;
806 o7.emplace<void()>(nullptr);
807 any o8;
808 o8.emplace<void(*)()>(nullptr);
809 BOOST_CHECK(o7.type() == o8.type());
810 any o9;
811 o9.emplace<char(&)[42]>(nullptr);
812 any o10;
813 o10.emplace<char*>(nullptr);
814 BOOST_CHECK(o9.type() == o10.type());
815 any o11;
816 BOOST_CHECK(&o11.emplace<int>(42) == &any_cast<int&>(o11));
817 BOOST_CHECK(&o11.emplace<std::vector<int>>({1,2,3}) ==
818 &any_cast<std::vector<int>&>(o11));
819}
820
821
822
823struct X_e
824{
825 X_e() = default;
826 X_e(const X_e&) { copied = true; }
827 X_e(X_e&&) { moved = true; }
828};
829
830struct X2_e
831{
832 X2_e() = default;
833 X2_e(const X2_e&) { copied = true; }
834 X2_e(X2_e&&) noexcept { moved = true; }
835};
836
837
A type-safe container of any type.
Definition: ki_any.h:93
bool has_value() const noexcept
Report whether there is a contained object or not.
Definition: ki_any.h:312
void reset() noexcept
If not empty, destroys the contained object.
Definition: ki_any.h:272
void swap(any &rhs) noexcept
Exchange state with another object.
Definition: ki_any.h:282
any_emplace_t< std::decay_t< T >, Args... > emplace(Args &&... args)
Emplace with an object created from args as the contained object.
Definition: ki_any.h:254
const std::type_info & type() const noexcept
The typeid of the contained object, or typeid(void) if empty.
Definition: ki_any.h:316
Exception class thrown by a failed any_cast.
Definition: ki_any.h:81
An implementation of std::any_cast, which uses type_info::hash_code to check validity of cast types.
ValueType any_cast(const any &any)
Access the contained object.
Definition: ki_any.h:446
STL namespace.
A(any value)
~A()
A(const A &)=default
A(const A &a)
Bad2(Bad2 &&) noexcept
Bad2()=default
Bad2(const Bad2 &)
Bad(const Bad &)
Bad()=default
Good()=default
Good(const Good &)=default
Good(Good &&)=default
void *const self
LocationAware & operator=(const LocationAware &)
LocationAware(LocationAware &&) noexcept
LocationAware(const LocationAware &)
LocationAware & operator=(LocationAware &&) noexcept
NoDefaultCtor()=delete
X2_e(const X2_e &)
X2_e()=default
X2_e(X2_e &&) noexcept
X2()=default
X2(const X2 &)
X2(X2 &&) noexcept
X_e()=default
X_e(const X_e &)
X_e(X_e &&)
X()=default
X(X &&)
X(const X &)
std::vector< int > v
combined(std::initializer_list< int > il, Args &&... args)
std::tuple< int, int > t
wrapper(const any &t)
wrapper(const wrapper &w)
wrapper()=default
auto & operator=(const any &t)
auto & operator=(const wrapper &w)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
bool stored_internally(void *obj, const ki::any &a)
bool should_throw
bool copied
BOOST_AUTO_TEST_CASE(AnyCast_1)
std::set< const void * > live_objects
int del_count
bool moved
static int move_count
MATRIX3x3D m2(VECTOR3I{ 6, 6, 6 }, { 1, 1, 1 }, { 3, 3, 3 })
Test suite for KiCad math code.
MATRIX3x3D m3(VECTOR3I{ 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 })