diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-06-25 22:59:01 +0000 |
---|---|---|
committer | <> | 2013-09-27 11:49:28 +0000 |
commit | 8c4528713d907ee2cfd3bfcbbad272c749867f84 (patch) | |
tree | c09e2ce80f47b90c85cc720f5139089ad9c8cfff /libs/local_function/example/scope_exit.cpp | |
download | boost-tarball-8c4528713d907ee2cfd3bfcbbad272c749867f84.tar.gz |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_54_0.tar.bz2.boost_1_54_0baserock/morph
Diffstat (limited to 'libs/local_function/example/scope_exit.cpp')
-rw-r--r-- | libs/local_function/example/scope_exit.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/libs/local_function/example/scope_exit.cpp b/libs/local_function/example/scope_exit.cpp new file mode 100644 index 000000000..607bf6be0 --- /dev/null +++ b/libs/local_function/example/scope_exit.cpp @@ -0,0 +1,110 @@ + +// 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(); +} + |