rippled
Loading...
Searching...
No Matches
aged_associative_container_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of Beast: https://github.com/vinniefalco/Beast
4 Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/beast/clock/manual_clock.h>
21#include <xrpl/beast/unit_test.h>
22
23#include <xrpl/beast/container/aged_map.h>
24#include <xrpl/beast/container/aged_multimap.h>
25#include <xrpl/beast/container/aged_multiset.h>
26#include <xrpl/beast/container/aged_set.h>
27#include <xrpl/beast/container/aged_unordered_map.h>
28#include <xrpl/beast/container/aged_unordered_multimap.h>
29#include <xrpl/beast/container/aged_unordered_multiset.h>
30#include <xrpl/beast/container/aged_unordered_set.h>
31
32#include <list>
33#include <vector>
34
35#ifndef BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR
36#ifdef _MSC_VER
37#define BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR 0
38#else
39#define BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR 1
40#endif
41#endif
42
43#ifndef BEAST_CONTAINER_EXTRACT_NOREF
44#ifdef _MSC_VER
45#define BEAST_CONTAINER_EXTRACT_NOREF 1
46#else
47#define BEAST_CONTAINER_EXTRACT_NOREF 1
48#endif
49#endif
50
51namespace beast {
52
54{
55public:
56 template <class T>
57 struct CompT
58 {
59 explicit CompT(int)
60 {
61 }
62
63 CompT(CompT const&)
64 {
65 }
66
67 bool
68 operator()(T const& lhs, T const& rhs) const
69 {
70 return m_less(lhs, rhs);
71 }
72
73 private:
74 CompT() = delete;
76 };
77
78 template <class T>
79 class HashT
80 {
81 public:
82 explicit HashT(int)
83 {
84 }
85
87 operator()(T const& t) const
88 {
89 return m_hash(t);
90 }
91
92 private:
93 HashT() = delete;
95 };
96
97 template <class T>
98 struct EqualT
99 {
100 public:
101 explicit EqualT(int)
102 {
103 }
104
105 bool
106 operator()(T const& lhs, T const& rhs) const
107 {
108 return m_eq(lhs, rhs);
109 }
110
111 private:
112 EqualT() = delete;
114 };
115
116 template <class T>
117 struct AllocT
118 {
119 using value_type = T;
120
121 // using std::true_type::type = propagate_on_container_swap :;
122
123 template <class U>
124 struct rebind
125 {
127 };
128
129 explicit AllocT(int)
130 {
131 }
132
133 AllocT(AllocT const&) = default;
134
135 template <class U>
137 {
138 }
139
140 template <class U>
141 bool
142 operator==(AllocT<U> const&) const
143 {
144 return true;
145 }
146
147 template <class U>
148 bool
149 operator!=(AllocT<U> const& o) const
150 {
151 return !(*this == o);
152 }
153
154 T*
155 allocate(std::size_t n, T const* = 0)
156 {
157 return static_cast<T*>(::operator new(n * sizeof(T)));
158 }
159
160 void
162 {
163 ::operator delete(p);
164 }
165
166#if !BEAST_AGED_UNORDERED_NO_ALLOC_DEFAULTCTOR
168 {
169 }
170#else
171 private:
172 AllocT() = delete;
173#endif
174 };
175
176 //--------------------------------------------------------------------------
177
178 // ordered
179 template <class Base, bool IsUnordered>
180 class MaybeUnordered : public Base
181 {
182 public:
185
186 protected:
187 static std::string
189 {
190 return "";
191 }
192 };
193
194 // unordered
195 template <class Base>
196 class MaybeUnordered<Base, true> : public Base
197 {
198 public:
203
204 protected:
205 static std::string
207 {
208 return "unordered_";
209 }
210 };
211
212 // unique
213 template <class Base, bool IsMulti>
214 class MaybeMulti : public Base
215 {
216 public:
217 protected:
218 static std::string
220 {
221 return "";
222 }
223 };
224
225 // multi
226 template <class Base>
227 class MaybeMulti<Base, true> : public Base
228 {
229 public:
230 protected:
231 static std::string
233 {
234 return "multi";
235 }
236 };
237
238 // set
239 template <class Base, bool IsMap>
240 class MaybeMap : public Base
241 {
242 public:
243 using T = void;
244 using Value = typename Base::Key;
246
247 static typename Base::Key const&
248 extract(Value const& value)
249 {
250 return value;
251 }
252
253 static Values
255 {
256 Values v{
257 "apple",
258 "banana",
259 "cherry",
260 "grape",
261 "orange",
262 };
263 return v;
264 }
265
266 protected:
267 static std::string
269 {
270 return "set";
271 }
272 };
273
274 // map
275 template <class Base>
276 class MaybeMap<Base, true> : public Base
277 {
278 public:
279 using T = int;
282
283 static typename Base::Key const&
284 extract(Value const& value)
285 {
286 return value.first;
287 }
288
289 static Values
291 {
292 Values v{
293 std::make_pair("apple", 1),
294 std::make_pair("banana", 2),
295 std::make_pair("cherry", 3),
296 std::make_pair("grape", 4),
297 std::make_pair("orange", 5)};
298 return v;
299 }
300
301 protected:
302 static std::string
304 {
305 return "map";
306 }
307 };
308
309 //--------------------------------------------------------------------------
310
311 // ordered
312 template <class Base, bool IsUnordered = Base::is_unordered::value>
313 struct ContType
314 {
315 template <
316 class Compare = std::less<typename Base::Key>,
317 class Allocator = std::allocator<typename Base::Value>>
319 Base::is_multi::value,
320 Base::is_map::value,
321 typename Base::Key,
322 typename Base::T,
323 typename Base::Clock,
324 Compare,
325 Allocator>;
326 };
327
328 // unordered
329 template <class Base>
330 struct ContType<Base, true>
331 {
332 template <
334 class KeyEqual = std::equal_to<typename Base::Key>,
335 class Allocator = std::allocator<typename Base::Value>>
337 Base::is_multi::value,
338 Base::is_map::value,
339 typename Base::Key,
340 typename Base::T,
341 typename Base::Clock,
342 Hash,
343 KeyEqual,
344 Allocator>;
345 };
346
347 //--------------------------------------------------------------------------
348
350 {
354 };
355
356 template <bool IsUnordered, bool IsMulti, bool IsMap>
359 MaybeMulti<MaybeMap<TestTraitsBase, IsMap>, IsMulti>,
360 IsUnordered>
361 {
362 private:
365 IsUnordered>;
366
367 public:
368 using typename Base::Key;
369
373
376
377 static std::string
379 {
380 return std::string("aged_") + Base::name_ordered_part() +
382 }
383 };
384
385 template <bool IsUnordered, bool IsMulti, bool IsMap>
386 struct TestTraits : TestTraitsHelper<IsUnordered, IsMulti, IsMap>,
387 ContType<TestTraitsHelper<IsUnordered, IsMulti, IsMap>>
388 {
389 };
390
391 template <class Cont>
392 static std::string
393 name(Cont const&)
394 {
396 name();
397 }
398
399 template <class Traits>
401 {
402 bool
404 typename Traits::Value const& lhs,
405 typename Traits::Value const& rhs)
406 {
407 return Traits::extract(lhs) == Traits::extract(rhs);
408 }
409 };
410
411 template <class Cont>
413 make_list(Cont const& c)
414 {
415 return std::vector<typename Cont::value_type>(c.begin(), c.end());
416 }
417
418 //--------------------------------------------------------------------------
419
420 template <class Container, class Values>
421 typename std::enable_if<
422 Container::is_map::value && !Container::is_multi::value>::type
423 checkMapContents(Container& c, Values const& v);
424
425 template <class Container, class Values>
426 typename std::enable_if<
427 !(Container::is_map::value && !Container::is_multi::value)>::type
428 checkMapContents(Container, Values const&)
429 {
430 }
431
432 // unordered
433 template <class C, class Values>
434 typename std::enable_if<
436 checkUnorderedContentsRefRef(C&& c, Values const& v);
437
438 template <class C, class Values>
439 typename std::enable_if<
442 {
443 }
444
445 template <class C, class Values>
446 void
447 checkContentsRefRef(C&& c, Values const& v);
448
449 template <class Cont, class Values>
450 void
451 checkContents(Cont& c, Values const& v);
452
453 template <class Cont>
454 void
455 checkContents(Cont& c);
456
457 //--------------------------------------------------------------------------
458
459 // ordered
460 template <bool IsUnordered, bool IsMulti, bool IsMap>
463
464 // unordered
465 template <bool IsUnordered, bool IsMulti, bool IsMap>
468
469 // ordered
470 template <bool IsUnordered, bool IsMulti, bool IsMap>
473
474 // unordered
475 template <bool IsUnordered, bool IsMulti, bool IsMap>
478
479 // ordered
480 template <bool IsUnordered, bool IsMulti, bool IsMap>
483
484 // unordered
485 template <bool IsUnordered, bool IsMulti, bool IsMap>
488
489 //--------------------------------------------------------------------------
490
491 template <bool IsUnordered, bool IsMulti, bool IsMap>
492 void
493 testCopyMove();
494
495 //--------------------------------------------------------------------------
496
497 template <bool IsUnordered, bool IsMulti, bool IsMap>
498 void
499 testIterator();
500
501 // Unordered containers don't have reverse iterators
502 template <bool IsUnordered, bool IsMulti, bool IsMap>
505
506 template <bool IsUnordered, bool IsMulti, bool IsMap>
509 {
510 }
511
512 //--------------------------------------------------------------------------
513
514 template <class Container, class Values>
515 void
516 checkInsertCopy(Container& c, Values const& v);
517
518 template <class Container, class Values>
519 void
520 checkInsertMove(Container& c, Values const& v);
521
522 template <class Container, class Values>
523 void
524 checkInsertHintCopy(Container& c, Values const& v);
525
526 template <class Container, class Values>
527 void
528 checkInsertHintMove(Container& c, Values const& v);
529
530 template <class Container, class Values>
531 void
532 checkEmplace(Container& c, Values const& v);
533
534 template <class Container, class Values>
535 void
536 checkEmplaceHint(Container& c, Values const& v);
537
538 template <bool IsUnordered, bool IsMulti, bool IsMap>
539 void
541
542 //--------------------------------------------------------------------------
543
544 template <bool IsUnordered, bool IsMulti, bool IsMap>
545 void
547
548 //--------------------------------------------------------------------------
549
550 // map, unordered_map
551 template <bool IsUnordered, bool IsMulti, bool IsMap>
554
555 template <bool IsUnordered, bool IsMulti, bool IsMap>
556 typename std::enable_if<!(IsMap && !IsMulti)>::type
558 {
559 }
560
561 //--------------------------------------------------------------------------
562
563 // Helpers for erase tests
564 template <class Container, class Values>
565 void
566 reverseFillAgedContainer(Container& c, Values const& v);
567
568 template <class Iter>
569 Iter
570 nextToEndIter(Iter const beginIter, Iter const endItr);
571
572 //--------------------------------------------------------------------------
573
574 template <class Container, class Iter>
575 bool
576 doElementErase(Container& c, Iter const beginItr, Iter const endItr);
577
578 template <bool IsUnordered, bool IsMulti, bool IsMap>
579 void
581
582 //--------------------------------------------------------------------------
583
584 template <class Container, class BeginEndSrc>
585 void
586 doRangeErase(Container& c, BeginEndSrc const& beginEndSrc);
587
588 template <bool IsUnordered, bool IsMulti, bool IsMap>
589 void
591
592 //--------------------------------------------------------------------------
593
594 // ordered
595 template <bool IsUnordered, bool IsMulti, bool IsMap>
597 testCompare();
598
599 template <bool IsUnordered, bool IsMulti, bool IsMap>
602 {
603 }
604
605 //--------------------------------------------------------------------------
606
607 // ordered
608 template <bool IsUnordered, bool IsMulti, bool IsMap>
611
612 // unordered
613 template <bool IsUnordered, bool IsMulti, bool IsMap>
616
617 //--------------------------------------------------------------------------
618
619 template <bool IsUnordered, bool IsMulti, bool IsMap>
620 void
622
623 template <bool IsUnordered, bool IsMulti>
624 void
626
627 template <bool IsUnordered>
628 void
630};
631
632//------------------------------------------------------------------------------
633
634// Check contents via at() and operator[]
635// map, unordered_map
636template <class Container, class Values>
637typename std::enable_if<
638 Container::is_map::value && !Container::is_multi::value>::type
640 Container& c,
641 Values const& v)
642{
643 if (v.empty())
644 {
645 BEAST_EXPECT(c.empty());
646 BEAST_EXPECT(c.size() == 0);
647 return;
648 }
649
650 try
651 {
652 // Make sure no exception is thrown
653 for (auto const& e : v)
654 c.at(e.first);
655 for (auto const& e : v)
656 BEAST_EXPECT(c.operator[](e.first) == e.second);
657 }
658 catch (std::out_of_range const&)
659 {
660 fail("caught exception");
661 }
662}
663
664// unordered
665template <class C, class Values>
666typename std::enable_if<
669 C&& c,
670 Values const& v)
671{
672 using Cont = typename std::remove_reference<C>::type;
673 using Traits = TestTraits<
674 Cont::is_unordered::value,
675 Cont::is_multi::value,
676 Cont::is_map::value>;
677 using size_type = typename Cont::size_type;
678 auto const hash(c.hash_function());
679 auto const key_eq(c.key_eq());
680 for (size_type i(0); i < c.bucket_count(); ++i)
681 {
682 auto const last(c.end(i));
683 for (auto iter(c.begin(i)); iter != last; ++iter)
684 {
685 auto const match(std::find_if(
686 v.begin(),
687 v.end(),
688 [iter](typename Values::value_type const& e) {
689 return Traits::extract(*iter) == Traits::extract(e);
690 }));
691 BEAST_EXPECT(match != v.end());
692 BEAST_EXPECT(
693 key_eq(Traits::extract(*iter), Traits::extract(*match)));
694 BEAST_EXPECT(
695 hash(Traits::extract(*iter)) == hash(Traits::extract(*match)));
696 }
697 }
698}
699
700template <class C, class Values>
701void
703 C&& c,
704 Values const& v)
705{
706 using Cont = typename std::remove_reference<C>::type;
707 using Traits = TestTraits<
708 Cont::is_unordered::value,
709 Cont::is_multi::value,
710 Cont::is_map::value>;
711 using size_type = typename Cont::size_type;
712
713 BEAST_EXPECT(c.size() == v.size());
714 BEAST_EXPECT(size_type(std::distance(c.begin(), c.end())) == v.size());
715 BEAST_EXPECT(size_type(std::distance(c.cbegin(), c.cend())) == v.size());
716 BEAST_EXPECT(
717 size_type(std::distance(
718 c.chronological.begin(), c.chronological.end())) == v.size());
719 BEAST_EXPECT(
720 size_type(std::distance(
721 c.chronological.cbegin(), c.chronological.cend())) == v.size());
722 BEAST_EXPECT(
723 size_type(std::distance(
724 c.chronological.rbegin(), c.chronological.rend())) == v.size());
725 BEAST_EXPECT(
726 size_type(std::distance(
727 c.chronological.crbegin(), c.chronological.crend())) == v.size());
728
730}
731
732template <class Cont, class Values>
733void
735{
737 checkContentsRefRef(const_cast<Cont const&>(c), v);
738 checkMapContents(c, v);
739}
740
741template <class Cont>
742void
744{
745 using Traits = TestTraits<
746 Cont::is_unordered::value,
747 Cont::is_multi::value,
748 Cont::is_map::value>;
749 using Values = typename Traits::Values;
750 checkContents(c, Values());
751}
752
753//------------------------------------------------------------------------------
754//
755// Construction
756//
757//------------------------------------------------------------------------------
758
759// ordered
760template <bool IsUnordered, bool IsMulti, bool IsMap>
763{
765 using Value = typename Traits::Value;
766 using Key = typename Traits::Key;
767 using T = typename Traits::T;
768 using Clock = typename Traits::Clock;
769 using Comp = typename Traits::Comp;
770 using Alloc = typename Traits::Alloc;
771 using MyComp = typename Traits::MyComp;
772 using MyAlloc = typename Traits::MyAlloc;
773 typename Traits::ManualClock clock;
774
775 // testcase (Traits::name() + " empty");
776 testcase("empty");
777
778 {
779 typename Traits::template Cont<Comp, Alloc> c(clock);
780 checkContents(c);
781 }
782
783 {
784 typename Traits::template Cont<MyComp, Alloc> c(clock, MyComp(1));
785 checkContents(c);
786 }
787
788 {
789 typename Traits::template Cont<Comp, MyAlloc> c(clock, MyAlloc(1));
790 checkContents(c);
791 }
792
793 {
794 typename Traits::template Cont<MyComp, MyAlloc> c(
795 clock, MyComp(1), MyAlloc(1));
796 checkContents(c);
797 }
798}
799
800// unordered
801template <bool IsUnordered, bool IsMulti, bool IsMap>
804{
805 using Traits = TestTraits<IsUnordered, IsMulti, IsMap>;
806 using Value = typename Traits::Value;
807 using Key = typename Traits::Key;
808 using T = typename Traits::T;
809 using Clock = typename Traits::Clock;
810 using Hash = typename Traits::Hash;
811 using Equal = typename Traits::Equal;
812 using Alloc = typename Traits::Alloc;
813 using MyHash = typename Traits::MyHash;
814 using MyEqual = typename Traits::MyEqual;
815 using MyAlloc = typename Traits::MyAlloc;
816 typename Traits::ManualClock clock;
817
818 // testcase (Traits::name() + " empty");
819 testcase("empty");
820 {
821 typename Traits::template Cont<Hash, Equal, Alloc> c(clock);
822 checkContents(c);
823 }
824
825 {
826 typename Traits::template Cont<MyHash, Equal, Alloc> c(
827 clock, MyHash(1));
828 checkContents(c);
829 }
830
831 {
832 typename Traits::template Cont<Hash, MyEqual, Alloc> c(
833 clock, MyEqual(1));
834 checkContents(c);
835 }
836
837 {
838 typename Traits::template Cont<Hash, Equal, MyAlloc> c(
839 clock, MyAlloc(1));
840 checkContents(c);
841 }
842
843 {
844 typename Traits::template Cont<MyHash, MyEqual, Alloc> c(
845 clock, MyHash(1), MyEqual(1));
846 checkContents(c);
847 }
848
849 {
850 typename Traits::template Cont<MyHash, Equal, MyAlloc> c(
851 clock, MyHash(1), MyAlloc(1));
852 checkContents(c);
853 }
854
855 {
856 typename Traits::template Cont<Hash, MyEqual, MyAlloc> c(
857 clock, MyEqual(1), MyAlloc(1));
858 checkContents(c);
859 }
860
861 {
862 typename Traits::template Cont<MyHash, MyEqual, MyAlloc> c(
863 clock, MyHash(1), MyEqual(1), MyAlloc(1));
864 checkContents(c);
865 }
866}
867
868// ordered
869template <bool IsUnordered, bool IsMulti, bool IsMap>
872{
874 using Value = typename Traits::Value;
875 using Key = typename Traits::Key;
876 using T = typename Traits::T;
877 using Clock = typename Traits::Clock;
878 using Comp = typename Traits::Comp;
879 using Alloc = typename Traits::Alloc;
880 using MyComp = typename Traits::MyComp;
881 using MyAlloc = typename Traits::MyAlloc;
882 typename Traits::ManualClock clock;
883 auto const v(Traits::values());
884
885 // testcase (Traits::name() + " range");
886 testcase("range");
887
888 {
889 typename Traits::template Cont<Comp, Alloc> c(
890 v.begin(), v.end(), clock);
891 checkContents(c, v);
892 }
893
894 {
895 typename Traits::template Cont<MyComp, Alloc> c(
896 v.begin(), v.end(), clock, MyComp(1));
897 checkContents(c, v);
898 }
899
900 {
901 typename Traits::template Cont<Comp, MyAlloc> c(
902 v.begin(), v.end(), clock, MyAlloc(1));
903 checkContents(c, v);
904 }
905
906 {
907 typename Traits::template Cont<MyComp, MyAlloc> c(
908 v.begin(), v.end(), clock, MyComp(1), MyAlloc(1));
909 checkContents(c, v);
910 }
911
912 // swap
913
914 {
915 typename Traits::template Cont<Comp, Alloc> c1(
916 v.begin(), v.end(), clock);
917 typename Traits::template Cont<Comp, Alloc> c2(clock);
918 std::swap(c1, c2);
919 checkContents(c2, v);
920 }
921}
922
923// unordered
924template <bool IsUnordered, bool IsMulti, bool IsMap>
927{
928 using Traits = TestTraits<IsUnordered, IsMulti, IsMap>;
929 using Value = typename Traits::Value;
930 using Key = typename Traits::Key;
931 using T = typename Traits::T;
932 using Clock = typename Traits::Clock;
933 using Hash = typename Traits::Hash;
934 using Equal = typename Traits::Equal;
935 using Alloc = typename Traits::Alloc;
936 using MyHash = typename Traits::MyHash;
937 using MyEqual = typename Traits::MyEqual;
938 using MyAlloc = typename Traits::MyAlloc;
939 typename Traits::ManualClock clock;
940 auto const v(Traits::values());
941
942 // testcase (Traits::name() + " range");
943 testcase("range");
944
945 {
946 typename Traits::template Cont<Hash, Equal, Alloc> c(
947 v.begin(), v.end(), clock);
948 checkContents(c, v);
949 }
950
951 {
952 typename Traits::template Cont<MyHash, Equal, Alloc> c(
953 v.begin(), v.end(), clock, MyHash(1));
954 checkContents(c, v);
955 }
956
957 {
958 typename Traits::template Cont<Hash, MyEqual, Alloc> c(
959 v.begin(), v.end(), clock, MyEqual(1));
960 checkContents(c, v);
961 }
962
963 {
964 typename Traits::template Cont<Hash, Equal, MyAlloc> c(
965 v.begin(), v.end(), clock, MyAlloc(1));
966 checkContents(c, v);
967 }
968
969 {
970 typename Traits::template Cont<MyHash, MyEqual, Alloc> c(
971 v.begin(), v.end(), clock, MyHash(1), MyEqual(1));
972 checkContents(c, v);
973 }
974
975 {
976 typename Traits::template Cont<MyHash, Equal, MyAlloc> c(
977 v.begin(), v.end(), clock, MyHash(1), MyAlloc(1));
978 checkContents(c, v);
979 }
980
981 {
982 typename Traits::template Cont<Hash, MyEqual, MyAlloc> c(
983 v.begin(), v.end(), clock, MyEqual(1), MyAlloc(1));
984 checkContents(c, v);
985 }
986
987 {
988 typename Traits::template Cont<MyHash, MyEqual, MyAlloc> c(
989 v.begin(), v.end(), clock, MyHash(1), MyEqual(1), MyAlloc(1));
990 checkContents(c, v);
991 }
992}
993
994// ordered
995template <bool IsUnordered, bool IsMulti, bool IsMap>
998{
1000 using Value = typename Traits::Value;
1001 using Key = typename Traits::Key;
1002 using T = typename Traits::T;
1003 using Clock = typename Traits::Clock;
1004 using Comp = typename Traits::Comp;
1005 using Alloc = typename Traits::Alloc;
1006 using MyComp = typename Traits::MyComp;
1007 using MyAlloc = typename Traits::MyAlloc;
1008 typename Traits::ManualClock clock;
1009
1010 // testcase (Traits::name() + " init-list");
1011 testcase("init-list");
1012
1013 // VFALCO TODO
1014
1015 pass();
1016}
1017
1018// unordered
1019template <bool IsUnordered, bool IsMulti, bool IsMap>
1022{
1023 using Traits = TestTraits<IsUnordered, IsMulti, IsMap>;
1024 using Value = typename Traits::Value;
1025 using Key = typename Traits::Key;
1026 using T = typename Traits::T;
1027 using Clock = typename Traits::Clock;
1028 using Hash = typename Traits::Hash;
1029 using Equal = typename Traits::Equal;
1030 using Alloc = typename Traits::Alloc;
1031 using MyHash = typename Traits::MyHash;
1032 using MyEqual = typename Traits::MyEqual;
1033 using MyAlloc = typename Traits::MyAlloc;
1034 typename Traits::ManualClock clock;
1035
1036 // testcase (Traits::name() + " init-list");
1037 testcase("init-list");
1038
1039 // VFALCO TODO
1040 pass();
1041}
1042
1043//------------------------------------------------------------------------------
1044//
1045// Copy/Move construction and assign
1046//
1047//------------------------------------------------------------------------------
1048
1049template <bool IsUnordered, bool IsMulti, bool IsMap>
1050void
1052{
1054 using Value = typename Traits::Value;
1055 using Alloc = typename Traits::Alloc;
1056 typename Traits::ManualClock clock;
1057 auto const v(Traits::values());
1058
1059 // testcase (Traits::name() + " copy/move");
1060 testcase("copy/move");
1061
1062 // copy
1063
1064 {
1065 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1066 typename Traits::template Cont<> c2(c);
1067 checkContents(c, v);
1068 checkContents(c2, v);
1069 BEAST_EXPECT(c == c2);
1070 unexpected(c != c2);
1071 }
1072
1073 {
1074 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1075 typename Traits::template Cont<> c2(c, Alloc());
1076 checkContents(c, v);
1077 checkContents(c2, v);
1078 BEAST_EXPECT(c == c2);
1079 unexpected(c != c2);
1080 }
1081
1082 {
1083 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1084 typename Traits::template Cont<> c2(clock);
1085 c2 = c;
1086 checkContents(c, v);
1087 checkContents(c2, v);
1088 BEAST_EXPECT(c == c2);
1089 unexpected(c != c2);
1090 }
1091
1092 // move
1093
1094 {
1095 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1096 typename Traits::template Cont<> c2(std::move(c));
1097 checkContents(c2, v);
1098 }
1099
1100 {
1101 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1102 typename Traits::template Cont<> c2(std::move(c), Alloc());
1103 checkContents(c2, v);
1104 }
1105
1106 {
1107 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1108 typename Traits::template Cont<> c2(clock);
1109 c2 = std::move(c);
1110 checkContents(c2, v);
1111 }
1112}
1113
1114//------------------------------------------------------------------------------
1115//
1116// Iterator construction and assignment
1117//
1118//------------------------------------------------------------------------------
1119
1120template <bool IsUnordered, bool IsMulti, bool IsMap>
1121void
1123{
1125 using Value = typename Traits::Value;
1126 using Alloc = typename Traits::Alloc;
1127 typename Traits::ManualClock clock;
1128 auto const v(Traits::values());
1129
1130 // testcase (Traits::name() + " iterators");
1131 testcase("iterator");
1132
1133 typename Traits::template Cont<> c{clock};
1134
1135 using iterator = decltype(c.begin());
1136 using const_iterator = decltype(c.cbegin());
1137
1138 // Should be able to construct or assign an iterator from an iterator.
1139 iterator nnIt_0{c.begin()};
1140 iterator nnIt_1{nnIt_0};
1141 BEAST_EXPECT(nnIt_0 == nnIt_1);
1142 iterator nnIt_2;
1143 nnIt_2 = nnIt_1;
1144 BEAST_EXPECT(nnIt_1 == nnIt_2);
1145
1146 // Should be able to construct or assign a const_iterator from a
1147 // const_iterator.
1148 const_iterator ccIt_0{c.cbegin()};
1149 const_iterator ccIt_1{ccIt_0};
1150 BEAST_EXPECT(ccIt_0 == ccIt_1);
1151 const_iterator ccIt_2;
1152 ccIt_2 = ccIt_1;
1153 BEAST_EXPECT(ccIt_1 == ccIt_2);
1154
1155 // Comparison between iterator and const_iterator is okay
1156 BEAST_EXPECT(nnIt_0 == ccIt_0);
1157 BEAST_EXPECT(ccIt_1 == nnIt_1);
1158
1159 // Should be able to construct a const_iterator from an iterator.
1160 const_iterator ncIt_3{c.begin()};
1161 const_iterator ncIt_4{nnIt_0};
1162 BEAST_EXPECT(ncIt_3 == ncIt_4);
1163 const_iterator ncIt_5;
1164 ncIt_5 = nnIt_2;
1165 BEAST_EXPECT(ncIt_5 == ncIt_4);
1166
1167 // None of these should compile because they construct or assign to a
1168 // non-const iterator with a const_iterator.
1169
1170 // iterator cnIt_0 {c.cbegin()};
1171
1172 // iterator cnIt_1 {ccIt_0};
1173
1174 // iterator cnIt_2;
1175 // cnIt_2 = ccIt_2;
1176}
1177
1178template <bool IsUnordered, bool IsMulti, bool IsMap>
1181{
1183 using Value = typename Traits::Value;
1184 using Alloc = typename Traits::Alloc;
1185 typename Traits::ManualClock clock;
1186 auto const v(Traits::values());
1187
1188 // testcase (Traits::name() + " reverse_iterators");
1189 testcase("reverse_iterator");
1190
1191 typename Traits::template Cont<> c{clock};
1192
1193 using iterator = decltype(c.begin());
1194 using const_iterator = decltype(c.cbegin());
1195 using reverse_iterator = decltype(c.rbegin());
1196 using const_reverse_iterator = decltype(c.crbegin());
1197
1198 // Naming decoder ring
1199 // constructed from ------+ +----- constructed type
1200 // /\/\ -- character pairs
1201 // xAyBit
1202 // r (reverse) or f (forward)--^-^
1203 // ^-^------ C (const) or N (non-const)
1204
1205 // Should be able to construct or assign a reverse_iterator from a
1206 // reverse_iterator.
1207 reverse_iterator rNrNit_0{c.rbegin()};
1208 reverse_iterator rNrNit_1{rNrNit_0};
1209 BEAST_EXPECT(rNrNit_0 == rNrNit_1);
1210 reverse_iterator xXrNit_2;
1211 xXrNit_2 = rNrNit_1;
1212 BEAST_EXPECT(rNrNit_1 == xXrNit_2);
1213
1214 // Should be able to construct or assign a const_reverse_iterator from a
1215 // const_reverse_iterator
1216 const_reverse_iterator rCrCit_0{c.crbegin()};
1217 const_reverse_iterator rCrCit_1{rCrCit_0};
1218 BEAST_EXPECT(rCrCit_0 == rCrCit_1);
1219 const_reverse_iterator xXrCit_2;
1220 xXrCit_2 = rCrCit_1;
1221 BEAST_EXPECT(rCrCit_1 == xXrCit_2);
1222
1223 // Comparison between reverse_iterator and const_reverse_iterator is okay
1224 BEAST_EXPECT(rNrNit_0 == rCrCit_0);
1225 BEAST_EXPECT(rCrCit_1 == rNrNit_1);
1226
1227 // Should be able to construct or assign a const_reverse_iterator from a
1228 // reverse_iterator
1229 const_reverse_iterator rNrCit_0{c.rbegin()};
1230 const_reverse_iterator rNrCit_1{rNrNit_0};
1231 BEAST_EXPECT(rNrCit_0 == rNrCit_1);
1232 xXrCit_2 = rNrNit_1;
1233 BEAST_EXPECT(rNrCit_1 == xXrCit_2);
1234
1235 // The standard allows these conversions:
1236 // o reverse_iterator is explicitly constructible from iterator.
1237 // o const_reverse_iterator is explicitly constructible from
1238 // const_iterator.
1239 // Should be able to construct or assign reverse_iterators from
1240 // non-reverse iterators.
1241 reverse_iterator fNrNit_0{c.begin()};
1242 const_reverse_iterator fNrCit_0{c.begin()};
1243 BEAST_EXPECT(fNrNit_0 == fNrCit_0);
1244 const_reverse_iterator fCrCit_0{c.cbegin()};
1245 BEAST_EXPECT(fNrCit_0 == fCrCit_0);
1246
1247 // None of these should compile because they construct a non-reverse
1248 // iterator from a reverse_iterator.
1249 // iterator rNfNit_0 {c.rbegin()};
1250 // const_iterator rNfCit_0 {c.rbegin()};
1251 // const_iterator rCfCit_0 {c.crbegin()};
1252
1253 // You should not be able to assign an iterator to a reverse_iterator or
1254 // vise-versa. So the following lines should not compile.
1255 iterator xXfNit_0;
1256 // xXfNit_0 = xXrNit_2;
1257 // xXrNit_2 = xXfNit_0;
1258}
1259
1260//------------------------------------------------------------------------------
1261//
1262// Modifiers
1263//
1264//------------------------------------------------------------------------------
1265
1266template <class Container, class Values>
1267void
1269 Container& c,
1270 Values const& v)
1271{
1272 for (auto const& e : v)
1273 c.insert(e);
1274 checkContents(c, v);
1275}
1276
1277template <class Container, class Values>
1278void
1280 Container& c,
1281 Values const& v)
1282{
1283 Values v2(v);
1284 for (auto& e : v2)
1285 c.insert(std::move(e));
1286 checkContents(c, v);
1287}
1288
1289template <class Container, class Values>
1290void
1292 Container& c,
1293 Values const& v)
1294{
1295 for (auto const& e : v)
1296 c.insert(c.cend(), e);
1297 checkContents(c, v);
1298}
1299
1300template <class Container, class Values>
1301void
1303 Container& c,
1304 Values const& v)
1305{
1306 Values v2(v);
1307 for (auto& e : v2)
1308 c.insert(c.cend(), std::move(e));
1309 checkContents(c, v);
1310}
1311
1312template <class Container, class Values>
1313void
1315 Container& c,
1316 Values const& v)
1317{
1318 for (auto const& e : v)
1319 c.emplace(e);
1320 checkContents(c, v);
1321}
1322
1323template <class Container, class Values>
1324void
1326 Container& c,
1327 Values const& v)
1328{
1329 for (auto const& e : v)
1330 c.emplace_hint(c.cend(), e);
1331 checkContents(c, v);
1332}
1333
1334template <bool IsUnordered, bool IsMulti, bool IsMap>
1335void
1337{
1339 typename Traits::ManualClock clock;
1340 auto const v(Traits::values());
1341 auto const l(make_list(v));
1342
1343 // testcase (Traits::name() + " modify");
1344 testcase("modify");
1345
1346 {
1347 typename Traits::template Cont<> c(clock);
1348 checkInsertCopy(c, v);
1349 }
1350
1351 {
1352 typename Traits::template Cont<> c(clock);
1353 checkInsertCopy(c, l);
1354 }
1355
1356 {
1357 typename Traits::template Cont<> c(clock);
1358 checkInsertMove(c, v);
1359 }
1360
1361 {
1362 typename Traits::template Cont<> c(clock);
1363 checkInsertMove(c, l);
1364 }
1365
1366 {
1367 typename Traits::template Cont<> c(clock);
1368 checkInsertHintCopy(c, v);
1369 }
1370
1371 {
1372 typename Traits::template Cont<> c(clock);
1373 checkInsertHintCopy(c, l);
1374 }
1375
1376 {
1377 typename Traits::template Cont<> c(clock);
1378 checkInsertHintMove(c, v);
1379 }
1380
1381 {
1382 typename Traits::template Cont<> c(clock);
1383 checkInsertHintMove(c, l);
1384 }
1385}
1386
1387//------------------------------------------------------------------------------
1388//
1389// Chronological ordering
1390//
1391//------------------------------------------------------------------------------
1392
1393template <bool IsUnordered, bool IsMulti, bool IsMap>
1394void
1396{
1398 using Value = typename Traits::Value;
1399 typename Traits::ManualClock clock;
1400 auto const v(Traits::values());
1401
1402 // testcase (Traits::name() + " chronological");
1403 testcase("chronological");
1404
1405 typename Traits::template Cont<> c(v.begin(), v.end(), clock);
1406
1407 BEAST_EXPECT(std::equal(
1408 c.chronological.cbegin(),
1409 c.chronological.cend(),
1410 v.begin(),
1411 v.end(),
1413
1414 // Test touch() with a non-const iterator.
1415 for (auto iter(v.crbegin()); iter != v.crend(); ++iter)
1416 {
1417 using iterator = typename decltype(c)::iterator;
1418 iterator found(c.find(Traits::extract(*iter)));
1419
1420 BEAST_EXPECT(found != c.cend());
1421 if (found == c.cend())
1422 return;
1423 c.touch(found);
1424 }
1425
1426 BEAST_EXPECT(std::equal(
1427 c.chronological.cbegin(),
1428 c.chronological.cend(),
1429 v.crbegin(),
1430 v.crend(),
1432
1433 // Test touch() with a const_iterator
1434 for (auto iter(v.cbegin()); iter != v.cend(); ++iter)
1435 {
1436 using const_iterator = typename decltype(c)::const_iterator;
1437 const_iterator found(c.find(Traits::extract(*iter)));
1438
1439 BEAST_EXPECT(found != c.cend());
1440 if (found == c.cend())
1441 return;
1442 c.touch(found);
1443 }
1444
1445 BEAST_EXPECT(std::equal(
1446 c.chronological.cbegin(),
1447 c.chronological.cend(),
1448 v.cbegin(),
1449 v.cend(),
1451
1452 {
1453 // Because touch (reverse_iterator pos) is not allowed, the following
1454 // lines should not compile for any aged_container type.
1455 // c.touch (c.rbegin());
1456 // c.touch (c.crbegin());
1457 }
1458}
1459
1460//------------------------------------------------------------------------------
1461//
1462// Element creation via operator[]
1463//
1464//------------------------------------------------------------------------------
1465
1466// map, unordered_map
1467template <bool IsUnordered, bool IsMulti, bool IsMap>
1470{
1472 typename Traits::ManualClock clock;
1473 auto v(Traits::values());
1474
1475 // testcase (Traits::name() + " array create");
1476 testcase("array create");
1477
1478 {
1479 // Copy construct key
1480 typename Traits::template Cont<> c(clock);
1481 for (auto e : v)
1482 c[e.first] = e.second;
1483 checkContents(c, v);
1484 }
1485
1486 {
1487 // Move construct key
1488 typename Traits::template Cont<> c(clock);
1489 for (auto e : v)
1490 c[std::move(e.first)] = e.second;
1491 checkContents(c, v);
1492 }
1493}
1494
1495//------------------------------------------------------------------------------
1496//
1497// Helpers for erase tests
1498//
1499//------------------------------------------------------------------------------
1500
1501template <class Container, class Values>
1502void
1504 Container& c,
1505 Values const& values)
1506{
1507 // Just in case the passed in container was not empty.
1508 c.clear();
1509
1510 // c.clock() returns an abstract_clock, so dynamic_cast to manual_clock.
1511 // VFALCO NOTE This is sketchy
1512 using ManualClock = TestTraitsBase::ManualClock;
1513 ManualClock& clk(dynamic_cast<ManualClock&>(c.clock()));
1514 clk.set(0);
1515
1516 Values rev(values);
1517 std::sort(rev.begin(), rev.end());
1518 std::reverse(rev.begin(), rev.end());
1519 for (auto& v : rev)
1520 {
1521 // Add values in reverse order so they are reversed chronologically.
1522 ++clk;
1523 c.insert(v);
1524 }
1525}
1526
1527// Get one iterator before endIter. We have to use operator++ because you
1528// cannot use operator-- with unordered container iterators.
1529template <class Iter>
1530Iter
1532 Iter beginIter,
1533 Iter const endIter)
1534{
1535 if (beginIter == endIter)
1536 {
1537 fail("Internal test failure. Cannot advance beginIter");
1538 return beginIter;
1539 }
1540
1541 //
1542 Iter nextToEnd = beginIter;
1543 do
1544 {
1545 nextToEnd = beginIter++;
1546 } while (beginIter != endIter);
1547 return nextToEnd;
1548}
1549
1550// Implementation for the element erase tests
1551//
1552// This test accepts:
1553// o the container from which we will erase elements
1554// o iterators into that container defining the range of the erase
1555//
1556// This implementation does not declare a pass, since it wants to allow
1557// the caller to examine the size of the container and the returned iterator
1558//
1559// Note that this test works on the aged_associative containers because an
1560// erase only invalidates references and iterators to the erased element
1561// (see 23.2.4/13). Therefore the passed-in end iterator stays valid through
1562// the whole test.
1563template <class Container, class Iter>
1564bool
1566 Container& c,
1567 Iter const beginItr,
1568 Iter const endItr)
1569{
1570 auto it(beginItr);
1571 size_t count = c.size();
1572 while (it != endItr)
1573 {
1574 auto expectIt = it;
1575 ++expectIt;
1576 it = c.erase(it);
1577
1578 if (it != expectIt)
1579 {
1580 fail("Unexpected returned iterator from element erase");
1581 return false;
1582 }
1583
1584 --count;
1585 if (count != c.size())
1586 {
1587 fail("Failed to erase element");
1588 return false;
1589 }
1590
1591 if (c.empty())
1592 {
1593 if (it != endItr)
1594 {
1595 fail("Erase of last element didn't produce end");
1596 return false;
1597 }
1598 }
1599 }
1600 return true;
1601}
1602
1603//------------------------------------------------------------------------------
1604//
1605// Erase of individual elements
1606//
1607//------------------------------------------------------------------------------
1608
1609template <bool IsUnordered, bool IsMulti, bool IsMap>
1610void
1612{
1614
1615 // testcase (Traits::name() + " element erase"
1616 testcase("element erase");
1617
1618 // Make and fill the container
1619 typename Traits::ManualClock clock;
1620 typename Traits::template Cont<> c{clock};
1621 reverseFillAgedContainer(c, Traits::values());
1622
1623 {
1624 // Test standard iterators
1625 auto tempContainer(c);
1626 if (!doElementErase(
1627 tempContainer, tempContainer.cbegin(), tempContainer.cend()))
1628 return; // Test failed
1629
1630 BEAST_EXPECT(tempContainer.empty());
1631 pass();
1632 }
1633 {
1634 // Test chronological iterators
1635 auto tempContainer(c);
1636 auto& chron(tempContainer.chronological);
1637 if (!doElementErase(tempContainer, chron.begin(), chron.end()))
1638 return; // Test failed
1639
1640 BEAST_EXPECT(tempContainer.empty());
1641 pass();
1642 }
1643 {
1644 // Test standard iterator partial erase
1645 auto tempContainer(c);
1646 BEAST_EXPECT(tempContainer.size() > 2);
1647 if (!doElementErase(
1648 tempContainer,
1649 ++tempContainer.begin(),
1650 nextToEndIter(tempContainer.begin(), tempContainer.end())))
1651 return; // Test failed
1652
1653 BEAST_EXPECT(tempContainer.size() == 2);
1654 pass();
1655 }
1656 {
1657 // Test chronological iterator partial erase
1658 auto tempContainer(c);
1659 BEAST_EXPECT(tempContainer.size() > 2);
1660 auto& chron(tempContainer.chronological);
1661 if (!doElementErase(
1662 tempContainer,
1663 ++chron.begin(),
1664 nextToEndIter(chron.begin(), chron.end())))
1665 return; // Test failed
1666
1667 BEAST_EXPECT(tempContainer.size() == 2);
1668 pass();
1669 }
1670 {
1671 auto tempContainer(c);
1672 BEAST_EXPECT(tempContainer.size() > 4);
1673 // erase(reverse_iterator) is not allowed. None of the following
1674 // should compile for any aged_container type.
1675 // c.erase (c.rbegin());
1676 // c.erase (c.crbegin());
1677 // c.erase(c.rbegin(), ++c.rbegin());
1678 // c.erase(c.crbegin(), ++c.crbegin());
1679 }
1680}
1681
1682// Implementation for the range erase tests
1683//
1684// This test accepts:
1685//
1686// o A container with more than 2 elements and
1687// o An object to ask for begin() and end() iterators in the passed container
1688//
1689// This peculiar interface allows either the container itself to be passed as
1690// the second argument or the container's "chronological" element. Both
1691// sources of iterators need to be tested on the container.
1692//
1693// The test locates iterators such that a range-based delete leaves the first
1694// and last elements in the container. It then validates that the container
1695// ended up with the expected contents.
1696//
1697template <class Container, class BeginEndSrc>
1698void
1700 Container& c,
1701 BeginEndSrc const& beginEndSrc)
1702{
1703 BEAST_EXPECT(c.size() > 2);
1704 auto itBeginPlusOne(beginEndSrc.begin());
1705 auto const valueFront = *itBeginPlusOne;
1706 ++itBeginPlusOne;
1707
1708 // Get one iterator before end()
1709 auto itBack(nextToEndIter(itBeginPlusOne, beginEndSrc.end()));
1710 auto const valueBack = *itBack;
1711
1712 // Erase all elements but first and last
1713 auto const retIter = c.erase(itBeginPlusOne, itBack);
1714
1715 BEAST_EXPECT(c.size() == 2);
1716 BEAST_EXPECT(valueFront == *(beginEndSrc.begin()));
1717 BEAST_EXPECT(valueBack == *(++beginEndSrc.begin()));
1718 BEAST_EXPECT(retIter == (++beginEndSrc.begin()));
1719}
1720
1721//------------------------------------------------------------------------------
1722//
1723// Erase range of elements
1724//
1725//------------------------------------------------------------------------------
1726
1727template <bool IsUnordered, bool IsMulti, bool IsMap>
1728void
1730{
1732
1733 // testcase (Traits::name() + " element erase"
1734 testcase("range erase");
1735
1736 // Make and fill the container
1737 typename Traits::ManualClock clock;
1738 typename Traits::template Cont<> c{clock};
1739 reverseFillAgedContainer(c, Traits::values());
1740
1741 // Not bothering to test range erase with reverse iterators.
1742 {
1743 auto tempContainer(c);
1744 doRangeErase(tempContainer, tempContainer);
1745 }
1746 {
1747 auto tempContainer(c);
1748 doRangeErase(tempContainer, tempContainer.chronological);
1749 }
1750}
1751
1752//------------------------------------------------------------------------------
1753//
1754// Container-wide comparison
1755//
1756//------------------------------------------------------------------------------
1757
1758// ordered
1759template <bool IsUnordered, bool IsMulti, bool IsMap>
1762{
1764 using Value = typename Traits::Value;
1765 typename Traits::ManualClock clock;
1766 auto const v(Traits::values());
1767
1768 // testcase (Traits::name() + " array create");
1769 testcase("array create");
1770
1771 typename Traits::template Cont<> c1(v.begin(), v.end(), clock);
1772
1773 typename Traits::template Cont<> c2(v.begin(), v.end(), clock);
1774 c2.erase(c2.cbegin());
1775
1776 expect(c1 != c2);
1777 unexpected(c1 == c2);
1778 expect(c1 < c2);
1779 expect(c1 <= c2);
1780 unexpected(c1 > c2);
1781 unexpected(c1 >= c2);
1782}
1783
1784//------------------------------------------------------------------------------
1785//
1786// Observers
1787//
1788//------------------------------------------------------------------------------
1789
1790// ordered
1791template <bool IsUnordered, bool IsMulti, bool IsMap>
1794{
1796 typename Traits::ManualClock clock;
1797
1798 // testcase (Traits::name() + " observers");
1799 testcase("observers");
1800
1801 typename Traits::template Cont<> c(clock);
1802 c.key_comp();
1803 c.value_comp();
1804
1805 pass();
1806}
1807
1808// unordered
1809template <bool IsUnordered, bool IsMulti, bool IsMap>
1812{
1813 using Traits = TestTraits<IsUnordered, IsMulti, IsMap>;
1814 typename Traits::ManualClock clock;
1815
1816 // testcase (Traits::name() + " observers");
1817 testcase("observers");
1818
1819 typename Traits::template Cont<> c(clock);
1820 c.hash_function();
1821 c.key_eq();
1822
1823 pass();
1824}
1825
1826//------------------------------------------------------------------------------
1827//
1828// Matrix
1829//
1830//------------------------------------------------------------------------------
1831
1832template <bool IsUnordered, bool IsMulti, bool IsMap>
1833void
1835{
1837
1838 testConstructEmpty<IsUnordered, IsMulti, IsMap>();
1839 testConstructRange<IsUnordered, IsMulti, IsMap>();
1840 testConstructInitList<IsUnordered, IsMulti, IsMap>();
1841 testCopyMove<IsUnordered, IsMulti, IsMap>();
1842 testIterator<IsUnordered, IsMulti, IsMap>();
1843 testReverseIterator<IsUnordered, IsMulti, IsMap>();
1844 testModifiers<IsUnordered, IsMulti, IsMap>();
1845 testChronological<IsUnordered, IsMulti, IsMap>();
1846 testArrayCreate<IsUnordered, IsMulti, IsMap>();
1847 testElementErase<IsUnordered, IsMulti, IsMap>();
1848 testRangeErase<IsUnordered, IsMulti, IsMap>();
1849 testCompare<IsUnordered, IsMulti, IsMap>();
1850 testObservers<IsUnordered, IsMulti, IsMap>();
1851}
1852
1853//------------------------------------------------------------------------------
1854
1856{
1857public:
1858 // Compile time checks
1859
1861 using T = int;
1862
1863 static_assert(
1867 "bad alias: aged_set");
1868
1869 static_assert(
1873 "bad alias: aged_multiset");
1874
1875 static_assert(
1879 "bad alias: aged_map");
1880
1881 static_assert(
1885 "bad alias: aged_multimap");
1886
1887 static_assert(
1891 "bad alias: aged_unordered_set");
1892
1893 static_assert(
1897 "bad alias: aged_unordered_multiset");
1898
1899 static_assert(
1903 "bad alias: aged_unordered_map");
1904
1905 static_assert(
1909 "bad alias: aged_unordered_multimap");
1910
1911 void
1912 run() override
1913 {
1914 testMaybeUnorderedMultiMap<false, false, false>();
1915 }
1916};
1917
1919{
1920public:
1921 void
1922 run() override
1923 {
1924 testMaybeUnorderedMultiMap<false, false, true>();
1925 }
1926};
1927
1929{
1930public:
1931 void
1932 run() override
1933 {
1934 testMaybeUnorderedMultiMap<false, true, false>();
1935 }
1936};
1937
1939{
1940public:
1941 void
1942 run() override
1943 {
1944 testMaybeUnorderedMultiMap<false, true, true>();
1945 }
1946};
1947
1949{
1950public:
1951 void
1952 run() override
1953 {
1954 testMaybeUnorderedMultiMap<true, false, false>();
1955 }
1956};
1957
1959{
1960public:
1961 void
1962 run() override
1963 {
1964 testMaybeUnorderedMultiMap<true, false, true>();
1965 }
1966};
1967
1969{
1970public:
1971 void
1972 run() override
1973 {
1974 testMaybeUnorderedMultiMap<true, true, false>();
1975 }
1976};
1977
1979{
1980public:
1981 void
1982 run() override
1983 {
1984 testMaybeUnorderedMultiMap<true, true, true>();
1985 }
1986};
1987
1988BEAST_DEFINE_TESTSUITE(aged_set, container, beast);
1989BEAST_DEFINE_TESTSUITE(aged_map, container, beast);
1990BEAST_DEFINE_TESTSUITE(aged_multiset, container, beast);
1991BEAST_DEFINE_TESTSUITE(aged_multimap, container, beast);
1992BEAST_DEFINE_TESTSUITE(aged_unordered_set, container, beast);
1993BEAST_DEFINE_TESTSUITE(aged_unordered_map, container, beast);
1994BEAST_DEFINE_TESTSUITE(aged_unordered_multiset, container, beast);
1995BEAST_DEFINE_TESTSUITE(aged_unordered_multimap, container, beast);
1996
1997} // namespace beast
std::enable_if< IsMap &&!IsMulti >::type testArrayCreate()
std::enable_if<!std::remove_reference< C >::type::is_unordered::value >::type checkUnorderedContentsRefRef(C &&, Values const &)
std::enable_if<!(Container::is_map::value &&!Container::is_multi::value)>::type checkMapContents(Container, Values const &)
static std::vector< typename Cont::value_type > make_list(Cont const &c)
std::enable_if< IsUnordered >::type testReverseIterator()
std::enable_if< Container::is_map::value &&!Container::is_multi::value >::type checkMapContents(Container &c, Values const &v)
std::enable_if<!IsUnordered >::type testConstructRange()
bool doElementErase(Container &c, Iter const beginItr, Iter const endItr)
Iter nextToEndIter(Iter const beginIter, Iter const endItr)
std::enable_if<!IsUnordered >::type testConstructEmpty()
std::enable_if< std::remove_reference< C >::type::is_unordered::value >::type checkUnorderedContentsRefRef(C &&c, Values const &v)
std::enable_if<!IsUnordered >::type testConstructInitList()
std::enable_if<!(IsMap &&!IsMulti)>::type testArrayCreate()
void doRangeErase(Container &c, BeginEndSrc const &beginEndSrc)
void run() override
Runs the suite.
void run() override
Runs the suite.
Associative container where each element is also indexed by time.
Associative container where each element is also indexed by time.
Manual clock implementation.
Definition: manual_clock.h:39
A testsuite class.
Definition: suite.h:53
void pass()
Record a successful test condition.
Definition: suite.h:509
bool unexpected(Condition shouldBeFalse, String const &reason)
Definition: suite.h:497
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:153
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition: suite.h:227
void fail(String const &reason, char const *file, int line)
Record a failure.
Definition: suite.h:531
T distance(T... args)
T equal(T... args)
T find_if(T... args)
T make_pair(T... args)
T reverse(T... args)
T sort(T... args)
bool operator()(typename Traits::Value const &lhs, typename Traits::Value const &rhs)
T swap(T... args)