<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Problem mit Visual Studio 2005]]></title><description><![CDATA[<p>Ich hab im MS VS 2005 ein neues Projekt angelegt, dann Windows Konsolenanwendung, und dann leeres Projekt noch eingestellt.</p>
<p>So und da habe ich nun unten folgenden Code eingefuegt (main.ccp).<br />
Die beiden eingebundenen header files, tut.h und tut_reporter.h hab ich nat. auch hinzugefuegt.<br />
Soweit alles kein Problem, mach ich ja oefter.<br />
Was nun sehr komisch is, wenn ich kompilieren moecht, kommt ein error:<br />
atal error C1083: Datei (Include) kann nicht geöffnet werden: &quot;tut.h&quot;: No such file or directory</p>
<p>das gleich auch nochmal fuer die tut_report.h.</p>
<p>Ok dachte liegt daran, weil die beiden header mit &lt;&gt; Klammen eingebunden werden (Kompiler sicht nicht im aktuellen Pfad, sondern im Windows Source Verzeichnis), also geaendert in &quot;&quot;, aber das gleiche Problem.</p>
<p>Besten Dank,Georg</p>
<pre><code>#include &lt;tut.h&gt;
#include &lt;tut_reporter.h&gt;
#include &lt;iostream&gt;

namespace tut
{
  test_runner_singleton runner;
}

int main(int argc,const char* argv[])
{
  tut::reporter visi;

  if( argc &lt; 2 || argc &gt; 3 )
  {
    std::cout &lt;&lt; &quot;TUT example test application.&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;Usage: example [regression] | [list] | [ group] [test]&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       List all groups: example list&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run all tests: example regression&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run one group: example std::auto_ptr&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run one test: example std::auto_ptr 3&quot; &lt;&lt; std::endl;;
  }

  std::cout &lt;&lt; &quot;\nFAILURE and EXCEPTION in these tests are FAKE ;)\n\n&quot;;

  tut::runner.get().set_callback(&amp;visi);

  try
  {
    if( argc == 1 || (argc == 2 &amp;&amp; std::string(argv[1]) == &quot;regression&quot;) )
    {
      tut::runner.get().run_tests();
    }
    else if( argc == 2 &amp;&amp; std::string(argv[1]) == &quot;list&quot; )
    {
      std::cout &lt;&lt; &quot;registered test groups:&quot; &lt;&lt; std::endl;
      tut::groupnames gl = tut::runner.get().list_groups();
      tut::groupnames::const_iterator i = gl.begin();
      tut::groupnames::const_iterator e = gl.end();
      while( i != e )
      {
        std::cout &lt;&lt; &quot;  &quot; &lt;&lt; *i &lt;&lt; std::endl;
        ++i;
      }
    }
    else if( argc == 2 &amp;&amp; std::string(argv[1]) != &quot;regression&quot; )
    {
      tut::runner.get().run_tests(argv[1]);
    }
    else if( argc == 3 )
    {
      tut::runner.get().run_test(argv[1],::atoi(argv[2]));
    }
  }
  catch( const std::exception&amp; ex )
  {
    std::cerr &lt;&lt; &quot;tut raised ex: &quot; &lt;&lt; ex.what() &lt;&lt; std::endl;
  }

  return 0;
}
</code></pre>
<p>tut.h:</p>
<pre><code>#ifndef TUT_H_GUARD
#define TUT_H_GUARD

#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;vector&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
#include &lt;stdexcept&gt;
#include &lt;typeinfo&gt;

#if defined(TUT_USE_SEH)
#include &lt;windows.h&gt;
#include &lt;winbase.h&gt;
#endif

/**
 * Template Unit Tests Framework for C++.
 * http://tut.dozen.ru
 *
 * @author dozen, tut@dozen.ru
 */
namespace tut
{
  /**
   * Exception to be throwed when attempted to execute 
   * missed test by number.
   */
  struct no_such_test : public std::logic_error
  {
    no_such_test() : std::logic_error(&quot;no such test&quot;){};
  };

  /**
   * No such test and passed test number is higher than
   * any test number in current group. Used in one-by-one
   * test running when upper bound is not known.
   */
  struct beyond_last_test : public no_such_test
  {
    beyond_last_test(){};
  };

  /**
   * Group not found exception.
   */
  struct no_such_group : public std::logic_error
  {
    no_such_group(const std::string&amp; grp) : 
      std::logic_error(grp){};
  };

  /**
   * Internal exception to be throwed when 
   * no more tests left in group or journal.
   */
  struct no_more_tests
  {
    no_more_tests(){};
  };

  /**
   * Internal exception to be throwed when 
   * test constructor has failed.
   */
  struct bad_ctor : public std::logic_error
  {
    bad_ctor(const std::string&amp; msg) : 
      std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when ensure() fails or fail() called.
   */
  class failure : public std::logic_error
  {
    public:
      failure(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when test desctructor throwed an exception.
   */
  class warning : public std::logic_error
  {
    public:
      warning(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when test issued SEH (Win32)
   */
  class seh : public std::logic_error
  {
    public:
      seh(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Return type of runned test/test group.
   *
   * For test: contains result of test and, possible, message
   * for failure or exception.
   */
  struct test_result
  {
    /**
     * Test group name.
     */
    std::string group;

    /**
     * Test number in group.
     */
    int test;

    /**
     * ok - test finished successfully
     * fail - test failed with ensure() or fail() methods
     * ex - test throwed an exceptions
     * warn - test finished successfully, but test destructor throwed
     * term - test forced test application to terminate abnormally
     */
    typedef enum { ok, fail, ex, warn, term, ex_ctor } result_type;
    result_type result;

    /**
     * Exception message for failed test.
     */
    std::string message;
    std::string exception_typeid;

    /**
     * Default constructor.
     */
    test_result()
      : test(0),result(ok)
    {
    }

    /**
     * Constructor.
     */
    test_result( const std::string&amp; grp,int pos,result_type res)
      : group(grp),test(pos),result(res)
    {
    }

    /**
     * Constructor with exception.
     */
    test_result( const std::string&amp; grp,int pos,
                 result_type res,
                 const std::exception&amp; ex)
      : group(grp),test(pos),result(res),
        message(ex.what()),exception_typeid(typeid(ex).name())
    {
    }
  };

  /**
   * Interface.
   * Test group operations.
   */
  struct group_base
  {
    virtual ~group_base(){};

    // execute tests iteratively
    virtual void rewind() = 0;
    virtual test_result run_next() = 0;

    // execute one test
    virtual test_result run_test(int n) = 0;
  };

  /**
   * Test runner callback interface.
   * Can be implemented by caller to update
   * tests results in real-time. User can implement 
   * any of callback methods, and leave unused 
   * in default implementation.
   */
  struct callback
  {
    /**
     * Virtual destructor is a must for subclassed types.
     */
    virtual ~callback(){};

    /**
     * Called when new test run started.
     */
    virtual void run_started(){};

    /**
     * Called when a group started
     * @param name Name of the group
     */
    virtual void group_started(const std::string&amp; /*name*/){};

    /**
     * Called when a test finished.
     * @param tr Test results.
     */
    virtual void test_completed(const test_result&amp; /*tr*/){};

    /**
     * Called when a group is completed
     * @param name Name of the group
     */
    virtual void group_completed(const std::string&amp; /*name*/){};

    /**
     * Called when all tests in run completed.
     */
    virtual void run_completed(){};
  };

  /**
   * Typedef for runner::list_groups()
   */
  typedef std::vector&lt;std::string&gt; groupnames;

  /**
   * Test runner.
   */
  class test_runner
  {
    protected:
      typedef std::map&lt;std::string,group_base*&gt; groups;
      typedef groups::iterator iterator;
      typedef groups::const_iterator const_iterator;
      groups groups_;

      callback  default_callback_;
      callback* callback_;

    public:
    /**
     * Constructor
     */
    test_runner() : callback_(&amp;default_callback_)
    {
    }

    /**
     * Stores another group for getting by name.
     */
    void register_group(const std::string&amp; name,group_base* gr)
    {
      if( gr == 0 )
      {
        throw std::invalid_argument(&quot;group shall be non-null&quot;);
      }

      groups::iterator found = groups_.find(name);
      if( found != groups_.end() )
      {
        std::string msg(&quot;attempt to add already existent group &quot;+name);
        // this exception terminates application so we use cerr also
        std::cerr &lt;&lt; msg &lt;&lt; std::endl;
        throw std::logic_error(msg);
      }

      groups_[name] = gr;
    }

    /**
     * Stores callback object.
     */
    void set_callback(callback* cb)
    {
      callback_ = cb==0? &amp;default_callback_:cb;
    }

    /**
     * Returns callback object.
     */
    callback&amp; get_callback() const
    {
      return *callback_;
    }

    /**
     * Returns list of known test groups.
     */
    const groupnames list_groups() const
    {
      groupnames ret;
      const_iterator i = groups_.begin();
      const_iterator e = groups_.end();
      while( i != e )
      {
        ret.push_back(i-&gt;first);
        ++i;
      }
      return ret;
    }

    /**
     * Runs all tests in all groups.
     * @param callback Callback object if exists; null otherwise
     */
    void run_tests() const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.begin();
      const_iterator e = groups_.end();
      while( i != e )
      {
        callback_-&gt;group_started(i-&gt;first);
        try
        {
          run_all_tests_in_group_(i);
        }
        catch( const no_more_tests&amp; )
        {
          callback_-&gt;group_completed(i-&gt;first);
        }

        ++i;
      }

      callback_-&gt;run_completed();
    }

    /**
     * Runs all tests in specified group.
     */
    void run_tests(const std::string&amp; group_name) const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.find(group_name);
      if( i == groups_.end() )
      {
        callback_-&gt;run_completed();
        throw no_such_group(group_name);
      }

      callback_-&gt;group_started(group_name);
      try
      {
        run_all_tests_in_group_(i);
      }
      catch( const no_more_tests&amp; )
      {
        // ok
      }

      callback_-&gt;group_completed(group_name);
      callback_-&gt;run_completed();
    }

    /**
     * Runs one test in specified group.
     */
    test_result run_test(const std::string&amp; group_name,int n) const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.find(group_name);
      if( i == groups_.end() )
      {
        callback_-&gt;run_completed();
        throw no_such_group(group_name);
      }

      callback_-&gt;group_started(group_name);
      try
      {
        test_result tr = i-&gt;second-&gt;run_test(n);
        callback_-&gt;test_completed(tr);
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        return tr;
      }
      catch( const beyond_last_test&amp; )
      {
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        throw;
      }      
      catch( const no_such_test&amp; )
      {
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        throw;
      }
    }

    private:
    void run_all_tests_in_group_(const_iterator i) const
    {
      i-&gt;second-&gt;rewind();
      for( ;; )
      {
        test_result tr = i-&gt;second-&gt;run_next();
        callback_-&gt;test_completed(tr);

	if( tr.result == test_result::ex_ctor )
	{
          throw no_more_tests();
        }
      }
    }
  };

  /**
   * Singleton for test_runner implementation.
   * Instance with name runner_singleton shall be implemented
   * by user.
   */
  class test_runner_singleton
  {
    public:
      static test_runner&amp; get()
      {
        static test_runner tr;
        return tr;
      }
  };
  extern test_runner_singleton runner;

  /**
   * Test object. Contains data test run upon and default test method 
   * implementation. Inherited from Data to allow tests to  
   * access test data as members.
   */
  template &lt;class Data&gt;
  class test_object : public Data
  {
    public:
    /**
     * Default constructor
     */
    test_object(){};

    /**
     * The flag is set to true by default (dummy) test.
     * Used to detect usused test numbers and avoid unnecessary
     * test object creation which may be time-consuming depending
     * on operations described in Data::Data() and Data::~Data().
     * TODO: replace with throwing special exception from default test.
     */
    bool called_method_was_a_dummy_test_;

    /**
     * Default do-nothing test.
     */
    template &lt;int n&gt;
    void test()
    {
      called_method_was_a_dummy_test_ = true;
    }
  };

  namespace 
  {
    /**
     * Tests provided condition.
     * Throws if false.
     */
    void ensure(bool cond)
    {
       if( !cond ) throw failure(&quot;&quot;);
    }

    /**
     * Tests provided condition.
     * Throws if false.
     */
    template&lt;typename T&gt;
    void ensure(const T 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 &lt;&lt; defined somewhere, or
     * client code will not compile at all!
     */
    template &lt;class T,class Q&gt;
    void ensure_equals(const char* msg,const Q&amp; actual,const T&amp; expected)
    {
      if( expected != actual )
      {
        std::stringstream ss;
        ss &lt;&lt; (msg?msg:&quot;&quot;) &lt;&lt; (msg?&quot;: &quot;:&quot;&quot;) &lt;&lt; &quot;expected &quot; &lt;&lt; expected &lt;&lt; &quot; actual &quot; &lt;&lt; actual;
        throw failure(ss.str().c_str());
      }
    }

    template &lt;class T,class Q&gt;
    void ensure_equals(const Q&amp; actual,const T&amp; expected)
    {
      ensure_equals&lt;&gt;(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 &lt;&lt; defined somewhere, or
     * client code will not compile at all! Also, T shall have
     * operators + and -, and be comparable.
     */
    template &lt;class T&gt;
    void ensure_distance(const char* msg,const T&amp; actual,const T&amp; expected,const T&amp; distance)
    {
      if( expected-distance &gt;= actual || expected+distance &lt;= actual )
      {
        std::stringstream ss;
        ss &lt;&lt; (msg?msg:&quot;&quot;) &lt;&lt; (msg?&quot;: &quot;:&quot;&quot;) &lt;&lt; &quot;expected [&quot; &lt;&lt; expected-distance &lt;&lt; &quot;;&quot; 
           &lt;&lt; expected+distance &lt;&lt; &quot;] actual &quot; &lt;&lt; actual;
        throw failure(ss.str().c_str());
      }
    }

    template &lt;class T&gt;
    void ensure_distance(const T&amp; actual,const T&amp; expected,const T&amp; distance)
    {
      ensure_distance&lt;&gt;(0,actual,expected,distance);
    }

    /**
     * Unconditionally fails with message.
     */
    void fail(const char* msg=&quot;&quot;)
    {
      throw failure(msg);
    }
  }

  /**
   * Walks through test tree and stores address of each
   * test method in group. Instantiation stops at 0.
   */
  template &lt;class Test,class Group,int n&gt;
  struct tests_registerer
  {
    static void reg(Group&amp; group)
    {
      group.reg(n,&amp;Test::template test&lt;n&gt;);
      tests_registerer&lt;Test,Group,n-1&gt;::reg(group);
    }
  };

  template&lt;class Test,class Group&gt;
  struct tests_registerer&lt;Test,Group,0&gt;
  {
    static void reg(Group&amp;){};
  };

  /**
   * Test group; used to recreate test object instance for
   * each new test since we have to have reinitialized 
   * Data base class.
   */
  template &lt;class Data,int MaxTestsInGroup = 50&gt;
  class test_group : public group_base
  {
    const char* name_;

    typedef void (test_object&lt;Data&gt;::*testmethod)();
    typedef std::map&lt;int,testmethod&gt; 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 &lt;class T&gt;
    class safe_holder
    {
      T* p_;
      bool permit_throw_in_dtor;

      safe_holder(const safe_holder&amp;);
      safe_holder&amp; operator = (const safe_holder&amp;);

      public:
      safe_holder() : p_(0),permit_throw_in_dtor(false)
      { 
      }

      ~safe_holder()
      {
        release();
      }

      T* operator -&gt; () 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(&quot;destructor of test object raised an SEH exception&quot;);
          }
        }
        catch( const std::exception&amp; ex )
        {
          if( permit_throw_in_dtor ) 
          {
            std::string msg = &quot;destructor of test object raised exception: &quot;;
            msg += ex.what();
            throw warning(msg);
          }
        }
        catch( ... )
        {
          if( permit_throw_in_dtor )
          {
            throw warning(&quot;destructor of test object raised an exception&quot;);
          }
        }
      }

      /**
       * 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&lt;Data&gt; 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&lt;object,test_group,MaxTestsInGroup&gt;::reg(*this);
    };

    /**
     * This constructor is used in self-test run only.
     */
    test_group(const char* name,test_runner&amp; another_runner)
      : name_(name)
    {
      // register itself
      another_runner.register_group(name_,this); 

      // register all tests
      tests_registerer&lt;test_object&lt;Data&gt;,
                       test_group,MaxTestsInGroup&gt;::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&lt;object&gt; obj;
      while( current_test_ != tests_.end() )
      {
        try
        {
          return run_test_(current_test_++,obj);
        }
        catch( const no_such_test&amp; )
        {
          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()-&gt;first &lt; 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&lt;object&gt; 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&amp; ti,safe_holder&lt;object&gt;&amp; obj)
    {
      try
      {
        if( run_test_seh_(ti-&gt;second,obj) == false )
          throw seh(&quot;seh&quot;);
      }
      catch(const no_such_test&amp;)
      {
        throw;
      }
      catch(const warning&amp; ex)
      {
        // test ok, but destructor failed
        test_result tr(name_,ti-&gt;first,test_result::warn,ex);
        return tr;
      }
      catch(const failure&amp; ex)
      {
        // test failed because of ensure() or similar method
        test_result tr(name_,ti-&gt;first,test_result::fail,ex);
        return tr;
      }
      catch(const seh&amp; ex)
      {
        // test failed with sigsegv, divide by zero, etc
        test_result tr(name_,ti-&gt;first,test_result::term,ex);
        return tr;
      }
      catch(const bad_ctor&amp; ex)
      {
        // test failed because test ctor failed; stop the whole group
        test_result tr(name_,ti-&gt;first,test_result::ex_ctor,ex);
        return tr;
      }
      catch(const std::exception&amp; ex)
      {
        // test failed with std::exception
        test_result tr(name_,ti-&gt;first,test_result::ex,ex);
        return tr;
      }
      catch(...)
      {
        // test failed with unknown exception
        test_result tr(name_,ti-&gt;first,test_result::ex);
        return tr;
      }

      // test passed
      test_result tr(name_,ti-&gt;first,test_result::ok);
      return tr;
    }

    /**
     * Runs one under SEH if platform supports it.
     */
    bool run_test_seh_(testmethod tm,safe_holder&lt;object&gt;&amp; obj)
    {
#if defined(TUT_USE_SEH)
      __try
      {
#endif
        if( obj.get() == 0 ) 
	{
          reset_holder_(obj);
	}
        obj-&gt;called_method_was_a_dummy_test_ = false;

#if defined(TUT_USE_SEH)
        __try
        {
#endif
          (obj.get()-&gt;*tm)();
#if defined(TUT_USE_SEH)
        }
        __except(handle_seh_(::GetExceptionCode()))
        {
          // throw seh(&quot;SEH&quot;);
          return false;
        }
#endif

        if( obj-&gt;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()))
      {
        return false;
      }
#endif
      return true;
    }

    void reset_holder_(safe_holder&lt;object&gt;&amp; obj)
    {
      try 
      {
        obj.reset();
      }
      catch(const std::exception&amp; ex)
      {
        throw bad_ctor(ex.what());
      }
      catch(...)
      {
        throw bad_ctor(&quot;test constructor has generated an exception; group execution is terminated&quot;);
      }
    }
  };

#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
</code></pre>
<p>tut-reporter.h:</p>
<pre><code>#ifndef TUT_REPORTER
#define TUT_REPORTER

#include &lt;tut.h&gt;

/**
 * Template Unit Tests Framework for C++.
 * http://tut.dozen.ru
 *
 * @author dozen, tut@dozen.ru
 */
namespace
{
  std::ostream&amp; operator &lt;&lt; (std::ostream&amp; os,const tut::test_result&amp; tr)
  {
    switch(tr.result)
    {
      case tut::test_result::ok: 
      os &lt;&lt; '.'; 
      break;

      case tut::test_result::fail: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=F]&quot;;
      break;

      case tut::test_result::ex_ctor: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=C]&quot;;
      break;

      case tut::test_result::ex: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=X]&quot;;
      break;

      case tut::test_result::warn: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=W]&quot;;
      break;

      case tut::test_result::term: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=T]&quot;;
      break;
    }

    return os;
  }
}

namespace tut
{
  /**
   * Default TUT callback handler.
   */
  class reporter : public tut::callback
  {
    std::string current_group;
    typedef std::vector&lt;tut::test_result&gt; not_passed_list;
    not_passed_list not_passed;
    std::ostream&amp; os;

  public:
    int ok_count;
    int exceptions_count;
    int failures_count;
    int terminations_count;
    int warnings_count;

    reporter() : os(std::cout)
    {
      init();
    }

    reporter(std::ostream&amp; out) : os(out)
    {
      init();
    }

    void run_started()
    {
      init();
    }

    void test_completed(const tut::test_result&amp; tr)
    {
      if( tr.group != current_group )
      {
        os &lt;&lt; std::endl &lt;&lt; tr.group &lt;&lt; &quot;: &quot; &lt;&lt; std::flush;
        current_group = tr.group;
      }

      os &lt;&lt; tr &lt;&lt; std::flush;
      if( tr.result == tut::test_result::ok ) ok_count++;
      else if( tr.result == tut::test_result::ex ) exceptions_count++;
      else if( tr.result == tut::test_result::ex_ctor ) exceptions_count++;
      else if( tr.result == tut::test_result::fail ) failures_count++;
      else if( tr.result == tut::test_result::warn ) warnings_count++;
      else terminations_count++;

      if( tr.result != tut::test_result::ok )
      {
        not_passed.push_back(tr);
      }
    }

    void run_completed()
    {
      os &lt;&lt; std::endl;

      if( not_passed.size() &gt; 0 )
      {
        not_passed_list::const_iterator i = not_passed.begin();
        while( i != not_passed.end() )
        {
           tut::test_result tr = *i;

           os &lt;&lt; std::endl;

           os &lt;&lt; &quot;---&gt; &quot; &lt;&lt; &quot;group: &quot; &lt;&lt; tr.group &lt;&lt; &quot;, test: test&lt;&quot; &lt;&lt; tr.test &lt;&lt; &quot;&gt;&quot; &lt;&lt; std::endl;

           os &lt;&lt; &quot;     problem: &quot;;
           switch(tr.result)
           {
             case test_result::fail: 
               os &lt;&lt; &quot;assertion failed&quot; &lt;&lt; std::endl; 
               break;
             case test_result::ex: 
             case test_result::ex_ctor: 
               os &lt;&lt; &quot;unexpected exception&quot; &lt;&lt; std::endl;
               if( tr.exception_typeid != &quot;&quot; )
               { 
                 os &lt;&lt; &quot;     exception typeid: &quot; 
                    &lt;&lt; tr.exception_typeid &lt;&lt; std::endl;
               }
               break;
             case test_result::term: 
               os &lt;&lt; &quot;would be terminated&quot; &lt;&lt; std::endl; 
               break;
             case test_result::warn: 
               os &lt;&lt; &quot;test passed, but cleanup code (destructor) raised an exception&quot; &lt;&lt; std::endl; 
               break;
             default: break;
           }

           if( tr.message != &quot;&quot; )
           {
             if( tr.result == test_result::fail )
             {
               os &lt;&lt; &quot;     failed assertion: \&quot;&quot; &lt;&lt; tr.message &lt;&lt; &quot;\&quot;&quot; &lt;&lt; std::endl;
             }
             else
             {
               os &lt;&lt; &quot;     message: \&quot;&quot; &lt;&lt; tr.message &lt;&lt; &quot;\&quot;&quot; &lt;&lt; std::endl;
             }
           }

           ++i;
        }
      }

      os &lt;&lt; std::endl;

      os &lt;&lt; &quot;tests summary:&quot;;
      if( terminations_count &gt; 0 ) os &lt;&lt; &quot; terminations:&quot; &lt;&lt; terminations_count;
      if( exceptions_count &gt; 0 ) os &lt;&lt; &quot; exceptions:&quot; &lt;&lt; exceptions_count;
      if( failures_count &gt; 0 ) os &lt;&lt; &quot; failures:&quot; &lt;&lt; failures_count;
      if( warnings_count &gt; 0 ) os &lt;&lt; &quot; warnings:&quot; &lt;&lt; warnings_count;
      os &lt;&lt; &quot; ok:&quot; &lt;&lt; ok_count;
      os &lt;&lt; std::endl;
    }

    bool all_ok() const
    {
      return not_passed.size() == 0;
    }

    private:
    void init()
    {
      ok_count = 0;
      exceptions_count = 0;  
      failures_count = 0;
      terminations_count = 0;
      warnings_count = 0;

      not_passed.clear();
    }    
  };
};

#endif
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/160752/problem-mit-visual-studio-2005</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Jul 2026 18:48:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/160752.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 29 Sep 2006 04:58:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 04:58:35 GMT]]></title><description><![CDATA[<p>Ich hab im MS VS 2005 ein neues Projekt angelegt, dann Windows Konsolenanwendung, und dann leeres Projekt noch eingestellt.</p>
<p>So und da habe ich nun unten folgenden Code eingefuegt (main.ccp).<br />
Die beiden eingebundenen header files, tut.h und tut_reporter.h hab ich nat. auch hinzugefuegt.<br />
Soweit alles kein Problem, mach ich ja oefter.<br />
Was nun sehr komisch is, wenn ich kompilieren moecht, kommt ein error:<br />
atal error C1083: Datei (Include) kann nicht geöffnet werden: &quot;tut.h&quot;: No such file or directory</p>
<p>das gleich auch nochmal fuer die tut_report.h.</p>
<p>Ok dachte liegt daran, weil die beiden header mit &lt;&gt; Klammen eingebunden werden (Kompiler sicht nicht im aktuellen Pfad, sondern im Windows Source Verzeichnis), also geaendert in &quot;&quot;, aber das gleiche Problem.</p>
<p>Besten Dank,Georg</p>
<pre><code>#include &lt;tut.h&gt;
#include &lt;tut_reporter.h&gt;
#include &lt;iostream&gt;

namespace tut
{
  test_runner_singleton runner;
}

int main(int argc,const char* argv[])
{
  tut::reporter visi;

  if( argc &lt; 2 || argc &gt; 3 )
  {
    std::cout &lt;&lt; &quot;TUT example test application.&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;Usage: example [regression] | [list] | [ group] [test]&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       List all groups: example list&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run all tests: example regression&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run one group: example std::auto_ptr&quot; &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;       Run one test: example std::auto_ptr 3&quot; &lt;&lt; std::endl;;
  }

  std::cout &lt;&lt; &quot;\nFAILURE and EXCEPTION in these tests are FAKE ;)\n\n&quot;;

  tut::runner.get().set_callback(&amp;visi);

  try
  {
    if( argc == 1 || (argc == 2 &amp;&amp; std::string(argv[1]) == &quot;regression&quot;) )
    {
      tut::runner.get().run_tests();
    }
    else if( argc == 2 &amp;&amp; std::string(argv[1]) == &quot;list&quot; )
    {
      std::cout &lt;&lt; &quot;registered test groups:&quot; &lt;&lt; std::endl;
      tut::groupnames gl = tut::runner.get().list_groups();
      tut::groupnames::const_iterator i = gl.begin();
      tut::groupnames::const_iterator e = gl.end();
      while( i != e )
      {
        std::cout &lt;&lt; &quot;  &quot; &lt;&lt; *i &lt;&lt; std::endl;
        ++i;
      }
    }
    else if( argc == 2 &amp;&amp; std::string(argv[1]) != &quot;regression&quot; )
    {
      tut::runner.get().run_tests(argv[1]);
    }
    else if( argc == 3 )
    {
      tut::runner.get().run_test(argv[1],::atoi(argv[2]));
    }
  }
  catch( const std::exception&amp; ex )
  {
    std::cerr &lt;&lt; &quot;tut raised ex: &quot; &lt;&lt; ex.what() &lt;&lt; std::endl;
  }

  return 0;
}
</code></pre>
<p>tut.h:</p>
<pre><code>#ifndef TUT_H_GUARD
#define TUT_H_GUARD

#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;vector&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
#include &lt;stdexcept&gt;
#include &lt;typeinfo&gt;

#if defined(TUT_USE_SEH)
#include &lt;windows.h&gt;
#include &lt;winbase.h&gt;
#endif

/**
 * Template Unit Tests Framework for C++.
 * http://tut.dozen.ru
 *
 * @author dozen, tut@dozen.ru
 */
namespace tut
{
  /**
   * Exception to be throwed when attempted to execute 
   * missed test by number.
   */
  struct no_such_test : public std::logic_error
  {
    no_such_test() : std::logic_error(&quot;no such test&quot;){};
  };

  /**
   * No such test and passed test number is higher than
   * any test number in current group. Used in one-by-one
   * test running when upper bound is not known.
   */
  struct beyond_last_test : public no_such_test
  {
    beyond_last_test(){};
  };

  /**
   * Group not found exception.
   */
  struct no_such_group : public std::logic_error
  {
    no_such_group(const std::string&amp; grp) : 
      std::logic_error(grp){};
  };

  /**
   * Internal exception to be throwed when 
   * no more tests left in group or journal.
   */
  struct no_more_tests
  {
    no_more_tests(){};
  };

  /**
   * Internal exception to be throwed when 
   * test constructor has failed.
   */
  struct bad_ctor : public std::logic_error
  {
    bad_ctor(const std::string&amp; msg) : 
      std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when ensure() fails or fail() called.
   */
  class failure : public std::logic_error
  {
    public:
      failure(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when test desctructor throwed an exception.
   */
  class warning : public std::logic_error
  {
    public:
      warning(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Exception to be throwed when test issued SEH (Win32)
   */
  class seh : public std::logic_error
  {
    public:
      seh(const std::string&amp; msg) : std::logic_error(msg){};
  };

  /**
   * Return type of runned test/test group.
   *
   * For test: contains result of test and, possible, message
   * for failure or exception.
   */
  struct test_result
  {
    /**
     * Test group name.
     */
    std::string group;

    /**
     * Test number in group.
     */
    int test;

    /**
     * ok - test finished successfully
     * fail - test failed with ensure() or fail() methods
     * ex - test throwed an exceptions
     * warn - test finished successfully, but test destructor throwed
     * term - test forced test application to terminate abnormally
     */
    typedef enum { ok, fail, ex, warn, term, ex_ctor } result_type;
    result_type result;

    /**
     * Exception message for failed test.
     */
    std::string message;
    std::string exception_typeid;

    /**
     * Default constructor.
     */
    test_result()
      : test(0),result(ok)
    {
    }

    /**
     * Constructor.
     */
    test_result( const std::string&amp; grp,int pos,result_type res)
      : group(grp),test(pos),result(res)
    {
    }

    /**
     * Constructor with exception.
     */
    test_result( const std::string&amp; grp,int pos,
                 result_type res,
                 const std::exception&amp; ex)
      : group(grp),test(pos),result(res),
        message(ex.what()),exception_typeid(typeid(ex).name())
    {
    }
  };

  /**
   * Interface.
   * Test group operations.
   */
  struct group_base
  {
    virtual ~group_base(){};

    // execute tests iteratively
    virtual void rewind() = 0;
    virtual test_result run_next() = 0;

    // execute one test
    virtual test_result run_test(int n) = 0;
  };

  /**
   * Test runner callback interface.
   * Can be implemented by caller to update
   * tests results in real-time. User can implement 
   * any of callback methods, and leave unused 
   * in default implementation.
   */
  struct callback
  {
    /**
     * Virtual destructor is a must for subclassed types.
     */
    virtual ~callback(){};

    /**
     * Called when new test run started.
     */
    virtual void run_started(){};

    /**
     * Called when a group started
     * @param name Name of the group
     */
    virtual void group_started(const std::string&amp; /*name*/){};

    /**
     * Called when a test finished.
     * @param tr Test results.
     */
    virtual void test_completed(const test_result&amp; /*tr*/){};

    /**
     * Called when a group is completed
     * @param name Name of the group
     */
    virtual void group_completed(const std::string&amp; /*name*/){};

    /**
     * Called when all tests in run completed.
     */
    virtual void run_completed(){};
  };

  /**
   * Typedef for runner::list_groups()
   */
  typedef std::vector&lt;std::string&gt; groupnames;

  /**
   * Test runner.
   */
  class test_runner
  {
    protected:
      typedef std::map&lt;std::string,group_base*&gt; groups;
      typedef groups::iterator iterator;
      typedef groups::const_iterator const_iterator;
      groups groups_;

      callback  default_callback_;
      callback* callback_;

    public:
    /**
     * Constructor
     */
    test_runner() : callback_(&amp;default_callback_)
    {
    }

    /**
     * Stores another group for getting by name.
     */
    void register_group(const std::string&amp; name,group_base* gr)
    {
      if( gr == 0 )
      {
        throw std::invalid_argument(&quot;group shall be non-null&quot;);
      }

      groups::iterator found = groups_.find(name);
      if( found != groups_.end() )
      {
        std::string msg(&quot;attempt to add already existent group &quot;+name);
        // this exception terminates application so we use cerr also
        std::cerr &lt;&lt; msg &lt;&lt; std::endl;
        throw std::logic_error(msg);
      }

      groups_[name] = gr;
    }

    /**
     * Stores callback object.
     */
    void set_callback(callback* cb)
    {
      callback_ = cb==0? &amp;default_callback_:cb;
    }

    /**
     * Returns callback object.
     */
    callback&amp; get_callback() const
    {
      return *callback_;
    }

    /**
     * Returns list of known test groups.
     */
    const groupnames list_groups() const
    {
      groupnames ret;
      const_iterator i = groups_.begin();
      const_iterator e = groups_.end();
      while( i != e )
      {
        ret.push_back(i-&gt;first);
        ++i;
      }
      return ret;
    }

    /**
     * Runs all tests in all groups.
     * @param callback Callback object if exists; null otherwise
     */
    void run_tests() const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.begin();
      const_iterator e = groups_.end();
      while( i != e )
      {
        callback_-&gt;group_started(i-&gt;first);
        try
        {
          run_all_tests_in_group_(i);
        }
        catch( const no_more_tests&amp; )
        {
          callback_-&gt;group_completed(i-&gt;first);
        }

        ++i;
      }

      callback_-&gt;run_completed();
    }

    /**
     * Runs all tests in specified group.
     */
    void run_tests(const std::string&amp; group_name) const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.find(group_name);
      if( i == groups_.end() )
      {
        callback_-&gt;run_completed();
        throw no_such_group(group_name);
      }

      callback_-&gt;group_started(group_name);
      try
      {
        run_all_tests_in_group_(i);
      }
      catch( const no_more_tests&amp; )
      {
        // ok
      }

      callback_-&gt;group_completed(group_name);
      callback_-&gt;run_completed();
    }

    /**
     * Runs one test in specified group.
     */
    test_result run_test(const std::string&amp; group_name,int n) const
    {
      callback_-&gt;run_started();

      const_iterator i = groups_.find(group_name);
      if( i == groups_.end() )
      {
        callback_-&gt;run_completed();
        throw no_such_group(group_name);
      }

      callback_-&gt;group_started(group_name);
      try
      {
        test_result tr = i-&gt;second-&gt;run_test(n);
        callback_-&gt;test_completed(tr);
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        return tr;
      }
      catch( const beyond_last_test&amp; )
      {
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        throw;
      }      
      catch( const no_such_test&amp; )
      {
        callback_-&gt;group_completed(group_name);
        callback_-&gt;run_completed();
        throw;
      }
    }

    private:
    void run_all_tests_in_group_(const_iterator i) const
    {
      i-&gt;second-&gt;rewind();
      for( ;; )
      {
        test_result tr = i-&gt;second-&gt;run_next();
        callback_-&gt;test_completed(tr);

	if( tr.result == test_result::ex_ctor )
	{
          throw no_more_tests();
        }
      }
    }
  };

  /**
   * Singleton for test_runner implementation.
   * Instance with name runner_singleton shall be implemented
   * by user.
   */
  class test_runner_singleton
  {
    public:
      static test_runner&amp; get()
      {
        static test_runner tr;
        return tr;
      }
  };
  extern test_runner_singleton runner;

  /**
   * Test object. Contains data test run upon and default test method 
   * implementation. Inherited from Data to allow tests to  
   * access test data as members.
   */
  template &lt;class Data&gt;
  class test_object : public Data
  {
    public:
    /**
     * Default constructor
     */
    test_object(){};

    /**
     * The flag is set to true by default (dummy) test.
     * Used to detect usused test numbers and avoid unnecessary
     * test object creation which may be time-consuming depending
     * on operations described in Data::Data() and Data::~Data().
     * TODO: replace with throwing special exception from default test.
     */
    bool called_method_was_a_dummy_test_;

    /**
     * Default do-nothing test.
     */
    template &lt;int n&gt;
    void test()
    {
      called_method_was_a_dummy_test_ = true;
    }
  };

  namespace 
  {
    /**
     * Tests provided condition.
     * Throws if false.
     */
    void ensure(bool cond)
    {
       if( !cond ) throw failure(&quot;&quot;);
    }

    /**
     * Tests provided condition.
     * Throws if false.
     */
    template&lt;typename T&gt;
    void ensure(const T 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 &lt;&lt; defined somewhere, or
     * client code will not compile at all!
     */
    template &lt;class T,class Q&gt;
    void ensure_equals(const char* msg,const Q&amp; actual,const T&amp; expected)
    {
      if( expected != actual )
      {
        std::stringstream ss;
        ss &lt;&lt; (msg?msg:&quot;&quot;) &lt;&lt; (msg?&quot;: &quot;:&quot;&quot;) &lt;&lt; &quot;expected &quot; &lt;&lt; expected &lt;&lt; &quot; actual &quot; &lt;&lt; actual;
        throw failure(ss.str().c_str());
      }
    }

    template &lt;class T,class Q&gt;
    void ensure_equals(const Q&amp; actual,const T&amp; expected)
    {
      ensure_equals&lt;&gt;(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 &lt;&lt; defined somewhere, or
     * client code will not compile at all! Also, T shall have
     * operators + and -, and be comparable.
     */
    template &lt;class T&gt;
    void ensure_distance(const char* msg,const T&amp; actual,const T&amp; expected,const T&amp; distance)
    {
      if( expected-distance &gt;= actual || expected+distance &lt;= actual )
      {
        std::stringstream ss;
        ss &lt;&lt; (msg?msg:&quot;&quot;) &lt;&lt; (msg?&quot;: &quot;:&quot;&quot;) &lt;&lt; &quot;expected [&quot; &lt;&lt; expected-distance &lt;&lt; &quot;;&quot; 
           &lt;&lt; expected+distance &lt;&lt; &quot;] actual &quot; &lt;&lt; actual;
        throw failure(ss.str().c_str());
      }
    }

    template &lt;class T&gt;
    void ensure_distance(const T&amp; actual,const T&amp; expected,const T&amp; distance)
    {
      ensure_distance&lt;&gt;(0,actual,expected,distance);
    }

    /**
     * Unconditionally fails with message.
     */
    void fail(const char* msg=&quot;&quot;)
    {
      throw failure(msg);
    }
  }

  /**
   * Walks through test tree and stores address of each
   * test method in group. Instantiation stops at 0.
   */
  template &lt;class Test,class Group,int n&gt;
  struct tests_registerer
  {
    static void reg(Group&amp; group)
    {
      group.reg(n,&amp;Test::template test&lt;n&gt;);
      tests_registerer&lt;Test,Group,n-1&gt;::reg(group);
    }
  };

  template&lt;class Test,class Group&gt;
  struct tests_registerer&lt;Test,Group,0&gt;
  {
    static void reg(Group&amp;){};
  };

  /**
   * Test group; used to recreate test object instance for
   * each new test since we have to have reinitialized 
   * Data base class.
   */
  template &lt;class Data,int MaxTestsInGroup = 50&gt;
  class test_group : public group_base
  {
    const char* name_;

    typedef void (test_object&lt;Data&gt;::*testmethod)();
    typedef std::map&lt;int,testmethod&gt; 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 &lt;class T&gt;
    class safe_holder
    {
      T* p_;
      bool permit_throw_in_dtor;

      safe_holder(const safe_holder&amp;);
      safe_holder&amp; operator = (const safe_holder&amp;);

      public:
      safe_holder() : p_(0),permit_throw_in_dtor(false)
      { 
      }

      ~safe_holder()
      {
        release();
      }

      T* operator -&gt; () 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(&quot;destructor of test object raised an SEH exception&quot;);
          }
        }
        catch( const std::exception&amp; ex )
        {
          if( permit_throw_in_dtor ) 
          {
            std::string msg = &quot;destructor of test object raised exception: &quot;;
            msg += ex.what();
            throw warning(msg);
          }
        }
        catch( ... )
        {
          if( permit_throw_in_dtor )
          {
            throw warning(&quot;destructor of test object raised an exception&quot;);
          }
        }
      }

      /**
       * 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&lt;Data&gt; 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&lt;object,test_group,MaxTestsInGroup&gt;::reg(*this);
    };

    /**
     * This constructor is used in self-test run only.
     */
    test_group(const char* name,test_runner&amp; another_runner)
      : name_(name)
    {
      // register itself
      another_runner.register_group(name_,this); 

      // register all tests
      tests_registerer&lt;test_object&lt;Data&gt;,
                       test_group,MaxTestsInGroup&gt;::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&lt;object&gt; obj;
      while( current_test_ != tests_.end() )
      {
        try
        {
          return run_test_(current_test_++,obj);
        }
        catch( const no_such_test&amp; )
        {
          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()-&gt;first &lt; 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&lt;object&gt; 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&amp; ti,safe_holder&lt;object&gt;&amp; obj)
    {
      try
      {
        if( run_test_seh_(ti-&gt;second,obj) == false )
          throw seh(&quot;seh&quot;);
      }
      catch(const no_such_test&amp;)
      {
        throw;
      }
      catch(const warning&amp; ex)
      {
        // test ok, but destructor failed
        test_result tr(name_,ti-&gt;first,test_result::warn,ex);
        return tr;
      }
      catch(const failure&amp; ex)
      {
        // test failed because of ensure() or similar method
        test_result tr(name_,ti-&gt;first,test_result::fail,ex);
        return tr;
      }
      catch(const seh&amp; ex)
      {
        // test failed with sigsegv, divide by zero, etc
        test_result tr(name_,ti-&gt;first,test_result::term,ex);
        return tr;
      }
      catch(const bad_ctor&amp; ex)
      {
        // test failed because test ctor failed; stop the whole group
        test_result tr(name_,ti-&gt;first,test_result::ex_ctor,ex);
        return tr;
      }
      catch(const std::exception&amp; ex)
      {
        // test failed with std::exception
        test_result tr(name_,ti-&gt;first,test_result::ex,ex);
        return tr;
      }
      catch(...)
      {
        // test failed with unknown exception
        test_result tr(name_,ti-&gt;first,test_result::ex);
        return tr;
      }

      // test passed
      test_result tr(name_,ti-&gt;first,test_result::ok);
      return tr;
    }

    /**
     * Runs one under SEH if platform supports it.
     */
    bool run_test_seh_(testmethod tm,safe_holder&lt;object&gt;&amp; obj)
    {
#if defined(TUT_USE_SEH)
      __try
      {
#endif
        if( obj.get() == 0 ) 
	{
          reset_holder_(obj);
	}
        obj-&gt;called_method_was_a_dummy_test_ = false;

#if defined(TUT_USE_SEH)
        __try
        {
#endif
          (obj.get()-&gt;*tm)();
#if defined(TUT_USE_SEH)
        }
        __except(handle_seh_(::GetExceptionCode()))
        {
          // throw seh(&quot;SEH&quot;);
          return false;
        }
#endif

        if( obj-&gt;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()))
      {
        return false;
      }
#endif
      return true;
    }

    void reset_holder_(safe_holder&lt;object&gt;&amp; obj)
    {
      try 
      {
        obj.reset();
      }
      catch(const std::exception&amp; ex)
      {
        throw bad_ctor(ex.what());
      }
      catch(...)
      {
        throw bad_ctor(&quot;test constructor has generated an exception; group execution is terminated&quot;);
      }
    }
  };

#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
</code></pre>
<p>tut-reporter.h:</p>
<pre><code>#ifndef TUT_REPORTER
#define TUT_REPORTER

#include &lt;tut.h&gt;

/**
 * Template Unit Tests Framework for C++.
 * http://tut.dozen.ru
 *
 * @author dozen, tut@dozen.ru
 */
namespace
{
  std::ostream&amp; operator &lt;&lt; (std::ostream&amp; os,const tut::test_result&amp; tr)
  {
    switch(tr.result)
    {
      case tut::test_result::ok: 
      os &lt;&lt; '.'; 
      break;

      case tut::test_result::fail: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=F]&quot;;
      break;

      case tut::test_result::ex_ctor: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=C]&quot;;
      break;

      case tut::test_result::ex: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=X]&quot;;
      break;

      case tut::test_result::warn: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=W]&quot;;
      break;

      case tut::test_result::term: 
      os &lt;&lt; '[' &lt;&lt; tr.test &lt;&lt; &quot;=T]&quot;;
      break;
    }

    return os;
  }
}

namespace tut
{
  /**
   * Default TUT callback handler.
   */
  class reporter : public tut::callback
  {
    std::string current_group;
    typedef std::vector&lt;tut::test_result&gt; not_passed_list;
    not_passed_list not_passed;
    std::ostream&amp; os;

  public:
    int ok_count;
    int exceptions_count;
    int failures_count;
    int terminations_count;
    int warnings_count;

    reporter() : os(std::cout)
    {
      init();
    }

    reporter(std::ostream&amp; out) : os(out)
    {
      init();
    }

    void run_started()
    {
      init();
    }

    void test_completed(const tut::test_result&amp; tr)
    {
      if( tr.group != current_group )
      {
        os &lt;&lt; std::endl &lt;&lt; tr.group &lt;&lt; &quot;: &quot; &lt;&lt; std::flush;
        current_group = tr.group;
      }

      os &lt;&lt; tr &lt;&lt; std::flush;
      if( tr.result == tut::test_result::ok ) ok_count++;
      else if( tr.result == tut::test_result::ex ) exceptions_count++;
      else if( tr.result == tut::test_result::ex_ctor ) exceptions_count++;
      else if( tr.result == tut::test_result::fail ) failures_count++;
      else if( tr.result == tut::test_result::warn ) warnings_count++;
      else terminations_count++;

      if( tr.result != tut::test_result::ok )
      {
        not_passed.push_back(tr);
      }
    }

    void run_completed()
    {
      os &lt;&lt; std::endl;

      if( not_passed.size() &gt; 0 )
      {
        not_passed_list::const_iterator i = not_passed.begin();
        while( i != not_passed.end() )
        {
           tut::test_result tr = *i;

           os &lt;&lt; std::endl;

           os &lt;&lt; &quot;---&gt; &quot; &lt;&lt; &quot;group: &quot; &lt;&lt; tr.group &lt;&lt; &quot;, test: test&lt;&quot; &lt;&lt; tr.test &lt;&lt; &quot;&gt;&quot; &lt;&lt; std::endl;

           os &lt;&lt; &quot;     problem: &quot;;
           switch(tr.result)
           {
             case test_result::fail: 
               os &lt;&lt; &quot;assertion failed&quot; &lt;&lt; std::endl; 
               break;
             case test_result::ex: 
             case test_result::ex_ctor: 
               os &lt;&lt; &quot;unexpected exception&quot; &lt;&lt; std::endl;
               if( tr.exception_typeid != &quot;&quot; )
               { 
                 os &lt;&lt; &quot;     exception typeid: &quot; 
                    &lt;&lt; tr.exception_typeid &lt;&lt; std::endl;
               }
               break;
             case test_result::term: 
               os &lt;&lt; &quot;would be terminated&quot; &lt;&lt; std::endl; 
               break;
             case test_result::warn: 
               os &lt;&lt; &quot;test passed, but cleanup code (destructor) raised an exception&quot; &lt;&lt; std::endl; 
               break;
             default: break;
           }

           if( tr.message != &quot;&quot; )
           {
             if( tr.result == test_result::fail )
             {
               os &lt;&lt; &quot;     failed assertion: \&quot;&quot; &lt;&lt; tr.message &lt;&lt; &quot;\&quot;&quot; &lt;&lt; std::endl;
             }
             else
             {
               os &lt;&lt; &quot;     message: \&quot;&quot; &lt;&lt; tr.message &lt;&lt; &quot;\&quot;&quot; &lt;&lt; std::endl;
             }
           }

           ++i;
        }
      }

      os &lt;&lt; std::endl;

      os &lt;&lt; &quot;tests summary:&quot;;
      if( terminations_count &gt; 0 ) os &lt;&lt; &quot; terminations:&quot; &lt;&lt; terminations_count;
      if( exceptions_count &gt; 0 ) os &lt;&lt; &quot; exceptions:&quot; &lt;&lt; exceptions_count;
      if( failures_count &gt; 0 ) os &lt;&lt; &quot; failures:&quot; &lt;&lt; failures_count;
      if( warnings_count &gt; 0 ) os &lt;&lt; &quot; warnings:&quot; &lt;&lt; warnings_count;
      os &lt;&lt; &quot; ok:&quot; &lt;&lt; ok_count;
      os &lt;&lt; std::endl;
    }

    bool all_ok() const
    {
      return not_passed.size() == 0;
    }

    private:
    void init()
    {
      ok_count = 0;
      exceptions_count = 0;  
      failures_count = 0;
      terminations_count = 0;
      warnings_count = 0;

      not_passed.clear();
    }    
  };
};

#endif
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1146260</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146260</guid><dc:creator><![CDATA[Georg Gh]]></dc:creator><pubDate>Fri, 29 Sep 2006 04:58:35 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 05:47:13 GMT]]></title><description><![CDATA[<p>Und in welchem Verzeichnis liegen die &quot;tut.h&quot; ????</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1146276</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146276</guid><dc:creator><![CDATA[Jochen Kalmbach]]></dc:creator><pubDate>Fri, 29 Sep 2006 05:47:13 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 08:13:49 GMT]]></title><description><![CDATA[<p>Ich vermute ganz stark im falschen...</p>
<pre><code class="language-cpp">#include &lt;tut.h&gt;
</code></pre>
<p>Is schon ziemlich verdächtig...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1146356</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146356</guid><dc:creator><![CDATA[Mathias]]></dc:creator><pubDate>Fri, 29 Sep 2006 08:13:49 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 11:35:44 GMT]]></title><description><![CDATA[<p>also ich hab die beiden Header ja im Visual Studio dem Projekt hinzugefuegt, d.h er muesste sie eigentlich finden.<br />
Hab sie aber sicherheitshalber auch noch in das Projektverzeichnis manuell kopiert.</p>
<p>Was meinst Du denn mit falschen C/C++ Code:</p>
<pre><code>#include &lt;tut.h&gt;
</code></pre>
<p>das hab ich schon versucht!</p>
<pre><code>#include &quot;tut.h&quot;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1146494</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146494</guid><dc:creator><![CDATA[Georg Gh]]></dc:creator><pubDate>Fri, 29 Sep 2006 11:35:44 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 12:25:02 GMT]]></title><description><![CDATA[<p>liegt die tut.h nu bei den anderen cpp und h dateien vom project ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1146539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146539</guid><dc:creator><![CDATA[EXDW]]></dc:creator><pubDate>Fri, 29 Sep 2006 12:25:02 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Visual Studio 2005 on Fri, 29 Sep 2006 14:05:02 GMT]]></title><description><![CDATA[<p>Ok funktioniert jetzt. (falsches Verzeichnis).</p>
<p>sagt mal eine Frage noch, bei zB folgendem Code, was bedeuted denn factory::object object? (Also jetzt ganz allgemein gehts mir um das ::object Konstrukt).</p>
<p>Also ::object ist doch bestimmt ein spezieller Zugriff auf eine Klasse?</p>
<pre><code>namespace tut
{
  // Data used by each test
  struct vector_basic
  {   
    std::vector&lt;int&gt; v;
  };

  // Test group registration
  typedef test_group&lt;vector_basic&gt; factory;
  typedef factory::object object;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1146601</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1146601</guid><dc:creator><![CDATA[Georg Gh]]></dc:creator><pubDate>Fri, 29 Sep 2006 14:05:02 GMT</pubDate></item></channel></rss>