OSDN Git Service

bool_comparable を最適化
[gintenlib/gintenlib.git] / gintenlib / typed_saver.hpp
1 #ifndef GINTENLIB_INCLUDED_TYPED_SAVER_HPP_
2 #define GINTENLIB_INCLUDED_TYPED_SAVER_HPP_
3
4 /*
5
6       <gintenlib/typed_saver.hpp>
7
8   typed_saver : デストラクタでの値の復帰(テンプレート版)
9
10   宣言:
11     template< typename T >
12     class typed_saver : boost::noncopyable
13     {
14      public:
15       // t の値を記録して
16       explicit typed_saver( T& t );
17       // デストラクタで元に戻す
18       ~typed_saver();
19       
20       // 明示的に値を戻したい場合に呼ぶ
21       // これを呼んでも、デストラクタでは再度値が巻き戻される
22       void invoke();
23       // これを呼ぶと、デストラクタで値が戻されることはなくなる
24       void release();
25       // invoke して release する
26       void reset();
27       
28     };
29     
30   機能:
31     コンストラクタで受け取った変数の値を記録し、デストラクタで書き戻します。
32     value_saver と違い変数の型を指定する必要がありますが、その分高速に動作します。
33     
34     詳しくは value_saver の項を確認して下さい。
35   
36   補足事項:
37     typed_saver, value_saver を利用できるオブジェクトの条件は、
38     ・CopyConstructible
39     ・Assignable
40     の2点です(version1.0.0で変更)。
41     また、例外を投げない swap() 関数呼び出しが存在すれば、例外安全です。
42
43 */
44
45 #include <algorithm>
46
47 #include <boost/noncopyable.hpp>
48 #include <boost/utility/addressof.hpp>
49
50 namespace gintenlib
51 {
52   // コンストラクタの時の値に、デストラクタで強制復帰させるオブジェクト
53   template< typename T >
54   struct typed_saver
55     : private boost::noncopyable
56   {
57     // t の値を記録し、デストラクタで巻き戻す
58     explicit typed_saver( T& t )
59       : target_( boost::addressof(t) ), saver_(t) {}
60     
61     // 復帰
62     ~typed_saver() { reset(); }
63     
64     // 明示的な復帰
65     // この呼出が行われたとしても、デストラクタでは再度 値の復帰が行われる
66     void invoke()
67     {
68       if( target_ )
69       {
70         *target_ = saver_;
71       }
72     }
73     
74     // 復帰処理の抑制
75     void release()
76     {
77       target_ = 0;
78     }
79     // 明示的に復帰してから release する
80     void reset()
81     {
82       if( target_ )
83       {
84         using std::swap;
85         swap( *target_, saver_ );
86         target_ = 0;
87       }
88     }
89
90    private:
91     T* target_;
92     T saver_;
93
94   };  // class typed_saver<T>
95
96 }   // namespace gintenlib
97
98 #endif  // #ifndef GINTENLIB_INCLUDED_TYPED_SAVER_HPP_