Ticket #12542: main.cpp

File main.cpp, 2.3 KB (added by Jon Kalb <jonkalb@…>, 6 years ago)

Demonstrating multi_index index corruption bug.

Line 
1
2#include "boost/multi_index_container.hpp"
3#include "boost/multi_index/member.hpp"
4#include "boost/multi_index/ordered_index.hpp"
5#include <boost/multi_index/sequenced_index.hpp>
6
7#include <algorithm>
8#include <list>
9#include <iostream>
10
11using namespace boost::multi_index;
12
13struct employee
14{
15 int id;
16 std:: string name;
17 employee(int id, std::string const& name): id{id}, name{name}{}
18};
19
20bool operator<(employee const& lhs, employee const& rhs)
21{
22 return lhs.id < rhs.id;
23}
24
25std::ostream& operator<<(std::ostream& os, employee const& e)
26{
27 os << e.name << " [" << e.id << "]"; return os;
28}
29
30
31struct id;
32struct name;
33
34// define a multiply indexed set with indices by id and name
35using employees = boost::multi_index_container<
36 employee,
37 indexed_by<
38 // sort by operator<(employee, employee)
39 ordered_unique<tag<id>, identity<employee>>,
40 // sort by less<string> on name
41 ordered_non_unique<tag<name>, member<employee, std::string, &employee::name>>>>;
42
43void print_out_by_name(employees const& es)
44{
45 // get a view to index #1 (name)
46 auto & name_index(es.get<name>());
47 // use name_index as a regular std::set
48 std::copy(
49 name_index.begin(),name_index.end(),
50 std::ostream_iterator<employee>(std::cout, "\n"));
51}
52
53
54int main()
55{
56 employees es;
57 es.insert({0, "Adam"});
58 es.insert({1, "Eve"});
59 es.insert({2, "Bob"});
60
61 std::cout << "Employee ids must be unique.\n";
62 std::cout << "Here are the original records:\n";
63 print_out_by_name(es);
64
65 std::cout << "Changing Bob's id to one which is already taken (1).\n";
66 std::cout << "Calling modify() with a callable that violates the index constraint\n";
67 std::cout << "and a rollback callable that does nothing to fix the problem.\n";
68 auto& name_index(es.get<name>());
69 auto it(name_index.find("Bob"));
70 bool succeed{name_index.modify(
71 it,
72 [](employee& e) {e.id = 1;},
73 [](employee& e) { std::cout << "[confirming rollback called]\n";})};
74 std::cout << "Call succeeded: " << std::boolalpha << succeed << "\n";
75 std::cout << "Here are the post-modify-call records.\n";
76 print_out_by_name(es);
77 std::cout << "We now have a duplicated unique key value.\n";
78
79 std::cout << "\nIf the rollback fails to correct the problem, should the record not be deleted?\n";
80}