⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut.h

📁 美国加州大学操作系统课程实验平台Nachos
💻 H
📖 第 1 页 / 共 2 页
字号:
     * Throws if false.     */    void ensure(const char* msg,bool cond)    {       if( !cond ) throw failure(msg);    }    /**     * Tests two objects for being equal.     * Throws if false.     *     * NB: both T and Q must have operator << defined somewhere, or     * client code will not compile at all!     */    template <class T,class Q>    void ensure_equals(const char* msg,const Q& actual,const T& expected)    {      if( expected != actual )      {        std::stringstream ss;        ss << (msg?msg:"") << (msg?": ":"") << "expected " << expected << " actual " << actual;        throw failure(ss.str().c_str());      }    }    template <class T,class Q>    void ensure_equals(const Q& actual,const T& expected)    {      ensure_equals<>(0,actual,expected);    }    /**     * Tests two objects for being at most in given distance one from another.     * Borders are excluded.     * Throws if false.     *     * NB: T must have operator << defined somewhere, or     * client code will not compile at all! Also, T shall have     * operators + and -, and be comparable.     */    template <class T>    void ensure_distance(const char* msg,const T& actual,const T& expected,const T& distance)    {      if( expected-distance >= actual || expected+distance <= actual )      {        std::stringstream ss;        ss << (msg?msg:"") << (msg?": ":"") << "expected [" << expected-distance << ";"            << expected+distance << "] actual " << actual;        throw failure(ss.str().c_str());      }    }    template <class T>    void ensure_distance(const T& actual,const T& expected,const T& distance)    {      ensure_distance<>(0,actual,expected,distance);    }    /**     * Unconditionally fails with message.     */    void fail(const char* msg="")    {      throw failure(msg);    }  }  /**   * Walks through test tree and stores address of each   * test method in group. Instantiation stops at 0.   */  template <class Test,class Group,int n>  struct tests_registerer  {    static void reg(Group& group)    {      group.reg(n,&Test::template test<n>);      tests_registerer<Test,Group,n-1>::reg(group);    }  };  template<class Test,class Group>  struct tests_registerer<Test,Group,0>  {    static void reg(Group&){};  };  /**   * Test group; used to recreate test object instance for   * each new test since we have to have reinitialized    * Data base class.   */  template <class Data,int MaxTestsInGroup = 50>  class test_group : public group_base  {    const char* name_;    typedef void (test_object<Data>::*testmethod)();    typedef std::map<int,testmethod> tests;    typedef typename tests::iterator tests_iterator;    typedef typename tests::const_iterator tests_const_iterator;    typedef typename tests::const_reverse_iterator                      tests_const_reverse_iterator;    typedef typename tests::size_type size_type;    tests tests_;    tests_iterator current_test_;    /**     * Exception-in-destructor-safe smart-pointer class.     */    template <class T>    class safe_holder    {      T* p_;      bool permit_throw_in_dtor;      safe_holder(const safe_holder&);      safe_holder& operator = (const safe_holder&);      public:      safe_holder() : p_(0),permit_throw_in_dtor(false)      {       }      ~safe_holder()      {        release();      }      T* operator -> () const { return p_; };      T* get() const { return p_; };      /**       * Tell ptr it can throw from destructor. Right way is to       * use std::uncaught_exception(), but some compilers lack       * correct implementation of the function.       */      void permit_throw(){ permit_throw_in_dtor = true; }      /**       * Specially treats exceptions in test object destructor;        * if test itself failed, exceptions in destructor       * are ignored; if test was successful and destructor failed,       * warning exception throwed.       */      void release()      {        try        {          if( delete_obj() == false )          {            throw warning("destructor of test object raised an SEH exception");          }        }        catch( const std::exception& ex )        {          if( permit_throw_in_dtor )           {            std::string msg = "destructor of test object raised exception:";            msg += ex.what();            throw warning(msg);          }        }        catch( ... )        {          if( permit_throw_in_dtor )          {            throw warning("destructor of test object raised an exception");          }        }      }      /**       * Re-init holder to get brand new object.       */      void reset()      {        release();        permit_throw_in_dtor = false;        p_ = new T();      }      bool delete_obj()      {#if defined(TUT_USE_SEH)        __try        {#endif          T* p = p_;           p_ = 0;          delete p;#if defined(TUT_USE_SEH)        }        __except(handle_seh_(::GetExceptionCode()))        {          if( permit_throw_in_dtor )          {            return false;          }        }#endif        return true;      }    };    public:    typedef test_object<Data> object;        /**     * Creates and registers test group with specified name.     */    test_group(const char* name)      : name_(name)    {      // register itself      runner.get().register_group(name_,this);          // register all tests      tests_registerer<object,test_group,MaxTestsInGroup>::reg(*this);    };    /**     * This constructor is used in self-test run only.     */    test_group(const char* name,test_runner& another_runner)      : name_(name)    {      // register itself      another_runner.register_group(name_,this);           // register all tests      tests_registerer<test_object<Data>,                       test_group,MaxTestsInGroup>::reg(*this);    };    /**     * Registers test method under given number.     */    void reg(int n,testmethod tm)    {      tests_[n] = tm;    }    /**     * Reset test position before first test.     */    void rewind()    {      current_test_ = tests_.begin();    }    /**     * Runs next test.     */    test_result run_next()    {      if( current_test_ == tests_.end() )      {        throw no_more_tests();      }      // find next user-specialized test      safe_holder<object> obj;      while( current_test_ != tests_.end() )      {        try        {          return run_test_(current_test_++,obj);        }        catch( const no_such_test& )        {          continue;         }      }       throw no_more_tests();    }    /**     * Runs one test by position.     */    test_result run_test(int n)    {      // beyond tests is special case to discover upper limit      if( tests_.rbegin() == tests_.rend() ) throw beyond_last_test();      if( tests_.rbegin()->first < n ) throw beyond_last_test();      // withing scope; check if given test exists      tests_iterator ti = tests_.find(n);      if( ti == tests_.end() ) throw no_such_test();      safe_holder<object> obj;      return run_test_(ti,obj);    }  private:    /**     * VC allows only one exception handling type per function,     * so I have to split the method     */    test_result run_test_(const tests_iterator& ti,safe_holder<object>& obj)    {      try      {        if( run_test_seh_(ti->second,obj) == false )          throw seh("seh");      }      catch(const no_such_test&)      {        throw;      }      catch(const warning& ex)      {        // test ok, but destructor failed        test_result tr(name_,ti->first,test_result::warn,ex);        return tr;      }      catch(const failure& ex)      {        // test failed because of ensure() or similar method        test_result tr(name_,ti->first,test_result::fail,ex);        return tr;      }      catch(const seh& ex)      {        // test failed with sigsegv, divide by zero, etc        test_result tr(name_,ti->first,test_result::term,ex);        return tr;      }      catch(const std::exception& ex)      {        // test failed with std::exception        test_result tr(name_,ti->first,test_result::ex,ex);        return tr;      }      catch(...)      {        // test failed with unknown exception        test_result tr(name_,ti->first,test_result::ex);        return tr;      }      // test passed      test_result tr(name_,ti->first,test_result::ok);      return tr;    }    /**     * Runs one under SEH if platform supports it.     */    bool run_test_seh_(testmethod tm,safe_holder<object>& obj)    {#if defined(TUT_USE_SEH)      __try      {#endif        if( obj.get() == 0 ) obj.reset();        obj->called_method_was_a_dummy_test_ = false;#if defined(TUT_USE_SEH)        __try        {#endif          (obj.get()->*tm)();#if defined(TUT_USE_SEH)        }        __except(handle_seh_(::GetExceptionCode()))        {          // throw seh("SEH");          return false;        }#endif        if( obj->called_method_was_a_dummy_test_ )        {          // do not call obj.release(); reuse object          throw no_such_test();        }        obj.permit_throw();        obj.release();#if defined(TUT_USE_SEH)      }      __except(handle_seh_(::GetExceptionCode()))      {        // throw seh("SEH");        return false;      }#endif      return true;    }  };#if defined(TUT_USE_SEH)  /**   * Decides should we execute handler or ignore SE.   */  inline int handle_seh_(DWORD excode)  {    switch(excode)    {      case EXCEPTION_ACCESS_VIOLATION:      case EXCEPTION_DATATYPE_MISALIGNMENT:      case EXCEPTION_BREAKPOINT:      case EXCEPTION_SINGLE_STEP:      case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:      case EXCEPTION_FLT_DENORMAL_OPERAND:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:      case EXCEPTION_FLT_INEXACT_RESULT:              case EXCEPTION_FLT_INVALID_OPERATION:      case EXCEPTION_FLT_OVERFLOW:      case EXCEPTION_FLT_STACK_CHECK:      case EXCEPTION_FLT_UNDERFLOW:      case EXCEPTION_INT_DIVIDE_BY_ZERO:      case EXCEPTION_INT_OVERFLOW:      case EXCEPTION_PRIV_INSTRUCTION:      case EXCEPTION_IN_PAGE_ERROR:      case EXCEPTION_ILLEGAL_INSTRUCTION:      case EXCEPTION_NONCONTINUABLE_EXCEPTION:      case EXCEPTION_STACK_OVERFLOW:      case EXCEPTION_INVALID_DISPOSITION:      case EXCEPTION_GUARD_PAGE:      case EXCEPTION_INVALID_HANDLE:        return EXCEPTION_EXECUTE_HANDLER;    };        return EXCEPTION_CONTINUE_SEARCH;  }#endif}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -