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