123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // Copyright (C) 2009-2012 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0
- // (see accompanying file LICENSE_1_0.txt or a copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Home at http://www.boost.org/libs/local_function
- #include "scope_exit.hpp"
- #include <boost/foreach.hpp>
- #include <boost/typeof/typeof.hpp>
- #include <boost/typeof/std/vector.hpp>
- #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
- #include <boost/detail/lightweight_test.hpp>
- #include <vector>
- #include <iostream>
- #include <sstream>
- class person {
- friend class world;
- public:
- typedef unsigned int id_t;
- typedef unsigned int evolution_t;
- person(void): id_(0), evolution_(0) {}
- friend std::ostream& operator<<(std::ostream& o, person const& p) {
- return o << "person(" << p.id_ << ", " << p.evolution_ << ")";
- }
- private:
- id_t id_;
- evolution_t evolution_;
- };
- BOOST_TYPEOF_REGISTER_TYPE(person)
- class world {
- public:
- typedef unsigned int id_t;
- world(void): next_id_(1) {}
- void add_person(person const& a_person);
- friend std::ostream& operator<<(std::ostream& o, world const& w) {
- o << "world(" << w.next_id_ << ", {";
- BOOST_FOREACH(person const& p, w.persons_) {
- o << " " << p << ", ";
- }
- return o << "})";
- }
- private:
- id_t next_id_;
- std::vector<person> persons_;
- };
- BOOST_TYPEOF_REGISTER_TYPE(world)
- void world::add_person(person const& a_person) {
- persons_.push_back(a_person);
- // This block must be no-throw.
- //[scope_exit
- person& p = persons_.back();
- person::evolution_t checkpoint = p.evolution_;
- SCOPE_EXIT(const bind checkpoint, const bind& p, bind this_) {
- if (checkpoint == p.evolution_) this_->persons_.pop_back();
- } SCOPE_EXIT_END
- //]
- // ...
- checkpoint = ++p.evolution_;
- // Assign new id to the person.
- world::id_t const prev_id = p.id_;
- p.id_ = next_id_++;
- SCOPE_EXIT(const bind checkpoint, const bind prev_id, bind& p,
- bind& next_id_) {
- if (checkpoint == p.evolution_) {
- next_id_ = p.id_;
- p.id_ = prev_id;
- }
- } SCOPE_EXIT_END
- // ...
- checkpoint = ++p.evolution_;
- }
- int main(void) {
- person adam, eva;
- std::ostringstream oss;
- oss << adam;
- std::cout << oss.str() << std::endl;
- BOOST_TEST(oss.str() == "person(0, 0)");
- oss.str("");
- oss << eva;
- std::cout << oss.str() << std::endl;
- BOOST_TEST(oss.str() == "person(0, 0)");
- world w;
- w.add_person(adam);
- w.add_person(eva);
- oss.str("");
- oss << w;
- std::cout << oss.str() << std::endl;
- BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })");
- return boost::report_errors();
- }
|