OSDN Git Service

pointer_facade のテストコードを追加
authorSubaruG <subaru_g@users.sourceforge.jp>
Thu, 28 Jan 2010 19:43:42 +0000 (04:43 +0900)
committerSubaruG <subaru_g@users.sourceforge.jp>
Thu, 28 Jan 2010 19:43:42 +0000 (04:43 +0900)
tests/pointer_facade.cc [new file with mode: 0644]

diff --git a/tests/pointer_facade.cc b/tests/pointer_facade.cc
new file mode 100644 (file)
index 0000000..09e210b
--- /dev/null
@@ -0,0 +1,226 @@
+// ヘッダのインクルード
+#include "../gintenlib/pointer_facade.hpp"
+
+// boost の単体テストフレームワーク
+#include <boost/test/minimal.hpp>
+
+// まず普通のクラスとして pointer_facade.hpp 中の例文
+struct trivial_ptr_category {}; // カテゴリクラスはタグなので適当に
+
+// 本体 
+template<typename T>
+struct trivial_ptr
+  : gintenlib::pointer_facade< trivial_ptr<T>, T, trivial_ptr_category > // こう使う
+{
+  trivial_ptr() : p(0) {}
+  explicit trivial_ptr( T* ptr ) : p( ptr ) {}
+  
+  template<typename U>
+  trivial_ptr( const trivial_ptr<U>& src ) : p( src.get() ) {}
+  
+  // 解放処理とか行わない
+  // ~trivial_ptr() throw () {}
+  
+  // get() さえあればOK
+  T* get() const { return p; }
+  
+  // reset とか swap もあると良いけど、基本はこれで終了!
+  
+ private:
+  T* p;
+  
+};
+
+// 基本的なチェック
+template<typename Pointer>
+void basic_test( const Pointer& pt )
+{
+  typename Pointer::pointer p_ = pt.get();
+  
+  // 基本動作
+  BOOST_CHECK( get_pointer(pt) == p_ );
+  if( pt )
+  {
+    BOOST_CHECK( &(*pt) == p_ );
+    BOOST_CHECK( pt.operator->() == p_ );
+  }
+  
+  // operator!
+  BOOST_CHECK( !pt == !p_ );
+  // operator unspecified bool
+  BOOST_CHECK( static_cast<bool>(pt) == static_cast<bool>(p_) );
+  
+  // 相互比較は別の場所で
+}
+
+// 関連性チェック
+template<typename P1, typename P2>
+void comparison_test( const P1& p1, const P2& p2 )
+{
+  BOOST_CHECK( ( p1 == p2 ) == ( p1.get() == p2.get() ) );
+  BOOST_CHECK( ( p1 != p2 ) == ( p1.get() != p2.get() ) );
+  BOOST_CHECK( ( p1 == p2 ) == !( p1 != p2 ) );
+  
+  if( p1 == p2 )
+  {
+    BOOST_CHECK( !(p1 < p2) && !(p2 < p1) );
+  }
+  else
+  {
+    BOOST_CHECK( p1 < p2 || p2 < p1 );
+    BOOST_CHECK( !( p1 < p2 && p2 < p1 ) );
+  }
+}
+
+void test1()
+{
+  trivial_ptr<int> p0, p1( new int() );
+  
+  // 基本的なチェック
+  basic_test( p0 );
+  basic_test( p1 );
+  
+  // 相互比較
+  {
+    // まず p0 に関して
+    BOOST_CHECK( &p0 == &p0 );
+    comparison_test( p0, p0 );  // 同一オブジェクト
+    
+    trivial_ptr<int> p0_ = p0;
+    BOOST_CHECK( p0 == p0_ );
+    BOOST_CHECK( &p0 != &p0_ );
+    comparison_test( p0, p0_ ); // 同じアドレスを持つ異なるオブジェクト
+    
+    BOOST_CHECK( p0 != p1 );
+    comparison_test( p0, p1 );  // 異なるアドレスを持つオブジェクト
+    
+    // 違う型に対して
+    trivial_ptr<const int> p2 = p0;
+    BOOST_CHECK( p0 == p2 );
+    comparison_test( p0, p2 );  // 型は違うが同じアドレスをもつオブジェクト
+    
+    trivial_ptr<const int> p3( new int() );
+    BOOST_CHECK( p0 != p3 );
+    comparison_test( p0, p3 );  // 異なるアドレスを持つ異なる型のオブジェクト
+    
+    delete p3.get();
+  }
+  
+  {
+    // 次に p1 に関して
+    BOOST_CHECK( &p1 == &p1 );
+    comparison_test( p1, p1 );  // 同一オブジェクト
+    
+    trivial_ptr<int> p1_ = p1;
+    BOOST_CHECK( p1 == p1_ );
+    BOOST_CHECK( &p1 != &p1_ );
+    comparison_test( p1, p1_ ); // 同じアドレスを持つ異なるオブジェクト
+    
+    BOOST_CHECK( p1 != p0 );
+    comparison_test( p1, p0 );  // 異なるアドレスを持つオブジェクト(NULL)
+    
+    p1_ = trivial_ptr<int>( new int() );  // 異なるアドレスを持つオブジェクト(非NULL)
+    BOOST_CHECK( p1 != p1_ );
+    comparison_test( p1, p1_ );  // 異なるアドレスを持つオブジェクト
+    delete p1_.get();
+    
+    // 違う型に対して
+    trivial_ptr<const int> p2 = p1;
+    BOOST_CHECK( p1 == p2 );
+    comparison_test( p1, p2 );  // 型は違うが同じアドレスをもつオブジェクト
+    
+    trivial_ptr<const int> p3;
+    BOOST_CHECK( p1 != p3 );
+    comparison_test( p1, p3 );  // 異なるアドレスを持つ異なる型のオブジェクト(NULL)
+    
+    trivial_ptr<const int> p4( new int() );
+    BOOST_CHECK( p1 != p3 );
+    comparison_test( p1, p3 );  // 異なるアドレスを持つ異なる型のオブジェクト(非NULL)
+    
+    delete p3.get();
+  }
+  
+  delete p1.get();
+}
+
+// 異なる型同士での比較を無効化した例
+template<typename T>
+struct trivial_ptr2
+  : gintenlib::pointer_facade<trivial_ptr2<T>, T>
+{
+  trivial_ptr2() : p(0) {}
+  explicit trivial_ptr2( T* ptr ) : p( ptr ) {}
+  
+  // get() から自動定義
+  T* get() const { return p; }
+  
+ private:
+  T* p;
+  
+};
+// テスト
+void test2()
+{
+  trivial_ptr2<int> p0, p1( new int() );
+  
+  // 基本的なチェック
+  basic_test( p0 );
+  basic_test( p1 );
+  
+  // 相互比較
+  {
+    // まず p0 に関して
+    BOOST_CHECK( &p0 == &p0 );
+    comparison_test( p0, p0 );  // 同一オブジェクト
+    
+    trivial_ptr2<int> p0_ = p0;
+    BOOST_CHECK( p0 == p0_ );
+    BOOST_CHECK( &p0 != &p0_ );
+    comparison_test( p0, p0_ ); // 同じアドレスを持つ異なるオブジェクト
+    
+    BOOST_CHECK( p0 != p1 );
+    comparison_test( p0, p1 );  // 異なるアドレスを持つオブジェクト
+    
+    // 違う型に対しての比較は無理
+    trivial_ptr<const int> p2;
+    // BOOST_CHECK( p0 == p2 );
+    // BOOST_CHECK( !( p0 != p2 ) );
+    // BOOST_CHECK( !(p1 < p2) && !(p2 < p1) );
+  }
+  
+  {
+    // 次に p1 に関して
+    BOOST_CHECK( &p1 == &p1 );
+    comparison_test( p1, p1 );  // 同一オブジェクト
+    
+    trivial_ptr2<int> p1_ = p1;
+    BOOST_CHECK( p1 == p1_ );
+    BOOST_CHECK( &p1 != &p1_ );
+    comparison_test( p1, p1_ ); // 同じアドレスを持つ異なるオブジェクト
+    
+    BOOST_CHECK( p1 != p0 );
+    comparison_test( p1, p0 );  // 異なるアドレスを持つオブジェクト(NULL)
+    
+    p1_ = trivial_ptr2<int>( new int() );  // 異なるアドレスを持つオブジェクト(非NULL)
+    BOOST_CHECK( p1 != p1_ );
+    comparison_test( p1, p1_ );  // 異なるアドレスを持つオブジェクト
+    delete p1_.get();
+    
+    // 違う型に対しての比較は無理
+    trivial_ptr<const int> p2;
+    // BOOST_CHECK( !(p1 == p2) );
+    // BOOST_CHECK( p1 != p2 );
+    // BOOST_CHECK( p1 < p2 || p2 < p1 );
+  }
+  
+  delete p1.get();
+}
+
+// テストメイン
+int test_main( int argc, char* argv[] )
+{
+  test1();
+  test2();
+  
+  return 0;
+}