#include <boost/iterator/counting_iterator.hpp>
#include <boost/array.hpp>
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
-// ¥Æ¥¹¥ÈËÜÂÎ
+// テスト本体
int test_main( int argc, char* argv[] )
{
static const int n = 10;
int a[n];
boost::array<int, n> b;
- // a ¤ò¡¢boost::counting_iterator ¤ò»È¤¤ 0 ¡Á 9 ¤ÎÃͤǽé´ü²½
+ // a を、boost::counting_iterator を使い 0 〜 9 の値で初期化
gintenlib::assign( a, boost::counting_iterator<int>(0) );
- // ¥Á¥§¥Ã¥¯
+ // ã\83\81ã\82§ã\83\83ã\82¯
for( int i = 0; i < n; ++i )
{
BOOST_CHECK( a[i] == i );
}
- // b ¤òµÕ½ç¤Ë a ¤Ç½é´ü²½
+ // b を逆順に a で初期化
gintenlib::assign( b.rbegin(), b.rend(), &a[0] );
- // ¥Á¥§¥Ã¥¯
+ // ã\83\81ã\82§ã\83\83ã\82¯
for( int i = 0, j = n - 1; i < n; ++i, --j )
{
BOOST_CHECK( b[i] == a[j] );
-// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+// ヘッダのインクルード
#include "../gintenlib/bool_comparable.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
-// ¤Þ¤ºÉáÄ̤Υ¯¥é¥¹¤È¤·¤Æ bool_comparable.hpp Ãæ¤ÎÎãʸ
+// まず普通のクラスとして bool_comparable.hpp 中の例文
#include <boost/scoped_ptr.hpp>
template<typename T>
class my_optional
- : public gintenlib::bool_comparable< my_optional<T> > // ¤³¤Î¤è¤¦¤Ë»È¤¦
+ : public gintenlib::bool_comparable< my_optional<T> > // このように使う
{
- // ËÜÂÎÉôʬ¤Ï¤Ê¤ó¤éµ¤¤Ë¤»¤º½ñ¤¤¤Æ¤è¤¤
+ // 本体部分はなんら気にせず書いてよい
public:
typedef T value_type;
reference operator*() { return *p; }
const_reference operator*() const { return *p; }
- // operator!() ¤ò³Î¼Â¤Ë¼ÂÁõ¤¹¤ë¤³¤È¤ò˺¤ì¤Ê¤±¤ì¤Ð¡£
+ // operator!() を確実に実装することを忘れなければ。
bool operator!() const { return !p; }
- // ¤³¤ì¤Ë¤è¤ê¡¢boolÈæ³Ó¤â½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ë
+ // これにより、bool比較も出来るようになる
- // ¤Á¤Ê¤ß¤Ë operator!() ¤¸¤ã¤Ê¤¯¤Æ
+ // ちなみに operator!() じゃなくて
// bool boolean_test() const { return p.get(); }
- // ¤³¤ì¤Ç¤â¤¤¤¤¡Ê¤½¤Î¾ì¹ç¡¢operator! ¤Ï¼«Æ°ÄêµÁ¡Ë
+ // これでもいい(その場合、operator! は自動定義)
- // ¤½¤Î¤Û¤«¡¢¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤È¤«ÂåÆþ±é»»»Ò¤È¤«¤ÏÌÌÅݤÀ¤«¤é¾Êά
+ // そのほか、コピーコンストラクタとか代入演算子とかは面倒だから省略
private:
- // ÌÌÅݤʥݥ¤¥ó¥¿´ÉÍý¤È¤«¤·¤¿¤¯¤Ê¤¤¤Î¤Ç scoped_ptr ¤ò»È¤¦
+ // 面倒なポインタ管理とかしたくないので scoped_ptr を使う
boost::scoped_ptr<T> p;
};
-// ¥Æ¥¹¥È¥±¡¼¥¹
+// ã\83\86ã\82¹ã\83\88ã\82±ã\83¼ã\82¹
void my_optional_test()
{
my_optional<int> a, b(1), c(0);
- // ´ðËÜŪ¤Ê¥Á¥§¥Ã¥¯
+ // å\9fºæ\9c¬ç\9a\84ã\81ªã\83\81ã\82§ã\83\83ã\82¯
- // if ¤Î¾ò·ïÉô¤ËľÀܻȤ¦
+ // if の条件部に直接使う
if( a ) { BOOST_ERROR( "a is empty." ); }
if( b ); else { BOOST_ERROR( "b is not empty." ); }
- // ÅöÁ³¤À¤±¤É ! ±é»»»Ò¤â¥Æ¥¹¥È¤¹¤ë
+ // 当然だけど ! 演算子もテストする
if( !c ) { BOOST_ERROR( "c is not empty." ); }
- // || ¤ä &&
- // || ¤ä && ¤ÏľÀÜ¿½ÅÄêµÁ¤·¤Æ¤Ê¤¤¤Î¤Ç¡¢short circuit ¤Ë¤Ê¤ë¤Ï¤º
+ // || や &&
+ // || や && は直接多重定義してないので、short circuit になるはず
BOOST_CHECK( b || a );
BOOST_CHECK( b && c );
- // 0 ¤È¤ÎÈæ³Ó
+ // 0 との比較
BOOST_CHECK( a == 0 );
- BOOST_CHECK( 0 == a ); // µÕ¤â¥Æ¥¹¥È
+ BOOST_CHECK( 0 == a ); // 逆もテスト
BOOST_CHECK( b != 0 ); // !=
- BOOST_CHECK( 0 != c ); // != ¤ÎµÕ
+ BOOST_CHECK( 0 != c ); // != の逆
- // true, false ¤È¤ÎÈæ³Ó
- BOOST_CHECK( b == true ); // ¤³¤ì¤Ï£Ï£Ë
- BOOST_CHECK( false == a ); // £Ï£Ë
- BOOST_CHECK( c != false ); // £Ï£Ë
- BOOST_CHECK( true != a ); // £Ï£Ë
- // BOOST_CHECK( b == 1 ); // ¥³¥ì¤Ï¥À¥á
+ // true, false との比較
+ BOOST_CHECK( b == true ); // これはOK
+ BOOST_CHECK( false == a ); // OK
+ BOOST_CHECK( c != false ); // OK
+ BOOST_CHECK( true != a ); // OK
+ // BOOST_CHECK( b == 1 ); // コレはダメ
- // bool ¤Ø¤Î¥¥ã¥¹¥È
+ // bool へのキャスト
BOOST_CHECK( static_cast<bool>(a) != static_cast<bool>(b) );
- // ľÀÜÈæ³Ó¤Ï¥À¥á
+ // 直接比較はダメ
// BOOST_CHECK( a != b );
// if( b == c ){ BOOST_ERROR( "1 equals to 0 !?" ); }
}
-// ¼¡¡¢Èæ³Ó¤â½ÐÍè¤ë¥¯¥é¥¹
+// 次ã\80\81æ¯\94è¼\83ã\82\82å\87ºæ\9d¥ã\82\8bã\82¯ã\83©ã\82¹
#include <boost/operators.hpp>
#include <string>
using namespace std;
string value;
eq_cmp( string x = "" ) : value(x) {}
- // ¤³¤ì¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð£Ï£Ë
+ // これさえ実装すればOK
bool operator!() const { return value.empty(); }
// equal_to
return lhs.value == rhs.value;
}
- // ¥Æ¥¹¥È¥³¡¼¥É
+ // テストコード
static void test()
{
eq_cmp x, y("hoge");
- // ¤³¤ÎÊÕ¤ÏŬÅö¤Ëή¤¹
+ // この辺は適当に流す
BOOST_CHECK( !x );
BOOST_CHECK( y );
BOOST_CHECK( x == 0 );
BOOST_CHECK( y != 0 );
- // ÅöÁ³¥À¥á
+ // 当然ダメ
// BOOST_CHECK( x != 1 );
// BOOST_CHECK( y == 1 );
- // ¤³¤ì¤é¤ÏÈæ³Ó´Ø¿ô¤òÄêµÁ¤·¤Æ¤ë¤Î¤Ç£Ï£Ë
+ // これらは比較関数を定義してるのでOK
BOOST_CHECK( x == x );
BOOST_CHECK( x != y );
- // °ÅÌÛÊÑ´¹¤Ç¤³¤ì¤â£Ï£Ë
+ // 暗黙変換でこれもOK
BOOST_CHECK( x == string("") );
BOOST_CHECK( y != string("") );
- // µÕÊý¸þ¤Ç¤â´ðËܣϣË
+ // 逆方向でも基本OK
BOOST_CHECK( ( x == true ) == ( true == x ) );
BOOST_CHECK( ( x != true ) == ( true != x ) );
BOOST_CHECK( ( x == 0 ) == ( 0 == x ) );
BOOST_CHECK( string("hoge") != x );
BOOST_CHECK( string("hoge") == y );
- // µÕÊý¸þ¤Ç¤âÅöÁ³¥À¥á
+ // 逆方向でも当然ダメ
// BOOST_CHECK( 1 != x );
// BOOST_CHECK( 1 == y );
}
};
-// int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¾ì¹ç¡¢¤Á¤ç¤Ã¤ÈÆüì
+// int から暗黙変換できる場合、ちょっと特殊
struct convertible_from_int
: gintenlib::bool_comparable<convertible_from_int>,
private boost::equality_comparable<convertible_from_int>
{
int value;
- convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
+ convertible_from_int( int x = 0 ) : value(x) {} // int から暗黙変換できると・・・
bool operator!() const { return value == 0; }
- // operator== ¤Ë¤è¤ëÈæ³Ó¤¬½ÐÍè¤ë¾ì¹ç
+ // operator== による比較が出来る場合
friend bool operator==( const convertible_from_int& lhs, const convertible_from_int& rhs )
{
return lhs.value == rhs.value;
static void test()
{
convertible_from_int x, y = 2;
- BOOST_CHECK( !x ); // ¤³¤¦¤¤¤¦¤Î¤ÏÉáÄ̤˽ÐÍè¤ë¤¬
+ BOOST_CHECK( !x ); // こういうのは普通に出来るが
BOOST_CHECK( y );
BOOST_CHECK( x == false );
BOOST_CHECK( y == true );
- // BOOST_CHECK( x == 0 ); // ¥³¥ì¤¬¼Â¹Ô¤Ç¤¤Ê¤¤¡ÊÛ£Ëæ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡Ë
- // BOOST_CHECK( y != 0 ); // ÅöÁ³¤³¤ì¤â¥À¥á
+ // BOOST_CHECK( x == 0 ); // コレが実行できない(曖昧になってしまう)
+ // BOOST_CHECK( y != 0 ); // 当然これもダメ
- BOOST_CHECK( y == 2 ); // ¤Ç¤â¥³¥ì¤Ï£Ï£Ë
- BOOST_CHECK( x != 1 ); // ¥³¥ì¤â£Ï£Ë
+ BOOST_CHECK( y == 2 ); // でもコレはOK
+ BOOST_CHECK( x != 1 ); // コレもOK
}
};
-// ¤½¤Î¾ì¹ç¡¢int ¤È¤ÎÈæ³Ó¤òÊ̸ÄÄêµÁ¤·¤Æ¤ä¤ì¤Ð£Ï£Ë
+// その場合、int との比較を別個定義してやればOK
struct convertible_from_int2
: gintenlib::bool_comparable<convertible_from_int2>,
private boost::equality_comparable<convertible_from_int2>,
private boost::equality_comparable<convertible_from_int2, int>
{
int value;
- convertible_from_int2( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
+ convertible_from_int2( int x = 0 ) : value(x) {} // int から暗黙変換できると・・・
- // ¤³¤Ã¤½¤ê boolean_test ¤ò»È¤¦¡£Æä˰ÕÌ£¤Ï̵¤¤
+ // こっそり boolean_test を使う。特に意味は無い
bool operator!() const { return value == 0; }
- // Ä̾ï¤Î == Èæ³Ó¤Ë²Ã¤¨¤Æ
+ // 通常の == 比較に加えて
friend bool operator==( const convertible_from_int2& lhs, const convertible_from_int2& rhs )
{
return lhs.value == rhs.value;
}
- // int ¤È¤ÎÈæ³Ó¤òÌÀ¼¨Åª¤ËÄêµÁ¤µ¤¨¤¹¤ì¤Ð
+ // int との比較を明示的に定義さえすれば
friend bool operator==( const convertible_from_int2& lhs, int rhs )
{
return lhs.value == rhs;
{
convertible_from_int2 x, y = 2;
- BOOST_CHECK( x == 0 ); // ¥³¥ì¤â¼Â¹Ô¤Ç¤¤ë¡ª
+ BOOST_CHECK( x == 0 ); // コレも実行できる!
BOOST_CHECK( y != 0 );
- BOOST_CHECK( y == 2 ); // ÅöÁ³¥³¥ì¤â£Ï£Ë
+ BOOST_CHECK( y == 2 ); // 当然コレもOK
BOOST_CHECK( x != 1 );
- BOOST_CHECK( !x ); // ¤Á¤Ê¤ß¤Ë boolean_test() ¤¬¤¢¤ì¤Ð operator !() ¤âÄêµÁ¤µ¤ì¤ë
- // º£²ó¤Î¥Æ¥¹¥È¤Ë¤Ï¤¢¤Þ¤ê´Ø·¸¤Ê¤¤¤¬
+ BOOST_CHECK( !x ); // ちなみに boolean_test() があれば operator !() も定義される
+ // 今回のテストにはあまり関係ないが
BOOST_CHECK( y );
BOOST_CHECK( x == false );
BOOST_CHECK( y == true );
};
-// ¥Æ¥¹¥È¥á¥¤¥ó
+// テストメイン
int test_main( int argc, char* argv[] )
{
my_optional_test();
#include "../gintenlib/clonable_ptr.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
template<typename T>
{
typedef gintenlib::clonable_ptr<T> ptr_type;
- // ¥Ç¥Õ¥©¥ë¥È¹½ÃÛ
+ // デフォルト構築
{
ptr_type p1;
- // NULL ¤Ë¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë¤«¡©
+ // NULL にセットされているか?
BOOST_CHECK( p1.get() == 0 );
}
- // ¥³¥Ô¡¼
+ // ã\82³ã\83\94ã\83¼
{
- // ¥³¥Ô¡¼¤ËÀèΩ¤Ã¤Æ»²¾È¥«¥¦¥ó¥È¤òÄ´¤Ù¤ë
+ // コピーに先立って参照カウントを調べる
int count = p0.use_count();
- // ¥³¥Ô¡¼¤¹¤ë
+ // コピーする
ptr_type p1 = p0;
- // ¥¢¥É¥ì¥¹¤È»²¾È¥«¥¦¥ó¥È¤ÎξÌ̤ÇÅù¤·¤¤¤³¤È¤ò³Îǧ
+ // アドレスと参照カウントの両面で等しいことを確認
BOOST_CHECK( p0 == p1 );
BOOST_CHECK( p0.use_count() == p1.use_count() );
- // ¤Þ¤¿¡¢¥³¥Ô¡¼¤¬½ÐÍ褿ʬ¡¢»²¾È¥«¥¦¥ó¥È¤ÏÁý¤¨¤Æ¤¤¤ë¤Ï¤º
+ // また、コピーが出来た分、参照カウントは増えているはず
if( p0 )
{
BOOST_CHECK( p0.use_count() == count+1 );
}
else
{
- // NULL ¤Î¾ì¹ç¤Ï»²¾È¥«¥¦¥ó¥È¤Ï¥¼¥í¤Ë¤Ê¤ë
+ // NULL の場合は参照カウントはゼロになる
BOOST_CHECK( count == 0 );
BOOST_CHECK( p0.use_count() == 0 );
}
- // ¥ê¥»¥Ã¥È¤Î¥Æ¥¹¥È
+ // リセットのテスト
p1.reset();
BOOST_CHECK( p1 == 0 );
- // ¤³¤Î»þÅÀ¤Ç»²¾È¥«¥¦¥ó¥È¤Ï¸µ¤ËÌá¤ë¤Ï¤º
+ // この時点で参照カウントは元に戻るはず
BOOST_CHECK( p0.use_count() == count );
}
- // ËÜÂê¡£clone ¤Î¥Æ¥¹¥È
+ // 本題。clone のテスト
{
ptr_type p1;
p1 = p0.clone();
- // ¤Þ¤¿¡¢¥³¥Ô¡¼¤¬½ÐÍ褿ʬ¡¢»²¾È¥«¥¦¥ó¥È¤ÏÁý¤¨¤Æ¤¤¤ë¤Ï¤º
+ // また、コピーが出来た分、参照カウントは増えているはず
if( p0 )
{
BOOST_CHECK( p0.get() != p1.get() );
}
else
{
- // NULL ¤Î¾ì¹ç¤Ï p1 ¤â¥¼¥í¤Î¤Ï¤º
+ // NULL の場合は p1 もゼロのはず
BOOST_CHECK( !p1 );
}
- // À¸¥Ý¥¤¥ó¥¿¤Ç to_unique ¤Î³Îǧ
+ // 生ポインタで to_unique の確認
T* p_ = p1.get();
- // ¤³¤ì¤Þ¤Ç¤Î²áÄø¤Ç p1 ¤Ï null ¤« unique ¤Î¤Ï¤º
+ // これまでの過程で p1 は null か unique のはず
BOOST_CHECK( !p1 || p1.unique() );
- // unique ¤Î¤È¤¤Ï to_unique() ¤ò¸Æ¤ó¤Ç¤â²¿¤â¤·¤Ê¤¤¤Ï¤º
+ // unique のときは to_unique() を呼んでも何もしないはず
p1.to_unique();
BOOST_CHECK( p_ == p1.get() );
- // ¼¡¤Ë p1 ¤Ë¤Õ¤¿¤¿¤Ó p0 ¤ÎÃͤòÆþ¤ì¤ë
+ // 次に p1 にふたたび p0 の値を入れる
p1 = p0;
- // À¸¥Ý¥¤¥ó¥¿¤ÎÃͤò¹¹¿·
+ // 生ポインタの値を更新
p_ = p1.get();
- // ¤³¤ì¤Ë¤è¤ê¡¢NULL ¤Ç¤¢¤ë¤«¥æ¥Ë¡¼¥¯¤¸¤ã¤Ê¤¤¤«¤Î¾õÂ֤ˤʤä¿
+ // これにより、NULL であるかユニークじゃないかの状態になった
BOOST_CHECK( !p1 || !p1.unique() );
- // unique ¤ò¸Æ¤Ö¤È p0 ¤ÏÊѲ½¤»¤º p1 ¤¬ÊѲ½¤¹¤ë¤Ï¤º
+ // unique を呼ぶと p0 は変化せず p1 が変化するはず
p1.to_unique();
BOOST_CHECK( p_ == p0.get() );
BOOST_CHECK( !p1 || p_ != p1.get() );
}
- // ¤ª¤Þ¤±¤Ç to_shared
+ // おまけで to_shared
{
- // Àè¤Ë»²¾È¥«¥¦¥ó¥È¤òÄ´¤Ù¤ë
+ // 先に参照カウントを調べる
int count = p0.use_count();
boost::shared_ptr<T> p1 = to_shared( p0 );
BOOST_CHECK( p0.get() == p1.get() );
- // shared_ptr ¤¬¥ê¥»¥Ã¥È¤µ¤ì¤¿¾ì¹ç¡¢¤Á¤ã¤ó¤È»²¾È¥«¥¦¥ó¥È¤Ï¸º¤ë¡©
+ // shared_ptr がリセットされた場合、ちゃんと参照カウントは減る?
p1.reset();
BOOST_CHECK( p0.use_count() == count );
}
- // ¤ª¤ï¤ê
+ // おわり
}
int test_main( int argc, char* argv[] )
-// ¥Ø¥Ã¥À
+// ヘッダ
#include "../gintenlib/deep_ptr.hpp"
-// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
-// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
-// ½ÐÎÏ¡¢¸«¤Å¤é¤¤¤±¤É²¿¤¬µ¯¤³¤Ã¤Æ¤ë¤«¤Ïʬ¤«¤ë¤è¤Í¡©
+// 仮テストコードなので
+// boost.test はまだ使わない。
+// 出力、見づらいけど何が起こってるかは分かるよね?
#include <iostream>
using namespace std;
-// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+// デバッグ用マクロ
#define PRINT_AND_EXECUTE( expr ) \
cout << #expr << ";\n"; expr
cout << #expr << " -> " << (expr) << endl
-// ¥Æ¥¹¥È£±¡¢¤Á¤ã¤ó¤È»È¤¨¤ë¤«Ä´¤Ù¤ë
+// テスト1、ちゃんと使えるか調べる
-// »ý¤¿¤»¤ë¥¯¥é¥¹
+// æ\8c\81ã\81\9fã\81\9bã\82\8bã\82¯ã\83©ã\82¹
struct hoge
{
hoge()
void test_hoge()
{
- // ¥³¥ó¥¹¥È¥é¥¯¥¿¤Î¥Á¥§¥Ã¥¯
+ // ã\82³ã\83³ã\82¹ã\83\88ã\83©ã\82¯ã\82¿ã\81®ã\83\81ã\82§ã\83\83ã\82¯
gintenlib::deep_ptr<hoge> p1, p2( new hoge() );
gintenlib::deep_ptr<const hoge> p3 = p2;
- // ÂåÆþ¥Á¥§¥Ã¥¯
- // Ãæ¿È¤ò¥³¥Ô¡¼¤¹¤ë¤Î¤Ç const ¤«¤é¤ÎÂåÆþ¤â½ÐÍè¤ë
+ // 代å\85¥ã\83\81ã\82§ã\83\83ã\82¯
+ // 中身をコピーするので const からの代入も出来る
PRINT_AND_EXECUTE( p2 = p3 );
- // reset ¥Á¥§¥Ã¥¯
+ // reset ã\83\81ã\82§ã\83\83ã\82¯
PRINT_AND_EXECUTE( p1.reset( new hoge() ) );
PRINT_AND_EXECUTE( p2.reset() );
- // swap ¤Ç;·×¤Ê¥ª¥Ö¥¸¥§¥¯¥È¤¬ºî¤é¤ì¤Ê¤¤¤³¤È¤ò¥Á¥§¥Ã¥¯
+ // swap ã\81§ä½\99è¨\88ã\81ªã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81\8cä½\9cã\82\89ã\82\8cã\81ªã\81\84ã\81\93ã\81¨ã\82\92ã\83\81ã\82§ã\83\83ã\82¯
PRINT_AND_EXECUTE( swap( p1, p2 ) );
- // shared_ptr ¤Ø¤ÎÊÑ´¹¥Á¥§¥Ã¥¯
+ // shared_ptr ã\81¸ã\81®å¤\89æ\8f\9bã\83\81ã\82§ã\83\83ã\82¯
PRINT_AND_EXECUTE( to_shared( p1 ) );
PRINT_AND_EXECUTE( to_shared( p2 ) );
PRINT_AND_EXECUTE( to_shared( p3 ) );
- // È´¤±¤ë¤è¡¼
+ // æ\8a\9cã\81\91ã\82\8bã\82\88ã\83¼
cout << "leaving test_hoge().\n";
}
-// pimpl ¤Ç»È¤¦¤È³ä¤ÈÊØÍø¤½¤¦¤À¤¬
-// ¥µ¥ó¥×¥ë¤Ï̤´°À®
+// pimpl で使うと割と便利そうだが
+// サンプルは未完成
int main()
{
-// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+// ヘッダのインクルード
#include "../gintenlib/deleter.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
#include <boost/noncopyable.hpp>
-// ÉÔ´°Á´·¿¡Ê¸å¤Ç»È¤¦¡Ë
+// 不完全型(後で使う)
struct incomplete_type;
-// ¥Æ¥¹¥ÈÍѤΥ¯¥é¥¹¡¢
-// À¸¤¤Æ¤¤¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¿ô¤ò¿ô¤¨¤ë
+// テスト用のクラス、
+// 生きているオブジェクトの数を数える
class test_class
: boost::noncopyable
{
};
int test_class::count_ = 0;
-// ¤Þ¤º deleter & dummy_deleter ¤Î¥Æ¥¹¥È
+// まず deleter & dummy_deleter のテスト
void test_deleter()
{
const int count = test_class::use_count();
gintenlib::deleter del;
- // ¥Ç¥ê¡¼¥È¤Ã
+ // デリートっ
del( p );
BOOST_CHECK( test_class::use_count() == count );
p = 0;
- del( p ); // ¤Ì¤ë¤Ý¤ËÂФ·¤Æ¤Ï²¿¤â¤·¤Ê¤¤
+ del( p ); // ぬるぽに対しては何もしない
BOOST_CHECK( test_class::use_count() == count );
- // ¤½¤Î¤Û¤«¡¢¡Ê°ÕÌ£¤Ï̵¤¤¤±¤É¡Ë¤³¤ì¤ÏÆ°¤¯
+ // そのほか、(意味は無いけど)これは動く
del( new int() );
- // ¤³¤ó¤Ê¤Î¤â¥®¥ê¥®¥ê¹çË¡
+ // こんなのもギリギリ合法
del( static_cast<test_class*>(0) );
- BOOST_CHECK( test_class::use_count() == count ); // ¥«¥¦¥ó¥ÈÊѲ½¤·¤Æ¤Ê¤¤¤è¡©
+ BOOST_CHECK( test_class::use_count() == count ); // カウント変化してないよ?
- // ¤Ç¤â¤³¤ì¤Ï¥À¥á¡£ÉÔ´°Á´·¿¤Î delete
+ // でもこれはダメ。不完全型の delete
// del( static_cast<incomplete_type*>(0) );
- // ÅöÁ³¤È»×¤¦¤Ç¤·¤ç¡¢¤Ç¤â ¢ ¤³¤ì¤À¤È
+ // 当然と思うでしょ、でも ↓ これだと
// delete static_cast<incomplete_type*>(0);
- // ¥³¥ó¥Ñ¥¤¥ëÄ̤äÁ¤ã¤¦¤ó¤Ç¤¹¤è¡©
- // ¡¦¡¦¡¦¤Þ¡¼ boost::checked_delete ¤Î¤ª¤«¤²¤Ê¤ó¤Ç¤¹¤¬
+ // コンパイル通っちゃうんですよ?
+ // ・・・まー boost::checked_delete のおかげなんですが
- // ¤¸¤ã¡¼ dummy_deleter ¤À¤È¤É¤¦¤Ê¤ë¡©
+ // じゃー dummy_deleter だとどうなる?
p = new test_class();
BOOST_CHECK( test_class::use_count() == count + 1 );
- // ÌÌÅݤʤΤǤ½¤Î¾ì¤Ç¹½ÃÛ¤¹¤ë
+ // 面倒なのでその場で構築する
gintenlib::dummy_deleter()( p );
- // ¼ÂºÝ¤Ë¤Ïºï½ü¤µ¤ì¤Æ¤Ê¤¤¤Î¤Ç¥«¥¦¥ó¥È¤ÏÊѲ½¤·¤Ê¤¤È¦
+ // 実際には削除されてないのでカウントは変化しない筈
BOOST_CHECK( test_class::use_count() == count + 1 );
- delete p; p = 0; // »ÅÊý¤Ê¤¤¤Î¤Ç¼êÆ° delete
+ delete p; p = 0; // 仕方ないので手動 delete
- // ¤³¤ó¤Ê¥Õ¥¡¥ó¥¯¥¿¤Ë°Ọ̃ͤ뤫¤Ã¤Æ¡©
- // ¤¢¤ë¤è¡£Î㤨¤Ð boost::shared_ptr ¤ò»È¤¦¾ì¹ç¤È¤«¡£
- // »²¾È´ÉÍý¤Ë boost::weak_ptr ¤ò»È¤¤¤¿¤¤¤±¤É¡¢¥Ý¥¤¥ó¥¿¤Îºï½ü¤Þ¤Ç¤Ï¤·¤ÆÍߤ·¤¯¤Ê¤¤¡¢
- // ¤½¤¦¤¤¤¦¤È¤¤Ëµ¤·Ú¤Ë»È¤¨¤ë¤Î¤¬ dummy_deleter ¡£
- // ¤¤¤Á¤¤¤Á¤½¤Î¾ì¤Ç¡Ö²¿¤â¤·¤Ê¤¤¥Õ¥¡¥ó¥¯¥¿¡×¤òºî¤ë¤è¤êµ¤¤¬Íø¤¤¤Æ¤ë¤Ç¤·¤ç¡©
+ // こんなファンクタに意味有るかって?
+ // あるよ。例えば boost::shared_ptr を使う場合とか。
+ // 参照管理に boost::weak_ptr を使いたいけど、ポインタの削除まではして欲しくない、
+ // そういうときに気軽に使えるのが dummy_deleter 。
+ // いちいちその場で「何もしないファンクタ」を作るより気が利いてるでしょ?
}
-// ¼¡¡¢ typed_deleter ¤Î¥Æ¥¹¥È
-// ¤Ê¤ó¤È¤Ê¤¯»×¤¤Î©¤Ã¤Æ value_saver ¤Ê¤ó¤Æ»È¤Ã¤Æ¤ß¤ë
+// 次、 typed_deleter のテスト
+// なんとなく思い立って value_saver なんて使ってみる
#include "../gintenlib/value_saver.hpp"
void test_typed_deleter()
int i = 1;
- // value_saver ¤òºî¤ë¡£
- // µ¡Ç½¤Ï¡¢¥Ç¥¹¥È¥é¥¯¥¿¸Æ¤Ó½Ð¤·»þ¤ËÂоÝÊÑ¿ô¤ÎÃͤòÉü¸µ
+ // value_saver を作る。
+ // 機能は、デストラクタ呼び出し時に対象変数の値を復元
value_saver* p = new value_saver(i);
BOOST_CHECK( i == 1 );
BOOST_CHECK( i == 2 );
gintenlib::typed_deleter<value_saver> del;
- // ºï½ü¤Ã
+ // 削除っ
del( p ); p = 0;
- // ¤³¤ì¤Ë¤è¤ê´¬¤Ìá¤Ã¤¿¤Ï¤º
+ // これにより巻き戻ったはず
BOOST_CHECK( i == 1 );
- // ¤Þ¡¼¤ä¤Ã¤Æ¤ë¤³¤È¤Ï deleter ¤ÈÊѤï¤ê¤Þ¤»¤ó¡£
+ // まーやってることは deleter と変わりません。
// del( new int() );
- // ¤³¤ì¤¬Æ°¤«¤Ê¤¤¤¯¤é¤¤¤Ç¡£
+ // これが動かないくらいで。
- // typed_dummy_deleter ¤âƱÍͤË
+ // typed_dummy_deleter も同様に
p = new value_saver(i);
i = 2;
BOOST_CHECK( i == 2 );
gintenlib::typed_dummy_deleter<value_saver>()( p );
- // ¥À¥ß¡¼¤Ê¤Î¤ÇÊѤï¤é¤Ê¤¤
+ // ダミーなので変わらない
BOOST_CHECK( i == 2 );
- // ¤á¤ó¤É¤¤¤Î¤Ç delete ¤â¤·¤Ê¤¤¡Ê¤©¤£¡Ë
+ // めんどいので delete もしない(ぉぃ)
}
int test_main( int argc, char* argv[] )
-// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+// ヘッダのインクルード
#include <gintenlib/preprocessor/enable_if.hpp>
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
-// ¥Æ¥¹¥È¤Ë»È¤¦¥¯¥é¥¹
+// ã\83\86ã\82¹ã\83\88ã\81«ä½¿ã\81\86ã\82¯ã\83©ã\82¹
struct base {};
struct derived : base {};
-// ¥Æ¥¹¥È¤Ë»È¤¦¥á¥¿´Ø¿ô
+// テストに使うメタ関数
#include <boost/type_traits/is_base_of.hpp>
-// GINTENLIB_ENABLE_IF ¤Î¥Á¥§¥Ã¥¯
-// ¤³¤ì¤µ¤¨Ä̤ì¤Ð¡¢¤³¤ÎÆâÉô¤Ç»È¤ï¤ì¤Æ¤¤¤ë
+// GINTENLIB_ENABLE_IF ã\81®ã\83\81ã\82§ã\83\83ã\82¯
+// これさえ通れば、この内部で使われている
// <gintenlib/enable_if.hpp>
// <gintenlib/d_enable_if.hpp>
// <gintenlib/preprocessor/dequote.hpp>
-// ¤³¤ì¤é¤Î¥Á¥§¥Ã¥¯¤â¼«Æ°Åª¤ËÄ̤俤³¤È¤Ë¤Ê¤ë
+// これらのチェックも自動的に通ったことになる
template<typename T>
bool hoge( const T&, GINTENLIB_ENABLE_IF(( boost::is_base_of<base, T> )) )
{
}
-// ñÂΥƥ¹¥ÈËÜÂÎ
+// 単体テスト本体
int test_main( int argc, char* argv[] )
{
derived d;
#include "../gintenlib/factorize.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
#include <vector>
#include <iterator>
using namespace std;
-// ¥Á¥§¥Ã¥¯ÍÑ´Ø¿ô
+// チェック用関数
template<typename T, size_t N>
inline void check( T x, const T (&ans)[N] )
{
- // ¤È¤ê¤¢¤¨¤º¥³¥ó¥Æ¥Ê¤òÍÑ°Õ
+ // とりあえずコンテナを用意
vector<T> v;
- // ºÇ½é¤Ë v ¤ÎÎΰè¤ò³ÎÊݤ·¤Æ¤ª¤¯¡Ê factorize ¼ºÇÔ¸å¤Î¥Æ¥¹¥È¤ÇÎΰè°ãÈ¿¤·¤Ê¤¤¤¿¤á¡Ë
+ // 最初に v の領域を確保しておく( factorize 失敗後のテストで領域違反しないため)
v.reserve(N);
- // ËÜÂÎ
+ // 本体
gintenlib::factorize( x, back_inserter(v) );
- // Í×ÁÇ¿ô¤Î¥Á¥§¥Ã¥¯
+ // è¦\81ç´ æ\95°ã\81®ã\83\81ã\82§ã\83\83ã\82¯
BOOST_CHECK( v.size() == N );
- // ³Æ°ø¿ô¤Î¥Á¥§¥Ã¥¯
+ // å\90\84å\9b æ\95°ã\81®ã\83\81ã\82§ã\83\83ã\82¯
for( size_t i = 0; i < N; ++i )
{
BOOST_CHECK( v[i] == ans[i] );
int test_main( int argc, char* argv[] )
{
- // 12 * 23 * 42 = 11592 = 2 * 2 * 2 * 3 * 3 * 7 * 23 ¤ò°ø¿ôʬ²ò
+ // 12 * 23 * 42 = 11592 = 2 * 2 * 2 * 3 * 3 * 7 * 23 を因数分解
{
int ans[] = { 2, 2, 2, 3, 3, 7, 23 };
check( 12 * 23 * 42, ans );
}
- // 8191¡ÊÁÇ¿ô¡Ë ¤ò°ø¿ôʬ²ò
+ // 8191(素数) を因数分解
{
int ans[] = { 8191 };
check( 8191, ans );
}
- // 1024 = 2 ** 10 ¤ò°ø¿ôʬ²ò
+ // 1024 = 2 ** 10 を因数分解
{
int ans[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
check( 1024, ans );
}
- // ¤ª¤ï¤ê
+ // おわり
return 0;
}
#include "../gintenlib/list_format.hpp"
#include "../gintenlib/to_string.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
#include <sstream>
int test_main( int argc, char* argv[] )
{
- // ¤È¤ê¤¢¤¨¤º¥Ç¡¼¥¿¤òÍÑ°Õ¤¹¤ë
+ // とりあえずデータを用意する
vector<int> v;
v.push_back( 0 );
v.push_back( 6 );
v.push_back( 7 );
{
- // ¤Á¤ã¤ó¤Èºî¤ì¤Æ¤ë¡©
+ // ちゃんと作れてる?
ostringstream oss;
oss << gintenlib::list_format( v );
BOOST_CHECK( oss.str() == "( 0, 6, 1, 7 )" );
BOOST_CHECK( oss.str() == gintenlib::to_str( gintenlib::list_format( v.begin(), v.end() ) ) );
}
{
- // ¥¹¥¿¥¤¥ë¤òÊѲ½¤µ¤»¤Æ¤ß¤è¤¦
+ // スタイルを変化させてみよう
ostringstream oss;
oss << gintenlib::list_format( v, "", " ", "" );
BOOST_CHECK( oss.str() == "0 6 1 7" );
#include "../gintenlib/list_formatter.hpp"
#include "../gintenlib/to_string.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
#include <sstream>
using namespace std;
-// list_format ¤ÈƱ¤¸¤Ç¼ºÎé
+// list_format と同じで失礼
int test_main( int argc, char* argv[] )
{
- // ¤È¤ê¤¢¤¨¤º¥Ç¡¼¥¿¤òÍÑ°Õ¤¹¤ë
+ // とりあえずデータを用意する
vector<int> v;
v.push_back( 0 );
v.push_back( 6 );
{
ostringstream oss;
- // formatter ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë
+ // formatter オブジェクトを作る
gintenlib::list_formatter fmt;
- // ¥³¥ó¥Æ¥Ê¤Ë³ú¤Þ¤»¤Æ½ÐÎÏ
+ // コンテナに噛ませて出力
oss << fmt( v );
BOOST_CHECK( oss.str() == "( 0, 6, 1, 7 )" );
BOOST_CHECK( oss.str() == gintenlib::to_str( gintenlib::list_format( v.begin(), v.end() ) ) );
}
{
- // ¥¹¥¿¥¤¥ë¤òÊѲ½¤µ¤»¤ë¾ì¹ç¤Ë¡¢¾¯¤·³Ú¤Ë¤Ê¤ë
+ // スタイルを変化させる場合に、少し楽になる
ostringstream oss;
- // formatter ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¤È¤¤Ë»ØÄê
+ // formatter オブジェクトを作るときに指定
gintenlib::list_formatter fmt( "", " ", "" );
- // ½ÐÎÏÉô¤ÏÊѤ¨¤Ê¤¯¤Æ¤¤¤¤
+ // 出力部は変えなくていい
oss << fmt( v );
BOOST_CHECK( oss.str() == "0 6 1 7" );
- // Ê̤Υ¹¥¿¥¤¥ë¤Ç½ÐÎÏ
+ // 別のスタイルで出力
oss.str( string() );
- // iterator ¤ò»È¤Ã¤Æ¤ß¤ë
+ // iterator を使ってみる
copy( v.begin(), v.end(), fmt.make_iterator(oss) );
BOOST_CHECK( oss.str() == "0 6 1 7" );
#include "../gintenlib/move_ptr.hpp"
-// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
-// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
-// ¥³¥á¥ó¥È¤â¾¯¤Ê¤¯Èó¾ï¤Ë¸«Æñ¤¤¥Æ¥¹¥È¤Ç¤¹¤¬¡¢
-// ½ÐÎϤȥ½¡¼¥¹¤ò¸«Èæ¤Ù¤Æ²¿¤¬µ¯¤³¤Ã¤Æ¤ë¤«¤òÇÄ°®¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤
+// 仮テストコードなので
+// boost.test はまだ使わない。
+// コメントも少なく非常に見難いテストですが、
+// 出力とソースを見比べて何が起こってるかを把握してみてください
struct hoge
{
virtual void foo() = 0;
- // ´Ø¿ô¤ÎÌá¤êÃͤȤ·¤Æ»È¤¦¤³¤È¤¬½ÐÍè¤ë
+ // 関数の戻り値として使うことが出来る
static gintenlib::move_ptr<hoge> create( int i );
// static std::auto_ptr<hoge> create( int i );
#include <iostream>
using namespace std;
-// Ê̤ÎÎã¡¢ºï½üÍÑ¥Õ¥¡¥ó¥¯¥¿¤òÍÑ°Õ¤¹¤ë
+// 別の例、削除用ファンクタを用意する
struct my_deleter
{
my_deleter( int x = 0 ) : i(x) {}
p1->foo();
p1.reset();
- // ¼«ºî¥Ç¥ê¡¼¥¿¤ò»È¤Ã¤Æ¤ß¤ë
+ // 自作デリータを使ってみる
gintenlib::move_ptr< int, my_deleter > p4( new int(4) ), p5( new int(5), my_deleter(2) );
p4 = p5;
cout << *p4 << endl;
cout << "scope out.\n";
}
-// ËÜÍè¤ÏÊÌ¥Õ¥¡¥¤¥ë¤ËÃÖ¤¯¤Ù¤¤Ç¤¹¤¬´Êά¤Î¤¿¤á¡£
+// 本来は別ファイルに置くべきですが簡略のため。
gintenlib::move_ptr<hoge> hoge::create( int i )
{
struct impl : hoge
#include "../gintenlib/new_.hpp"
-// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
-// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
-// ¤È¤¤¤¦¤è¤ê¡¢´Êñ¤Ê»È¤¤Æ»¤òÀâÌÀ¤¹¤ëÄøÅ٤Υ³¡¼¥É¡£
+// 仮テストコードなので
+// boost.test はまだ使わない。
+// というより、簡単な使い道を説明する程度のコード。
#include <iostream>
using namespace std;
-// shared_ptr ¤ò¼õ¤±¼è¤ë´Ø¿ô
+// shared_ptr を受け取る関数
template<typename T>
void hoge( const boost::shared_ptr<T>& ptr )
{
- // ÆâÍƤÏÊ̤ˤɤ¦¤Ç¤â¤è¤í¤·¤¤
+ // 内容は別にどうでもよろしい
cout << *ptr << endl;
}
void test1()
{
- // ´ðËÜŪ¤Ê»È¤¤¤«¤¿
- // shared_ptr ¤ò¼õ¤±¼è¤ë´Ø¿ô¤¬¤¢¤ë¤È¤¹¤ë¡£Î㤨¤Ð¾å¤Î hoge ¤À¡£
- // ¤³¤Î¼ê¤Î´Ø¿ô¤Ë¡¢¿·¤·¤¯ºî¤Ã¤¿¥ª¥Ö¥¸¥§¥¯¥È¤òÆþ¤ì¤¿¤¤¡£
+ // 基本的な使いかた
+ // shared_ptr を受け取る関数があるとする。例えば上の hoge だ。
+ // この手の関数に、新しく作ったオブジェクトを入れたい。
// hoge( new int(23) );
- // ¤³¤¦½ñ¤±¤ì¤Ð¤¤¤¤¤¬¡¢À¸¥Ý¥¤¥ó¥¿¤«¤é shared_ptr ¤Ø¤Î°ÅÌÛÊÑ´¹¤ÏÉÔ²Äǽ¤Ç¤¢¤ë¡£
+ // こう書ければいいが、生ポインタから shared_ptr への暗黙変換は不可能である。
- // ¤½¤³¤Ç¤³¤¦½ñ¤¡¢ÌÀ¼¨Åª¤ËÊÑ´¹¤·¤ÆÅϤ¹¤³¤È¤È¤Ê¤ë¡£
+ // そこでこう書き、明示的に変換して渡すこととなる。
hoge( boost::shared_ptr<int>( new int(23) ) );
- // ¤³¤ì¤Ï·¿Ì¾ int ¤¬Æó²ó»È¤ï¤ì¤Æ¤¤¤Æ¾éŤǤ¢¤ë¡£¤³¤³¤Ç new_ ¤ò»È¤¨¤Ð
+ // これは型名 int が二回使われていて冗長である。ここで new_ を使えば
hoge( gintenlib::new_<int>( 42 ) );
- // ¤È½ñ¤±¤ë¡£Â¿¤¯¤Î¥×¥í¥°¥é¥Þ¤Ï¡¢¤³¤ì¤ò¼«Á³¤È´¶¤¸¤ë¤Î¤Ç¤Ï¤Ê¤¤¤À¤í¤¦¤«¡£
+ // と書ける。多くのプログラマは、これを自然と感じるのではないだろうか。
- // ¤Þ¤¿¡¢¤³¤ì¤ÏÎã³°°ÂÁ´À¤Î´ÑÅÀ¤«¤é¤â½ÅÍפǤ¢¤ë¡£
- // ¾Ü¤·¤¯¤Ï http://boost.cppll.jp/HEAD/libs/smart_ptr/shared_ptr.htm#BestPractices ¤ò»²¾È¡£
- // gintenlib::new_ ¤Ï¡¢¤³¤ÎÌäÂê¤òÈó¾ï¤Ë¤¦¤Þ¤¯°·¤¦¤³¤È¤¬½ÐÍè¤ë¡£
+ // また、これは例外安全性の観点からも重要である。
+ // 詳しくは http://boost.cppll.jp/HEAD/libs/smart_ptr/shared_ptr.htm#BestPractices を参照。
+ // gintenlib::new_ は、この問題を非常にうまく扱うことが出来る。
}
-// ¤Þ¤¿ gintenlib::new_ ¤Ï¡¢¤½¤ì°Ê³°¤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß¤¹¤ë¤è¤¦¤Ê¥¯¥é¥¹¤ò´Êñ¤ËºîÀ®¤Ç¤¤ë¡£
-// ¤½¤Î°ìÈ֤λȤ¤Æ»¤Ï¡¢boost::enable_shared_from_this ¤ò»È¤¦¾ì¹ç¤À¤í¤¦¡£
-// gintenlib::new_ °Ê³°¤Ç¹½ÃۤǤ¤Ê¤¤¥¯¥é¥¹¤Ï¡¢³Î¼Â¤Ë shared_ptr ¤Ë³ÊǼ¤µ¤ì¤ë¤«¤é¤Ç¤¢¤ë¡£
-// ¤³¤ì¤é¤Ë¤ÏÆó¤Ä¤Î¼ÂÁõË¡¤¬¤¢¤ë¡£½ç¤Ë¸«¤Æ¤ß¤è¤¦¡£
+// また gintenlib::new_ は、それ以外からの構築を禁止するようなクラスを簡単に作成できる。
+// その一番の使い道は、boost::enable_shared_from_this を使う場合だろう。
+// gintenlib::new_ 以外で構築できないクラスは、確実に shared_ptr に格納されるからである。
+// これらには二つの実装法がある。順に見てみよう。
#include <boost/enable_shared_from_this.hpp>
-// ¼ÂÁõ£±
+// 実装1
struct force_shared1
: boost::enable_shared_from_this<force_shared1>
{
}
private:
- // private ¤ËÁ´¤Æ¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤òÃÖ¤¡¢°ìÈ̤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß
+ // private に全てのコンストラクタを置き、一般からの構築を禁止
force_shared1() {}
- // ¤½¤Î¾å¤Ç gintenlib::new_core_access ¹½Â¤ÂΤò friend ¤Ë»ØÄꤹ¤ë
+ // その上で gintenlib::new_core_access 構造体を friend に指定する
friend class gintenlib::new_core_access;
};
-// ¼ÂÁõ£²
+// 実装2
struct force_shared2
: boost::enable_shared_from_this<force_shared2>,
- gintenlib::enable_static_new_<force_shared2> // ¤³¤ì¤ò»ØÄꤹ¤ë
+ gintenlib::enable_static_new_<force_shared2> // これを指定する
{
~force_shared2() throw () {}
- // ŬÅö¤Ë¥á¥ó¥Ð¤òÃÖ¤¯
+ // 適当にメンバを置く
void foo();
void bar();
- // enable_static_new_<¥¯¥é¥¹Ì¾> ¤«¤é·Ñ¾µ¤µ¤»¤ë¤³¤È¤Ç¡¢
- // new_ ¤Ë¤è¤ë¹½Ãۤϡ¢¤½¤Î¥¯¥é¥¹¤ÎÀÅŪ´Ø¿ô new_ ¤òÄ̤·¤Æ¹Ô¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ë
+ // enable_static_new_<クラス名> から継承させることで、
+ // new_ による構築は、そのクラスの静的関数 new_ を通して行われるようになる
static boost::shared_ptr<force_shared2> new_()
{
cout << "force_shared2::new_();\n";
return boost::shared_ptr<force_shared2>( new force_shared2() );
}
- // ÅöÁ³Ê£¿ô¤Î new_ ¤òÃÖ¤±¤ë
+ // 当然複数の new_ を置ける
static boost::shared_ptr<force_shared2> new_( int )
{
cout << "force_shared2::new_( int );\n";
}
private:
- // ƱÍÍ¤Ë private ¤ËÁ´¤Æ¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤òÃÖ¤¡¢°ìÈ̤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß
+ // 同様に private に全てのコンストラクタを置き、一般からの構築を禁止
force_shared2() {}
};
-// »È¤¤Êý
+// 使い方
void test2()
{
- // »È¤¦Ê¬¤Ë¤Ï¤½¤Îº¹¤ò°Õ¼±¤¹¤ë¤³¤È¤Ï¤Ê¤¤¡£
+ // 使う分にはその差を意識することはない。
boost::shared_ptr<force_shared1> p1 = gintenlib::new_<force_shared1>();
p1->foo();
#include "../gintenlib/options.hpp"
-// <gintenlib/options/options.hpp> ¤ÎÎãʸ¤ÈƱ¤¸¥³¡¼¥É
-// Boost.Test ¤Ç¤Î¥Á¥§¥Ã¥¯¤Ï¤â¤¦¾¯¡¹¤ªÂÔ¤Á¤ò¡£
+// <gintenlib/options/options.hpp> の例文と同じコード
+// Boost.Test でのチェックはもう少々お待ちを。
-// usage: ¥³¥Þ¥ó¥É̾ ¥ª¥×¥·¥ç¥óʸ»úÎó ²òÀϤµ¤»¤¿¤¤°ú¿ô
-// ¤³¤¦µ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ options ¤Î¤Û¤ÜÁ´µ¡Ç½¤ò¥Æ¥¹¥È¤Ç¤¤ëÎã¤Ç¤¹
+// usage: コマンド名 オプション文字列 解析させたい引数
+// こう起動することにより、 options のほぼ全機能をテストできる例です
#include <gintenlib/options.hpp>
#include <gintenlib/cast.hpp>
int main( int argc, char* argv[] )
{
- // °ÅÌÛ¥¥ã¥¹¥È
+ // 暗黙キャスト
using gintenlib::cast;
try
{
if( argc < 2 ){ throw gintenlib::option_error("missing 'OPTSTR'"); }
- // argv[1] ¤ÏÆÃÊ̤ʰú¿ô
+ // argv[1] は特別な引数
gintenlib::options opt( argv[1], argc, argv );
- // ¤Ê¤Î¤Ç²òÀϤµ¤»¤Ê¤¤
+ // なので解析させない
opt.set_optind( 2 );
for(;;)
{
- // ²òÀϤµ¤»¤ë¡£ ch ¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤Îʸ»ú¤¬Æþ¤ë
+ // 解析させる。 ch にはオプションの文字が入る
int ch = opt();
- if( ch == -1 ){ break; } // -1: ²òÀϽª¤ï¤ê
+ if( ch == -1 ){ break; } // -1: 解析終わり
switch(ch)
{
case '?':
- // ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ // ':' で始まるオプション文字列への対応
cout << "unknown option '" << cast<char>( opt.optopt() ) << "' is given. continue...\n";
break;
case ':':
- // Ʊ¤¸¤¯ ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ // 同じく ':' で始まるオプション文字列への対応
cout << "option '" << cast<char>( opt.optopt() ) << "'requires argument. continue...\n";
break;
default:
- // ¥ª¥×¥·¥ç¥ó°ìÈÌ
+ // オプション一般
cout << "option '" << cast<char>( ch ) << "' is given.\n";
- // °ú¿ô¤Ï optarg() ¤Ç³ÍÆÀ
- // °ú¿ô¤¬Ìµ¤¤¾ì¹ç¤Ï string() ¤¬Æþ¤ë
+ // 引数は optarg() で獲得
+ // 引数が無い場合は string() が入る
if( !opt.optarg().empty() )
{
cout << " argument: " << opt.optarg() << endl;
}
}
- // ²òÀϽªÎ»¡£Í¾¤Ã¤¿¥ª¥×¥·¥ç¥ó¤Ï argv[opt.optind()] ¡Á argv[argc-1] ¤Ë½¸¤á¤é¤ì¤ë
- // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó°ú¿ô¤¬È󥪥ץ·¥ç¥ó°ú¿ô¤Î¸å¤Ë¤¢¤ë¾ì¹ç¡¢ argv ¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤ë
- // ¤³¤ÎÆ°ºî¤òÈò¤±¤¿¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤Î°ú¿ô¤ò '+' ¤Ç»Ï¤á¤ì¤Ð¤è¤¤
+ // 解析終了。余ったオプションは argv[opt.optind()] 〜 argv[argc-1] に集められる
+ // デフォルトでは、オプション引数が非オプション引数の後にある場合、 argv の順序を入れ替える
+ // この動作を避けたい場合は、コンストラクタの引数を '+' で始めればよい
cout << "\nextra options are:\n";
for( int i = opt.optind(); i < argc; ++i )
{
}
catch( gintenlib::option_error& e )
{
- // ¥ª¥×¥·¥ç¥ó²òÀϤ˼ºÇÔ¤·¤ÆÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ï¤³¤Á¤é¤ËÈô¤Ö
+ // オプション解析に失敗して例外が投げられた場合はこちらに飛ぶ
cerr << e.what() << endl;
cerr << "usage: " << argv[0] << " OPTSTR [OPTIONS]\n";
}
catch( std::exception& e )
{
- // ¤½¤Î¤Û¤«¤ÎÎã³°
+ // そのほかの例外
cerr << e.what() << endl;
return 1;
}
#include "../gintenlib/plane/angle.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
namespace plane = gintenlib::plane;
int test_main( int argc, char* argv[] )
{
- // neary_equal ¤Î¥Á¥§¥Ã¥¯
+ // neary_equal ã\81®ã\83\81ã\82§ã\83\83ã\82¯
BOOST_CHECK( !nearly_equal( 0.0, 1.0 ) );
- // ¹½ÃÛ¡Ê°ú¿ô̵¤·¤Ê¤é 0 ¡¢°ú¿ô¤Ï¥é¥¸¥¢¥óñ°Ì¡Ë
+ // 構築(引数無しなら 0 、引数はラジアン単位)
angle_t a, b( M_PI );
BOOST_CHECK( a.theta == 0 );
BOOST_CHECK( b.theta == M_PI );
- // to_deg ¤Î¥Æ¥¹¥È
+ // to_deg のテスト
BOOST_CHECK( nearly_equal( a.to_deg(), 0.0 ) );
- BOOST_CHECK( nearly_equal( to_deg(b), 180.0 ) ); // ¤³¤¦½ñ¤¯¤³¤È¤â½ÐÍè¤ë
- // to_rad ¤Î¥Æ¥¹¥È
+ BOOST_CHECK( nearly_equal( to_deg(b), 180.0 ) ); // こう書くことも出来る
+ // to_rad のテスト
BOOST_CHECK( a.theta == a.to_rad() );
BOOST_CHECK( b.theta == to_rad(b) );
- // ¾¡¼ê¤ÊÃͤËÊѹ¹¡¢¤Ä¤¤¤Ç¤Ë radian ´Ø¿ô¤È degree ´Ø¿ô¤â¥Á¥§¥Ã¥¯
- a = plane::radian( 1.0 ); // 1rad ¢â 57.3¡ë
- b = plane::degree( 60.0 ); // ¤Ä¤Þ¤ê a < b
+ // å\8b\9dæ\89\8bã\81ªå\80¤ã\81«å¤\89æ\9b´ã\80\81ã\81¤ã\81\84ã\81§ã\81« radian é\96¢æ\95°ã\81¨ degree é\96¢æ\95°ã\82\82ã\83\81ã\82§ã\83\83ã\82¯
+ a = plane::radian( 1.0 ); // 1rad ≒ 57.3°
+ b = plane::degree( 60.0 ); // つまり a < b
- // == ¤Î¥Æ¥¹¥È¡Ê¤Ä¤¤¤Ç¤Ë rad ´Ø¿ô¤ä deg ´Ø¿ô¤â¥Æ¥¹¥È¡Ë
+ // == のテスト(ついでに rad 関数や deg 関数もテスト)
BOOST_CHECK( a == a );
BOOST_CHECK( b == b );
- BOOST_CHECK( a == plane::rad( a.to_rad() ) ); // ¤³¤ì¤Ï¤¢¤¿¤ê¤Þ¤¨
- BOOST_CHECK( plane::deg( 60.0 ) == b ); // ¾å¸«¤ì¤ÐÅö¤¿¤êÁ°
- // != ¤Î¥Æ¥¹¥È
+ BOOST_CHECK( a == plane::rad( a.to_rad() ) ); // これはあたりまえ
+ BOOST_CHECK( plane::deg( 60.0 ) == b ); // 上見れば当たり前
+ // != のテスト
BOOST_CHECK( a != b );
- // ¤½¤Î¤Û¤«
+ // そのほか
BOOST_CHECK( a < b );
BOOST_CHECK( a <= b );
BOOST_CHECK( b > a );
BOOST_CHECK( b >= a );
- // ²Ã¸º¾è½ü¡ÊÅö¤¿¤êÁ°¤Î»ö¼Â¡Ë
- // ¤Ê¤ó¤« + ±é»»»Ò¤È += ±é»»»Ò¤ÎµóÆ°¤¬°ã¤¦¤é¤·¤¤¤Î¤Ç nearly Èæ³Ó¤¹¤ë
+ // 加減乗除(当たり前の事実)
+ // なんか + 演算子と += 演算子の挙動が違うらしいので nearly 比較する
BOOST_CHECK( nearly_equal( (a+b).theta, a.theta + b.theta ) );
BOOST_CHECK( nearly_equal( (a-b).theta, a.theta - b.theta ) );
BOOST_CHECK( nearly_equal( (-a).theta , -(a.theta) ) );
BOOST_CHECK( nearly_equal( (a*2).theta, a.theta * 2 ) );
BOOST_CHECK( nearly_equal( (a/2).theta, a.theta / 2 ) );
- BOOST_CHECK( nearly_equal( a/b , a.theta / b.theta ) ); // Æó¤Ä¤Î³Ñ¤ÎÈæ¤Ï¼Â¿ô
- BOOST_CHECK( nearly_equal( (a%b).theta, std::fmod( a.theta, b.theta ) ) ); // ¾ê;»»¤Ï fmod
+ BOOST_CHECK( nearly_equal( a/b , a.theta / b.theta ) ); // 二つの角の比は実数
+ BOOST_CHECK( nearly_equal( (a%b).theta, std::fmod( a.theta, b.theta ) ) ); // 剰余算は fmod
// normalize
b = a + plane::rad( 2*M_PI );
- a.normalize(); // a ¤òÀµµ¬²½¡Ê¤³¤Î¾ì¹ç¤ÏÆä˰Ọ̵̃¤¤¤±¤É¡Ë
- b.normalize(); // b ¤âÀµµ¬²½¡£a ¤È b ¤Ï 2¦Ð ¤À¤±°ã¤¦¤Î¤ÇƱ¤¸Ãͤˤʤë¤Ï¤º
- BOOST_CHECK( -M_PI <= b.theta && b.theta <= M_PI ); // normalize ¤·¤¿ÃͤϤ³¤Î¾ò·ï¤òËþ¤¿¤¹
+ a.normalize(); // a を正規化(この場合は特に意味無いけど)
+ b.normalize(); // b も正規化。a と b は 2π だけ違うので同じ値になるはず
+ BOOST_CHECK( -M_PI <= b.theta && b.theta <= M_PI ); // normalize した値はこの条件を満たす
BOOST_CHECK( nearly_equal( a.theta, b.theta ) );
- // ¤³¤ó¤É¤Ï -2¦Ð ¤À¤±¤º¤é¤·¤ÆºÆÅÙ¤Á¤§¤Ã¤¯
+ // こんどは -2π だけずらして再度ちぇっく
b = a - plane::rad( 2*M_PI );
- // normalize ¤·¤¿ÃͤΤßɬÍפʤ顢¤³¤¦¤â½ñ¤±¤ë¡ÊÊÑ¿ô¤Ë¤Ï±Æ¶Á¤·¤Ê¤¤¡Ë
+ // normalize した値のみ必要なら、こうも書ける(変数には影響しない)
BOOST_CHECK( nearly_equal( normalized(a).theta, normalized(b).theta ) );
- // ¤³¤ÎÊÕ¤Ï unique ¤Ç¤âÁ´¤¯Æ±¤¸¡Ê·ë²Ì¤ÎÃͤÎÈϰϤÀ¤±¤¬°ã¤¦¡Ë
+ // この辺は unique でも全く同じ(結果の値の範囲だけが違う)
b = a + plane::rad( 2*M_PI );
a.unique();
b.unique();
- BOOST_CHECK( 0 <= b.theta && b.theta < M_PI * 2 ); // °ã¤¦¤Î¤Ï¤³¤Î¾ò·ï¤À¤±
+ BOOST_CHECK( 0 <= b.theta && b.theta < M_PI * 2 ); // 違うのはこの条件だけ
BOOST_CHECK( nearly_equal( a.theta, b.theta ) );
b = a - plane::rad( 2*M_PI );
BOOST_CHECK( nearly_equal( uniqued(a).theta, uniqued(b).theta ) );
- // ¶³¦¤Ç¤Î¿¶Éñ¤¤
- // normalize ¤Î¾ì¹ç¡¢Ãͤ¬ ¡ÞM_PI ¤Î»þ¤Ë¡¢Æ±¤¸³ÑÅ٤ˤâ´Ø¤ï¤é¤ºÅù¤·¤¯¤Ê¤¤¾ì¹ç¤¬¤¢¤ë
+ // 境界での振舞い
+ // normalize の場合、値が ±M_PI の時に、同じ角度にも関わらず等しくない場合がある
a = plane::rad( -M_PI );
b = plane::rad( +M_PI );
BOOST_CHECK( !nearly_equal( normalized(a).theta, normalized(b).theta ) );
- // unique ¤Ê¤é¡¢¤½¤ÎÅÀ¤Ï°Â¿´¡Ê¤¿¤À¤· 2¦Ð ÉÕ¶á¤Ç¡¢¤´¤¯¶Ï¤«¤Êº¹¤¬Â礤ʰ㤤¤Ë¤Ê¤ê¤¨¤ë¤³¤È¤Ï¤¢¤ë¡Ë
+ // unique なら、その点は安心(ただし 2π 付近で、ごく僅かな差が大きな違いになりえることはある)
BOOST_CHECK( nearly_equal( uniqued(a).theta, uniqued(b).theta ) );
- // ¥µ¥¤¥ó¥³¥µ¥¤¥ó¥¿¥ó¥¸¥§¥ó¥È
+ // サインコサインタンジェント
using namespace std;
a = plane::deg(45.0);
b = plane::deg(60.0);
BOOST_CHECK( nearly_equal( a.cos(), cos( a.theta ) ) );
BOOST_CHECK( nearly_equal( a.tan(), tan( a.theta ) ) );
- // ¤³¤¦½ñ¤¤¤Æ¤â¤¤¤¤¡Ê¤½¤·¤Æ¤½¤Ã¤Á¤Î¤Û¤¦¤¬¼«Á³¡Ë
+ // こう書いてもいい(そしてそっちのほうが自然)
BOOST_CHECK( nearly_equal( sin(b), sin( b.theta ) ) );
BOOST_CHECK( nearly_equal( cos(b), cos( b.theta ) ) );
BOOST_CHECK( nearly_equal( tan(b), tan( b.theta ) ) );
- // µÕ»°³Ñ´Ø¿ô
+ // 逆三角関数
double x = 0.5, y = 1.0;
BOOST_CHECK( nearly_equal( plane::rad( asin(x) ), angle_t::asin(x) ) );
BOOST_CHECK( nearly_equal( plane::rad( acos(x) ), angle_t::acos(x) ) );
-// ¥Ø¥Ã¥À
+// ヘッダ
#include "../gintenlib/reference_counter.hpp"
-// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
-// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+// 仮テストコードなので
+// boost.test はまだ使わない。
#include <iostream>
using namespace std;
-// Ä̾ïÈÇ
+// 通常版
struct fast_ver
: gintenlib::reference_counter<fast_ver>
{
};
-// ¿½Å·Ñ¾µÈÇ
+// 多重継承版
struct base1
: gintenlib::reference_counter<base1, true>
{
}
};
-// Æó¤Ä¤Î¥¯¥é¥¹¤«¤éÇÉÀ¸¤¹¤ë
-// ÉáÄ̤ϤɤäÁ¤Î¥«¥¦¥ó¥È¤ò»È¤Ã¤Æ¤¤¤¤¤«Ê¬¤«¤é¤º¥³¥ó¥Ñ¥¤¥ëÄ̤é¤Ê¤¤
+// 二つのクラスから派生する
+// 普通はどっちのカウントを使っていいか分からずコンパイル通らない
struct derived
: base1, base2
{
};
-// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+// デバッグ用マクロ
#define PRINT_AND_EXECUTE( expr ) \
cout << #expr << ";\n"; expr
{
using boost::intrusive_ptr;
- // Ä̾ïÈÇ
+ // 通常版
{
intrusive_ptr<fast_ver> p1 = new fast_ver(), p2;
PRINT_AND_EXECUTE( p2.reset() );
}
- // ¿½Å·Ñ¾µÈÇ
+ // 多重継承版
{
intrusive_ptr<derived> p0 = new derived();
intrusive_ptr<base1> p1;
-// ¥Ø¥Ã¥À
+// ヘッダ
#include "../gintenlib/to_shared.hpp"
#include "../gintenlib/intrusive_to_shared.hpp"
#include "../gintenlib/reference_counter.hpp"
-// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
-// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+// 仮テストコードなので
+// boost.test はまだ使わない。
#include <iostream>
using namespace std;
-// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+// デバッグ用マクロ
#define PRINT_AND_EXECUTE( expr ) \
cout << #expr << ";\n"; expr
#define PRINT_EXPR( expr ) \
cout << #expr << " -> " << (expr) << endl
-// »ý¤¿¤»¤ë¥¯¥é¥¹
+// æ\8c\81ã\81\9fã\81\9bã\82\8bã\82¯ã\83©ã\82¹
struct hoge
: gintenlib::reference_counter<hoge>
{
};
-// ÈÆÍÑÈǤϤޤÀ¥Æ¥¹¥È¤·¤Ê¤¤¡£ intrusive, auto ¤ò¥Á¥§¥Ã¥¯
+// æ±\8eç\94¨ç\89\88ã\81¯ã\81¾ã\81 ã\83\86ã\82¹ã\83\88ã\81\97ã\81ªã\81\84ã\80\82 intrusive, auto ã\82\92ã\83\81ã\82§ã\83\83ã\82¯
int main()
{
// intrusive
{
- // pointer ÈÇ
+ // pointer 版
PRINT_AND_EXECUTE( gintenlib::intrusive_to_shared( new hoge() ) );
boost::intrusive_ptr<hoge> p1;
PRINT_AND_EXECUTE( p1 = new hoge() );
boost::shared_ptr<hoge> p2;
- // to_shared ÊÑ´¹
+ // to_shared 変換
PRINT_AND_EXECUTE( p2 = gintenlib::to_shared(p1) );
- // ¤Á¤ã¤ó¤ÈƱ¤¸¥ª¥Ö¥¸¥§¥¯¥È¡©
+ // ちゃんと同じオブジェクト?
PRINT_EXPR( p1.get() == p2.get() );
- // ¤â¤È¤â¤È¤Î intrusive ¤ò reset ¤·¤Æ¤âÂç¾æÉפ«¥Á¥§¥Ã¥¯
+ // ã\82\82ã\81¨ã\82\82ã\81¨ã\81® intrusive ã\82\92 reset ã\81\97ã\81¦ã\82\82大ä¸\88夫ã\81\8bã\83\81ã\82§ã\83\83ã\82¯
PRINT_AND_EXECUTE( p1.reset() );
- // È´¤±¤Þ¤¹
+ // 抜けます
cout << "scope out: p1, p2\n";
}
boost::shared_ptr<hoge> p2;
PRINT_AND_EXECUTE( p2 = gintenlib::to_shared(p1) );
- // ¤Á¤ã¤ó¤È½ê͸¢°ÜÆ°¤Ç¤¤Æ¤¤¤ë¤«¥Á¥§¥Ã¥¯
+ // ã\81¡ã\82\83ã\82\93ã\81¨æ\89\80æ\9c\89権移å\8b\95ã\81§ã\81\8dã\81¦ã\81\84ã\82\8bã\81\8bã\83\81ã\82§ã\83\83ã\82¯
PRINT_EXPR( p1.get() );
PRINT_EXPR( p2.get() );
- // ¤ª¤Þ¤±¡£trivial ¤Ê¤ä¤Ä
+ // おまけ。trivial なやつ
PRINT_AND_EXECUTE( gintenlib::to_shared(p2) );
- // È´¤±¤Þ¤¹
+ // 抜けます
cout << "scope out: p1, p2\n";
}
#include "../gintenlib/value_saver.hpp"
#include "../gintenlib/typed_saver.hpp"
-// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+// boost ã\81®å\8d\98ä½\93ã\83\86ã\82¹ã\83\88ã\83\95ã\83¬ã\83¼ã\83 ã\83¯ã\83¼ã\82¯
#include <boost/test/minimal.hpp>
-// ¥Æ¥¹¥ÈËÜÂΤϥƥó¥×¥ì¡¼¥È¤Çµ½Ò
+// テスト本体はテンプレートで記述
template<typename T, typename Saver>
void test( const T& x0, const T& x1 )
{
T x = x0;
{
- // ¤È¤ê¤¢¤¨¤º x ¤ÎÃͤò¥Á¥§¥Ã¥¯
+ // ã\81¨ã\82\8aã\81\82ã\81\88ã\81\9a x ã\81®å\80¤ã\82\92ã\83\81ã\82§ã\83\83ã\82¯
BOOST_CHECK( x == x0 );
- // Êݸ
+ // 保存
Saver saver(x);
- // saver ¤ËÆͤùþ¤ó¤À»þÅÀ¤Ç¤ÏÃͤÏÊѤï¤é¤Ê¤¤
+ // saver に突っ込んだ時点では値は変わらない
BOOST_CHECK( x == x0 );
- // ÃͤòÊѹ¹
+ // 値を変更
x = x1;
BOOST_CHECK( x == x1 );
- // ¤³¤³¤Ç¸µ¤ËÌá¤ë¤Ï¤º
+ // ここで元に戻るはず
}
BOOST_CHECK( x == x0 );
{
- // ¤Þ¤¿Êݸ
+ // また保存
Saver saver(x);
- // ÃͤòÊѹ¹
+ // 値を変更
x = x1;
BOOST_CHECK( x == x1 );
- // ÌÀ¼¨Åª¤ÊÃͤÎÉü¸µ
+ // 明示的な値の復元
saver.restore();
- // Éü¸µ¤Ç¤¤¿¤«¥Á¥§¥Ã¥¯
+ // 復å\85\83ã\81§ã\81\8dã\81\9fã\81\8bã\83\81ã\82§ã\83\83ã\82¯
BOOST_CHECK( x == x0 );
- // restore() ¸å¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤ÇÉü¸µ¤·¤Ê¤¤¡Ê¤¤¤¤¤«°¤¤¤«¤ÏÊ̤Ȥ·¤Æ¡Ë
+ // restore() 後はデストラクタで復元しない(いいか悪いかは別として)
x = x1;
}
BOOST_CHECK( x == x1 );
x = x0;
{
- // Êݸ¤ÈƱ»þ¤ËÃͤò½ñ¤´¹¤¨¤ë¡¢¤È¤¤¤¦¤Î¤Ï³ä¤È¤è¤¯¤¢¤ëÆ°ºî¤Ê¤Î¤Ç
- // ³Ú¤Ç¤¤ë¤è¤¦¤ËÀìÍÑ¥³¥ó¥¹¥È¥é¥¯¥¿¤òÍÑ°Õ¤·¤Æ¤¢¤ê¤Þ¤¹
+ // 保存と同時に値を書き換える、というのは割とよくある動作なので
+ // 楽できるように専用コンストラクタを用意してあります
Saver saver( x, x1 );
BOOST_CHECK( x == x1 );
- // ¤¤Á¤ó¤ÈÉü¸µ¤Ç¤¤ë¡©
+ // きちんと復元できる?
}
BOOST_CHECK( x == x0 );
{
- // Êݸ¤ÈƱ»þ¤ËÃͤò½ñ¤´¹¤¨¤ë¡¢¤È¤¤¤¦¤Î¤Ï³ä¤È¤è¤¯¤¢¤ëÆ°ºî¤Ê¤Î¤Ç
- // ³Ú¤Ç¤¤ë¤è¤¦¤ËÀìÍÑ¥³¥ó¥¹¥È¥é¥¯¥¿¤òÍÑ°Õ¤·¤Æ¤¢¤ê¤Þ¤¹
+ // 保存と同時に値を書き換える、というのは割とよくある動作なので
+ // 楽できるように専用コンストラクタを用意してあります
Saver saver( x, x1 );
BOOST_CHECK( x == x1 );
- // release() ¤ò¸Æ¤Ö¤È
+ // release() を呼ぶと
saver.release();
BOOST_CHECK( x == x1 );
}
- // Éü¸µ¤µ¤ì¤Ê¤¤
+ // 復元されない
BOOST_CHECK( x == x1 );
}
template<typename T>
void test_saver( const T& x0, const T& x1 )
{
- // ·¿ÉÕ¤ÈÈÆÍÑ¡¢Î¾Êý¥Æ¥¹¥È
+ // 型付と汎用、両方テスト
test< T, gintenlib::typed_saver<T> >( x0, x1 );
test< T, gintenlib::value_saver >( x0, x1 );
}
int test_main( int argc, char* argv[] )
{
- // ÁȤ߹þ¤ß·¿
+ // 組み込み型
test_saver<int>( 0, 1 );
- // ¥æ¡¼¥¶ÄêµÁ·¿¡Ê e.g. std::complex ¡Ë
+ // ユーザ定義型( e.g. std::complex )
std::complex<double> j( 0, 1 );
test_saver< std::complex<double> >( 1.0, j );
- // ¥æ¡¼¥¶ÄêµÁ·¿¤½¤Î¤Ë¡¢boost::shared_ptr
+ // ユーザ定義型そのに、boost::shared_ptr
boost::shared_ptr<int> p0, p1( new int(0) );
test_saver< boost::shared_ptr<int> >( p0, p1 );