宣言:
template<typename T>
struct optional_storage
- : private boost::noncopyable
{
typedef T element_type;
typedef T value_type;
// 構築/破棄
optional_storage();
+
+ template<typename Constructor>
+ explicit optional_storage( Constructor ctor );
+
~optional_storage() throw ();
// 中のデータを破棄する
T& operator*();
const T& operator*() const;
+ private:
+ optional_storage( optional_storage const& ) = delete;
+ void operator=( optional_storage const& ) = delete;
+
}; // optional_storage<T>
機能:
また、optional_storage<T> を使って構築済みオブジェクトを破棄する場合には、
普通のデストラクタだけでなく、カスタムデストラクタを指定することもできます。
そういう場合は明示的に destory を呼び出し、その引数にカスタムデストラクタを渡しましょう。
+
+ (追記)
+ 「指定したアドレスに対して関数を呼び出し、 set_initialized() する」
+ という construct 関数を新しく作りました。
+ こちらの方がより安全なので、今後はこちらを使いましょう。
+ set_initialized は近々削除予定です。
使用例:
// とりあえず領域だけ確保して
// storage の有効期限が切れると、自動でデストラクトされるので安心
補足:
- ・placement new を呼んだら、即 set_initialized() を呼び出しましょう。
- ・それさえ守れば、非常に安全性は高い筈です。
+ ・set_initialized ではなく construct を使いましょう。
*/
#include <cassert>
-#include <boost/noncopyable.hpp>
#include "destructor.hpp"
#include "storage.hpp"
// ちょっと安全性の低い boost::optional
template<typename T>
struct optional_storage
- : private boost::noncopyable
{
typedef T element_type;
typedef T value_type;
optional_storage()
: initialized_( false ) {}
+ template<typename Constructor>
+ explicit optional_storage( Constructor ctor )
+ : initialized_( false )
+ {
+ construct_( ctor );
+ }
+
~optional_storage() throw ()
{
destory();
// 初期化ずみか否か
bool initialized() const { return initialized_; }
- // 初期化ずみマークをつける
- void set_initialized() { initialized_ = true; }
+ // 初期化ずみマークをつける(非推奨)
+ void set_initialized() throw () { initialized_ = true; }
+
+ // 関数を使って初期化する
+ // 初期化済みの場合は破棄してから初期化する
+ template<typename Constructor>
+ T* construct( Constructor ctor )
+ {
+ if( initialized() ){ destory(); }
+
+ construct_();
+
+ return static_cast<T*>( address() );
+ }
// 構築済みなら、構築されたオブジェクトのアドレスを取得する
typedef storage<T> storage_type;
storage_type storage_;
+ // 実装用関数
+
+ // initialized_ によらずオブジェクトを構築する( unsafe )
+ template<typename Ctor>
+ void construct_( Ctor ctor )
+ {
+ ctor( address() );
+ initialized_ = true;
+ }
+
}; // optional_storage<T>
} // namespace gintenlib