3#include <boost/multi_index/member.hpp>
4#include <boost/multi_index/ordered_index.hpp>
6#include <boost/test/unit_test.hpp>
7#include <boost/test/data/monomorphic.hpp>
8#include <boost/test/data/test_case.hpp>
12int exception_counter = 0;
14struct test_exception_base {};
16struct test_exception : E, test_exception_base {
17 template<
typename...
A>
18 test_exception(
A&&...
a) : E{static_cast<E&&>(
a)...} {}
20template<
typename E,
typename...
A>
21void throw_point(
A&&...
a) {
22 if(throw_at != -1 && exception_counter++ >= throw_at) {
23 throw test_exception<E>{
static_cast<A&&
>(
a)...};
27void test_exceptions(F&&
f) {
28 for(throw_at = 0; ; ++throw_at) {
29 exception_counter = 0;
33 }
catch(test_exception_base&) {}
36 exception_counter = 0;
40 throwing_copy() { throw_point<std::bad_alloc>(); }
41 throwing_copy(
const throwing_copy&) { throw_point<std::bad_alloc>(); }
42 throwing_copy(throwing_copy&&) noexcept = default;
43 throwing_copy& operator=(const throwing_copy&) { throw_point<std::bad_alloc>();
return *
this; }
44 throwing_copy& operator=(throwing_copy&&) noexcept = default;
48struct test_allocator :
std::allocator<
T> {
49 test_allocator() =
default;
51 test_allocator(
const test_allocator<U>&) {}
53 struct rebind {
using other = test_allocator<U>; };
54 T* allocate(std::size_t
count) {
55 throw_point<std::bad_alloc>();
56 return std::allocator<T>::allocate(
count);
64 if(_exception_count != std::uncaught_exceptions()) _f();
70struct basic_element_t {
71 template<
typename C,
typename A>
72 basic_element_t(C&& c,
const std::allocator<A>&) { c(*
this); }
80template<
typename C,
typename T>
81struct key_impl<
T C::*> {
template<auto F>
using fn = boost::multi_index::member<C, T, F>; };
84using key =
typename key_impl<
decltype(Fn)>
::template fn<Fn>;
88BOOST_AUTO_TEST_SUITE(undo_index_tests)
90#define EXCEPTION_TEST_CASE(name) \
92 BOOST_AUTO_TEST_CASE(name) { test_exceptions(&name##impl); } \
97 i0.
emplace([](basic_element_t& elem) {});
98 const basic_element_t* element = i0.
find(0);
99 BOOST_TEST((element !=
nullptr && element->id == 0));
100 const basic_element_t* e1 = i0.
find(1);
101 BOOST_TEST(e1 ==
nullptr);
102 i0.
emplace([](basic_element_t& elem) {});
103 const basic_element_t* e2 = i0.
find(1);
104 BOOST_TEST((e2 !=
nullptr && e2->id == 1));
106 i0.
modify(*element, [](basic_element_t& elem) {});
108 element = i0.
find(0);
109 BOOST_TEST(element ==
nullptr);
113 template<
typename C,
typename A>
123 std::vector<std::pair<test_element_t, const test_element_t*>> vec;
124 for(
const auto& elem : index) {
125 vec.emplace_back(elem, &elem);
127 return scope_fail{[vec = std::move(vec), &index]{
128 BOOST_TEST(index.size() == vec.size());
129 for(
const auto& [elem, ptr] : vec) {
130 auto * actual0 = index.find(elem.id);
131 BOOST_TEST(actual0 == ptr);
132 if (actual0 !=
nullptr) {
133 BOOST_TEST(actual0->id == elem.id);
134 BOOST_TEST(actual0->secondary == elem.secondary);
136 auto actual1iter = index.template get<1>().find(elem.secondary);
137 BOOST_TEST((actual1iter != index.template get<1>().end() && &*actual1iter == actual0));
144 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
145 boost::multi_index::ordered_unique<key<&test_element_t::secondary> > > i0;
147 BOOST_TEST(i0.
find(0)->secondary == 42);
152 BOOST_TEST(i0.
find(1)->secondary == 12);
154 BOOST_TEST(i0.
find(0)->secondary == 42);
155 BOOST_TEST(i0.
find(1) ==
nullptr);
160 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
161 boost::multi_index::ordered_unique<key<&test_element_t::secondary> > > i0;
163 BOOST_TEST(i0.
find(0)->secondary == 42);
169 BOOST_TEST(i0.
find(1)->secondary == 12);
171 BOOST_TEST(i0.
find(1)->secondary == 12);
173 BOOST_TEST(i0.
find(0)->secondary == 42);
174 BOOST_TEST(i0.
find(1) ==
nullptr);
179 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
180 boost::multi_index::ordered_unique<key<&test_element_t::secondary> > > i0;
182 BOOST_TEST(i0.
find(0)->secondary == 42);
187 BOOST_TEST(i0.
find(1)->secondary == 12);
192 BOOST_TEST(i0.
find(0)->secondary == 42);
193 BOOST_TEST(i0.
find(1)->secondary == 12);
198 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
199 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
201 BOOST_TEST(i0.
find(0)->secondary == 42);
206 BOOST_TEST(i0.
find(0)->secondary == 18);
208 BOOST_TEST(i0.
find(0)->secondary == 42);
213 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
214 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
216 BOOST_TEST(i0.
find(0)->secondary == 42);
222 BOOST_TEST(i0.
find(0)->secondary == 18);
224 BOOST_TEST(i0.
find(0)->secondary == 18);
226 BOOST_TEST(i0.
find(0)->secondary == 42);
231 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
232 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
234 BOOST_TEST(i0.
find(0)->secondary == 42);
239 BOOST_TEST(i0.
find(0)->secondary == 18);
244 BOOST_TEST(i0.
find(0)->secondary == 18);
249 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
250 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
252 BOOST_TEST(i0.
find(0)->secondary == 42);
257 BOOST_TEST(i0.
find(0) ==
nullptr);
259 BOOST_TEST(i0.
find(0)->secondary == 42);
264 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
265 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
267 BOOST_TEST(i0.
find(0)->secondary == 42);
273 BOOST_TEST(i0.
find(0) ==
nullptr);
275 BOOST_TEST(i0.
find(0) ==
nullptr);
277 BOOST_TEST(i0.
find(0)->secondary == 42);
282 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
283 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
285 BOOST_TEST(i0.
find(0)->secondary == 42);
290 BOOST_TEST(i0.
find(0) ==
nullptr);
295 BOOST_TEST(i0.
find(0) ==
nullptr);
300 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
301 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
303 BOOST_TEST(i0.
find(0)->secondary == 42);
305 BOOST_TEST(i0.
find(1)->secondary == 12);
307 BOOST_TEST(i0.
find(1)->secondary == 24);
312 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
313 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
315 BOOST_TEST(i0.
find(0)->secondary == 42);
320 BOOST_TEST(i0.
find(1)->secondary == 12);
322 BOOST_TEST(i0.
find(1)->secondary == 24);
324 BOOST_TEST(i0.
find(0)->secondary == 42);
325 BOOST_TEST(i0.
find(1) ==
nullptr);
331 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
332 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
334 BOOST_TEST(i0.
find(0)->secondary == 42);
339 BOOST_TEST(i0.
find(1)->secondary == 12);
342 BOOST_TEST(i0.
find(1)->secondary == 24);
345 BOOST_TEST(i0.
find(0)->secondary == 42);
346 BOOST_TEST(i0.
find(1) ==
nullptr);
351 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
352 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
354 BOOST_TEST(i0.
find(0)->secondary == 42);
359 BOOST_TEST(i0.
find(1)->secondary == 12);
361 BOOST_TEST(i0.
find(1) ==
nullptr);
363 BOOST_TEST(i0.
find(0)->secondary == 42);
364 BOOST_TEST(i0.
find(1) ==
nullptr);
369 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
370 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
372 BOOST_TEST(i0.
find(0)->secondary == 42);
377 BOOST_TEST(i0.
find(1)->secondary == 12);
380 BOOST_TEST(i0.
find(1) ==
nullptr);
383 BOOST_TEST(i0.
find(0)->secondary == 42);
384 BOOST_TEST(i0.
find(1) ==
nullptr);
389 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
390 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
392 BOOST_TEST(i0.
find(0)->secondary == 42);
397 BOOST_TEST(i0.
find(0)->secondary == 18);
399 BOOST_TEST(i0.
find(0)->secondary == 24);
401 BOOST_TEST(i0.
find(0)->secondary == 42);
406 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
407 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
409 BOOST_TEST(i0.
find(0)->secondary == 42);
414 BOOST_TEST(i0.
find(0)->secondary == 18);
417 BOOST_TEST(i0.
find(0)->secondary == 24);
420 BOOST_TEST(i0.
find(0)->secondary == 42);
425 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
426 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
428 BOOST_TEST(i0.
find(0)->secondary == 42);
433 BOOST_TEST(i0.
find(0)->secondary == 18);
435 BOOST_TEST(i0.
find(0) ==
nullptr);
437 BOOST_TEST(i0.
find(0)->secondary == 42);
442 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
443 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
445 BOOST_TEST(i0.
find(0)->secondary == 42);
450 BOOST_TEST(i0.
find(0)->secondary == 18);
453 BOOST_TEST(i0.
find(0) ==
nullptr);
456 BOOST_TEST(i0.
find(0)->secondary == 42);
461 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
462 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
464 BOOST_TEST(i0.
find(0)->secondary == 42);
467 BOOST_TEST(i0.
find(0)->secondary == 18);
470 BOOST_TEST(i0.
find(0) ==
nullptr);
477 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
478 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
480 BOOST_TEST(i0.
find(0)->secondary == 42);
482 BOOST_TEST(i0.
find(0)->secondary == 42);
486 template<
typename C,
typename A>
497 boost::multi_index::ordered_unique<key<&conflict_element_t::id>>,
498 boost::multi_index::ordered_unique<key<&conflict_element_t::x0>>,
499 boost::multi_index::ordered_unique<key<&conflict_element_t::x1>>,
500 boost::multi_index::ordered_unique<key<&conflict_element_t::x2>>> i0;
516 BOOST_TEST(i0.
find(0)->x0 == 0);
517 BOOST_TEST(i0.
find(1)->x1 == 1);
518 BOOST_TEST(i0.
find(2)->x2 == 2);
520 BOOST_TEST(i0.
get<1>().find(0)->x0 == 0);
521 BOOST_TEST(i0.
get<1>().find(11)->x0 == 11);
522 BOOST_TEST(i0.
get<1>().find(12)->x0 == 12);
523 BOOST_TEST(i0.
get<2>().find(10)->x1 == 10);
524 BOOST_TEST(i0.
get<2>().find(1)->x1 == 1);
525 BOOST_TEST(i0.
get<2>().find(12)->x1 == 12);
526 BOOST_TEST(i0.
get<3>().find(10)->x2 == 10);
527 BOOST_TEST(i0.
get<3>().find(11)->x2 == 11);
528 BOOST_TEST(i0.
get<3>().find(2)->x2 == 2);
533 boost::multi_index::ordered_unique<key<&conflict_element_t::id>>,
534 boost::multi_index::ordered_unique<key<&conflict_element_t::x0>>,
535 boost::multi_index::ordered_unique<key<&conflict_element_t::x1>>,
536 boost::multi_index::ordered_unique<key<&conflict_element_t::x2>>> i0;
544 BOOST_CHECK_THROW(i0.
emplace([](
conflict_element_t& elem) { elem.x0 = 81; elem.x1 = 11; elem.x2 = 91; }), std::logic_error);
546 BOOST_TEST(i0.
find(0)->x0 == 10);
547 BOOST_TEST(i0.
find(1)->x1 == 11);
548 BOOST_TEST(i0.
find(2)->x2 == 12);
550 BOOST_TEST(i0.
get<1>().find(10)->x0 == 10);
551 BOOST_TEST(i0.
get<1>().find(11)->x0 == 11);
552 BOOST_TEST(i0.
get<1>().find(12)->x0 == 12);
553 BOOST_TEST(i0.
get<2>().find(10)->x1 == 10);
554 BOOST_TEST(i0.
get<2>().find(11)->x1 == 11);
555 BOOST_TEST(i0.
get<2>().find(12)->x1 == 12);
556 BOOST_TEST(i0.
get<3>().find(10)->x2 == 10);
557 BOOST_TEST(i0.
get<3>().find(11)->x2 == 11);
558 BOOST_TEST(i0.
get<3>().find(12)->x2 == 12);
563 boost::multi_index::ordered_unique<key<&conflict_element_t::id>>,
564 boost::multi_index::ordered_unique<key<&conflict_element_t::x0>>,
565 boost::multi_index::ordered_unique<key<&conflict_element_t::x1>>,
566 boost::multi_index::ordered_unique<key<&conflict_element_t::x2>>> i0;
575 BOOST_CHECK_THROW(i0.
modify(i0.
get(3), [](
conflict_element_t& elem) { elem.x0 = 71; elem.x1 = 10; elem.x2 = 91; }), std::logic_error);
577 BOOST_TEST(i0.
get<0>().size() == 3);
578 BOOST_TEST(i0.
get<1>().size() == 3);
579 BOOST_TEST(i0.
get<2>().size() == 3);
580 BOOST_TEST(i0.
get<3>().size() == 3);
581 BOOST_TEST(i0.
find(0)->x0 == 10);
582 BOOST_TEST(i0.
find(1)->x1 == 11);
583 BOOST_TEST(i0.
find(2)->x2 == 12);
585 BOOST_TEST(i0.
get<1>().find(10)->x0 == 10);
586 BOOST_TEST(i0.
get<1>().find(11)->x0 == 11);
587 BOOST_TEST(i0.
get<1>().find(12)->x0 == 12);
588 BOOST_TEST(i0.
get<2>().find(10)->x1 == 10);
589 BOOST_TEST(i0.
get<2>().find(11)->x1 == 11);
590 BOOST_TEST(i0.
get<2>().find(12)->x1 == 12);
591 BOOST_TEST(i0.
get<3>().find(10)->x2 == 10);
592 BOOST_TEST(i0.
get<3>().find(11)->x2 == 11);
593 BOOST_TEST(i0.
get<3>().find(12)->x2 == 12);
600 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
601 boost::multi_index::ordered_unique<boost::multi_index::tag<by_secondary>, key<&test_element_t::secondary>>> i0;
612 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
613 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
620 BOOST_CHECK(!tracker.is_removed(elem0));
621 BOOST_CHECK(!tracker.is_removed(elem1));
622 tracker.remove(elem0);
623 tracker.remove(elem1);
624 BOOST_CHECK(tracker.is_removed(elem0));
625 BOOST_CHECK(tracker.is_removed(elem1));
631 boost::multi_index::ordered_unique<key<&test_element_t::id>>,
632 boost::multi_index::ordered_unique<key<&test_element_t::secondary>>> i0;
638 BOOST_CHECK(!tracker.is_removed(elem0));
639 BOOST_CHECK(!tracker.is_removed(elem1));
640 tracker.remove(elem0);
641 tracker.remove(elem1);
642 BOOST_CHECK(tracker.is_removed(elem0));
643 BOOST_CHECK(tracker.is_removed(elem1));
646BOOST_AUTO_TEST_SUITE_END()
void modify(const value_type &obj, Modifier &&m)
const value_type & get(CompatibleKey &&key) const
bool has_undo_session() const
auto project(Iter iter) const
session start_undo_session(bool enabled)
void commit(int64_t revision) noexcept
const value_type * find(CompatibleKey &&key) const
const value_type & emplace(Constructor &&c)
void remove(const value_type &obj) noexcept
CK_SESSION_HANDLE session
constexpr enabler dummy
An instance to use in EnableIf.
bool uncaught_exceptions()
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define T(meth, val, expected)
unsigned __int64 uint64_t
conflict_element_t(C &&c, const test_allocator< A > &)
test_element_t(C &&c, const std::allocator< A > &)
#define EXCEPTION_TEST_CASE(name)
auto capture_state(const C &index)
BOOST_DATA_TEST_CASE(test_insert_fail, boost::unit_test::data::make({true, false}), use_undo)
BOOST_AUTO_TEST_CASE(test_project)
yubihsm_pkcs11_object_template template