📄 operation_sequence.hpp
字号:
/* * * Distributed under the Boost Software License, Version 1.0.(See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) * * See http://www.boost.org/libs/iostreams for documentation. * * Defines the classes operation_sequence and operation, in the namespace * boost::iostreams::test, for verifying that all elements of a sequence of * operations are executed, and that they are executed in the correct order. * * File: libs/iostreams/test/detail/operation_sequence.hpp * Date: Mon Dec 10 18:58:19 MST 2007 * Copyright: 2007-2008 CodeRage, LLC * Author: Jonathan Turkanis * Contact: turkanis at coderage dot com */#ifndef BOOST_IOSTREAMS_TEST_OPERATION_SEQUENCE_HPP_INCLUDED#define BOOST_IOSTREAMS_TEST_OPERATION_SEQUENCE_HPP_INCLUDED#include <boost/config.hpp> // make sure size_t is in namespace std#include <cstddef>#include <climits>#include <map>#include <stdexcept>#include <string>#include <utility> // pair#include <vector>#include <boost/lexical_cast.hpp>#include <boost/preprocessor/iteration/local.hpp>#include <boost/shared_ptr.hpp>#include <boost/test/test_tools.hpp>#include <boost/weak_ptr.hpp>#ifndef BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR# define BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR 20#endif#define BOOST_CHECK_OPERATION_SEQUENCE(seq) \ BOOST_CHECK_MESSAGE(seq.is_success(), seq.message()) \ /**/namespace boost { namespace iostreams { namespace test {// Simple exception class with error code built in to typetemplate<int Code>struct operation_error { };class operation_sequence;// Represent an operation in a sequence of operations to be executedclass operation {public: friend class operation_sequence; operation() : pimpl_() { } void execute();private: static void remove_operation(operation_sequence& seq, int id); struct impl { impl(operation_sequence& seq, int id, int error_code = -1) : seq(seq), id(id), error_code(error_code) { } ~impl() { remove_operation(seq, id); } impl& operator=(const impl&); // Supress VC warning 4512 operation_sequence& seq; int id; int error_code; }; friend struct impl; operation(operation_sequence& seq, int id, int error_code = -1) : pimpl_(new impl(seq, id, error_code)) { } shared_ptr<impl> pimpl_;};// Represents a sequence of operations to be executed in a particular orderclass operation_sequence {public: friend class operation; operation_sequence() { reset(); } // // Returns a new operation. // Parameters: // // id - The operation id, determining the position // of the new operation in the operation sequence // error_code - If supplied, indicates that the new // operation will throw operation_error<error_code> // when executed. Must be an integer between 0 and // BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR, // inclusive. // operation new_operation(int id, int error_code = INT_MAX); bool is_success() const { return success_; } bool is_failure() const { return failed_; } std::string message() const; void reset();private: void execute(int id); void remove_operation(int id); operation_sequence(const operation_sequence&); operation_sequence& operator=(const operation_sequence&); typedef weak_ptr<operation::impl> ptr_type; typedef std::map<int, ptr_type> map_type; map_type operations_; std::vector<int> log_; std::size_t total_executed_; int last_executed_; bool success_; bool failed_;};//--------------Implementation of operation-----------------------------------//void operation::execute(){ pimpl_->seq.execute(pimpl_->id); switch (pimpl_->error_code) { // Implementation with one or more cleanup operations #define BOOST_PP_LOCAL_MACRO(n) \ case n: throw operation_error<n>(); \ /**/ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR) #include BOOST_PP_LOCAL_ITERATE() #undef BOOST_PP_LOCAL_MACRO default: break; }}inline void operation::remove_operation(operation_sequence& seq, int id){ seq.remove_operation(id);}//--------------Implementation of operation_sequence--------------------------//inline operation operation_sequence::new_operation(int id, int error_code){ using namespace std; if ( error_code < 0 || error_code > BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR && error_code != INT_MAX ) { throw runtime_error( string("The error code ") + lexical_cast<string>(error_code) + " is out of range" ); } if (last_executed_ != INT_MIN) throw runtime_error( "Operations in progress; call reset() " "before creating more operations" ); map_type::const_iterator it = operations_.find(id); if (it != operations_.end()) throw runtime_error( string("The operation ") + lexical_cast<string>(id) + " already exists" ); operation op(*this, id, error_code); operations_.insert(make_pair(id, ptr_type(op.pimpl_))); return op;}inline std::string operation_sequence::message() const{ using namespace std; if (success_) return "success"; std::string msg = failed_ ? "operations occurred out of order: " : "operation sequence is incomplete: "; typedef vector<int>::size_type size_type; for (size_type z = 0, n = log_.size(); z < n; ++z) { msg += lexical_cast<string>(log_[z]); if (z < n - 1) msg += ','; } return msg;}inline void operation_sequence::reset() { log_.clear(); total_executed_ = 0; last_executed_ = INT_MIN; success_ = false; failed_ = false;}inline void operation_sequence::execute(int id){ log_.push_back(id); if (!failed_ && last_executed_ < id) { if (++total_executed_ == operations_.size()) success_ = true; last_executed_ = id; } else { success_ = false; failed_ = true; }}inline void operation_sequence::remove_operation(int id){ using namespace std; map_type::iterator it = operations_.find(id); if (it == operations_.end()) throw runtime_error( string("No such operation: ") + lexical_cast<string>(id) ); operations_.erase(it);}} } } // End namespace boost::iostreams::test.#endif // #ifndef BOOST_IOSTREAMS_TEST_OPERATION_SEQUENCE_HPP_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -