--- /dev/null
+// ヘッダのインクルード
+#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;
+}