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 |
|
---|
11 | using namespace boost::multi_index;
|
---|
12 |
|
---|
13 | struct employee
|
---|
14 | {
|
---|
15 | int id;
|
---|
16 | std:: string name;
|
---|
17 | employee(int id, std::string const& name): id{id}, name{name}{}
|
---|
18 | };
|
---|
19 |
|
---|
20 | bool operator<(employee const& lhs, employee const& rhs)
|
---|
21 | {
|
---|
22 | return lhs.id < rhs.id;
|
---|
23 | }
|
---|
24 |
|
---|
25 | std::ostream& operator<<(std::ostream& os, employee const& e)
|
---|
26 | {
|
---|
27 | os << e.name << " [" << e.id << "]"; return os;
|
---|
28 | }
|
---|
29 |
|
---|
30 |
|
---|
31 | struct id;
|
---|
32 | struct name;
|
---|
33 |
|
---|
34 | // define a multiply indexed set with indices by id and name
|
---|
35 | using 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 |
|
---|
43 | void 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 |
|
---|
54 | int 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 | }
|
---|