1
2// Copyright (C) 2006-2009, 2012 Alexander Nasonov
3// Copyright (C) 2012 Lorenzo Caminiti
4// Distributed under the Boost Software License, Version 1.0
5// (see accompanying file LICENSE_1_0.txt or a copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7// Home at http://www.boost.org/libs/scope_exit
8
9#include <boost/scope_exit.hpp>
10#include <boost/foreach.hpp>
11#include <boost/typeof/typeof.hpp>
12#include <boost/typeof/std/vector.hpp>
13#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
14#include <boost/detail/lightweight_test.hpp>
15#include <vector>
16#include <sstream>
17
18struct person {
19 typedef unsigned int id_t;
20 typedef unsigned int evolution_t;
21
22 id_t id;
23 evolution_t evolution;
24
25 person(void) : id(0), evolution(0) {}
26
27 friend std::ostream& operator<<(std::ostream& o, person const& p) {
28 return o << "person(" << p.id << ", " << p.evolution << ")";
29 }
30};
31BOOST_TYPEOF_REGISTER_TYPE(person)
32
33struct world {
34 world(void) : next_id_(1) {}
35 void add_person(person const& a_person);
36
37 friend std::ostream& operator<<(std::ostream& o, world const& w) {
38 o << "world(" << w.next_id_ << ", {";
39 BOOST_FOREACH(person const& p, w.persons_) {
40 o << " " << p << ", ";
41 }
42 return o << "})";
43 }
44
45private:
46 person::id_t next_id_;
47 std::vector<person> persons_;
48};
49BOOST_TYPEOF_REGISTER_TYPE(world)
50
51void world::add_person(person const& a_person) {
52 persons_.push_back(x: a_person);
53
54 // This block must be no-throw.
55 person& p = persons_.back();
56 person::evolution_t checkpoint = p.evolution;
57 BOOST_SCOPE_EXIT( (checkpoint) (&p) (&persons_) ) {
58 if(checkpoint == p.evolution) persons_.pop_back();
59 } BOOST_SCOPE_EXIT_END
60
61 // ...
62
63 checkpoint = ++p.evolution;
64
65 // Assign new identifier to the person.
66 person::id_t const prev_id = p.id;
67 p.id = next_id_++;
68 BOOST_SCOPE_EXIT( (checkpoint) (&p) (&next_id_) (prev_id) ) {
69 if(checkpoint == p.evolution) {
70 next_id_ = p.id;
71 p.id = prev_id;
72 }
73 } BOOST_SCOPE_EXIT_END
74
75 // ...
76
77 checkpoint = ++p.evolution;
78}
79
80int main(void) {
81 person adam, eva;
82 std::ostringstream oss;
83 oss << adam;
84 BOOST_TEST(oss.str() == "person(0, 0)");
85
86 oss.str(s: "");
87 oss << eva;
88 BOOST_TEST(oss.str() == "person(0, 0)");
89
90 world w;
91 w.add_person(a_person: adam);
92 w.add_person(a_person: eva);
93 oss.str(s: "");
94 oss << w;
95 BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
96
97 return boost::report_errors();
98}
99
100

source code of boost/libs/scope_exit/test/world_checkpoint_seq.cpp