From: SubaruG Date: Thu, 28 Jan 2010 19:43:42 +0000 (+0900) Subject: pointer_facade のテストコードを追加 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=d2ba291ca83edfe1a376bffbcc0fc49299de1214;p=gintenlib%2Fgintenlib.git pointer_facade のテストコードを追加 --- diff --git a/tests/pointer_facade.cc b/tests/pointer_facade.cc new file mode 100644 index 0000000..09e210b --- /dev/null +++ b/tests/pointer_facade.cc @@ -0,0 +1,226 @@ +// ヘッダのインクルード +#include "../gintenlib/pointer_facade.hpp" + +// boost の単体テストフレームワーク +#include + +// まず普通のクラスとして pointer_facade.hpp 中の例文 +struct trivial_ptr_category {}; // カテゴリクラスはタグなので適当に + +// 本体 +template +struct trivial_ptr + : gintenlib::pointer_facade< trivial_ptr, T, trivial_ptr_category > // こう使う +{ + trivial_ptr() : p(0) {} + explicit trivial_ptr( T* ptr ) : p( ptr ) {} + + template + trivial_ptr( const trivial_ptr& src ) : p( src.get() ) {} + + // 解放処理とか行わない + // ~trivial_ptr() throw () {} + + // get() さえあればOK + T* get() const { return p; } + + // reset とか swap もあると良いけど、基本はこれで終了! + + private: + T* p; + +}; + +// 基本的なチェック +template +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(pt) == static_cast(p_) ); + + // 相互比較は別の場所で +} + +// 関連性チェック +template +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 p0, p1( new int() ); + + // 基本的なチェック + basic_test( p0 ); + basic_test( p1 ); + + // 相互比較 + { + // まず p0 に関して + BOOST_CHECK( &p0 == &p0 ); + comparison_test( p0, p0 ); // 同一オブジェクト + + trivial_ptr p0_ = p0; + BOOST_CHECK( p0 == p0_ ); + BOOST_CHECK( &p0 != &p0_ ); + comparison_test( p0, p0_ ); // 同じアドレスを持つ異なるオブジェクト + + BOOST_CHECK( p0 != p1 ); + comparison_test( p0, p1 ); // 異なるアドレスを持つオブジェクト + + // 違う型に対して + trivial_ptr p2 = p0; + BOOST_CHECK( p0 == p2 ); + comparison_test( p0, p2 ); // 型は違うが同じアドレスをもつオブジェクト + + trivial_ptr 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 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( new int() ); // 異なるアドレスを持つオブジェクト(非NULL) + BOOST_CHECK( p1 != p1_ ); + comparison_test( p1, p1_ ); // 異なるアドレスを持つオブジェクト + delete p1_.get(); + + // 違う型に対して + trivial_ptr p2 = p1; + BOOST_CHECK( p1 == p2 ); + comparison_test( p1, p2 ); // 型は違うが同じアドレスをもつオブジェクト + + trivial_ptr p3; + BOOST_CHECK( p1 != p3 ); + comparison_test( p1, p3 ); // 異なるアドレスを持つ異なる型のオブジェクト(NULL) + + trivial_ptr p4( new int() ); + BOOST_CHECK( p1 != p3 ); + comparison_test( p1, p3 ); // 異なるアドレスを持つ異なる型のオブジェクト(非NULL) + + delete p3.get(); + } + + delete p1.get(); +} + +// 異なる型同士での比較を無効化した例 +template +struct trivial_ptr2 + : gintenlib::pointer_facade, 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 p0, p1( new int() ); + + // 基本的なチェック + basic_test( p0 ); + basic_test( p1 ); + + // 相互比較 + { + // まず p0 に関して + BOOST_CHECK( &p0 == &p0 ); + comparison_test( p0, p0 ); // 同一オブジェクト + + trivial_ptr2 p0_ = p0; + BOOST_CHECK( p0 == p0_ ); + BOOST_CHECK( &p0 != &p0_ ); + comparison_test( p0, p0_ ); // 同じアドレスを持つ異なるオブジェクト + + BOOST_CHECK( p0 != p1 ); + comparison_test( p0, p1 ); // 異なるアドレスを持つオブジェクト + + // 違う型に対しての比較は無理 + trivial_ptr 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 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( new int() ); // 異なるアドレスを持つオブジェクト(非NULL) + BOOST_CHECK( p1 != p1_ ); + comparison_test( p1, p1_ ); // 異なるアドレスを持つオブジェクト + delete p1_.get(); + + // 違う型に対しての比較は無理 + trivial_ptr 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; +}