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