MPLtop

#define BOOST_NO_RVALUE_REFERENCES 
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/none.hpp>

 namespace boost_util {
 
   // タイプが参照型ならtrueを返すMPL
   template <typename T> struct is_reference { static const bool value_type = false; };
   template <typename T> struct is_reference<T&> { static const bool value_type = true; };
 
 
   // boost optionalもどき用。リファレンス型時の型定義
   // 保存はポインタ型
   template <typename RefT>
   struct optional_ref {
       typedef typename boost::remove_reference<RefT>::type NoRefT;
       typedef RefT          ref_t;
       typedef NoRefT const& cref_t;
       typedef NoRefT*       ptr_t;
       typedef NoRefT const* cptr_t;
       typedef ptr_t   value_t; // valueはポインタ
       static ptr_t   initializer(ref_t val)     { return &val; }   // value_t型でvalueを得る。コンストラクタの初期化用
       static ptr_t   get_value_ptr(value_t val) { return val; }  // valueのポインタを得る
       static cref_t  get_value_cref(cptr_t val) { return *val; }       
       static value_t get_invalid_value()        { return 0; } // 無効時の値
   };
   // boost optionalもどき用。通常時の型定義
   // 保存は実体
   template <typename NoRefT>
   struct optional_noref {
       typedef NoRefT&       ref_t;
       typedef NoRefT const& cref_t;
       typedef NoRefT*       ptr_t;
       typedef NoRefT const* cptr_t;
       typedef NoRefT  value_t; // valueは実体
       static cref_t  initializer(cref_t val)     { return val; }      // value_t型でvalueを得る。コンストラクタの初期化用
       static ptr_t   get_value_ptr(value_t& val) { return &val; }     // valueのポインタを得る
       static cref_t  get_value_cref(cref_t val)  { return val; }      // valueのconst 参照を得る  
       static value_t get_invalid_value()         { return NoRefT(); } // 無効時の値
   };

   // boost optionalもどき。実装クラス
   template <typename OptTypeDef> 
   struct optional_impl {
       typedef typename OptTypeDef::ref_t ref_t;
       typedef typename OptTypeDef::cref_t cref_t;
       typedef typename OptTypeDef::ptr_t ptr_t;
       typedef typename OptTypeDef::cptr_t cptr_t;
       typedef typename OptTypeDef::value_t value_t;
       value_t value_;  // 保持する値
       bool valid_;
       optional_impl(ref_t val) : value_(OptTypeDef::initializer(val)), valid_(true) {}
       optional_impl(boost::none_t) : value_(OptTypeDef::get_invalid_value()), valid_(false) {}
       operator bool () const { return valid_; }
       ptr_t  get_ptr()       { return OptTypeDef::get_value_ptr(value_); }
       cptr_t get_ptr() const { return OptTypeDef::get_value_ptr(value_); }
       ref_t  get()           { return *OptTypeDef::get_value_ptr(value_); }
       cref_t get() const     { return OptTypeDef::get_value_cref(value_); }
   };


   // boost optionalもどき。
   template <typename UT>
   struct optional {
       // UTが参照型か否かでクラスを切り分ける
       typedef typename
           boost::mpl::if_c< is_reference<UT>::value_type
                           , optional_ref<UT>
                           , optional_noref<UT> >::type type;
       typedef typename type::ptr_t ptr_t;
       typedef typename type::cptr_t cptr_t;
       typedef typename type::ref_t ref_t;
       typedef typename type::cref_t cref_t;
       // 実装はoptional_implに委譲
       optional_impl<type> impl_;
       // コンストラクタ
       optional(UT val) : impl_(val) {}
       // コンストラクタ(nil)
       optional(boost::none_t n = 0) : impl_(n) {}
       // 実装
       operator bool() const       { return impl_; }
       ptr_t  operator -> ()       { return impl_.get_ptr(); }
       ptr_t  get_ptr()            { return impl_.get_ptr(); }
       ref_t  get()                { return impl_.get(); }
       ref_t  operator * ()        { return impl_.get(); }
       cptr_t operator -> () const { return impl_.get_ptr(); }
       cptr_t get_ptr()      const { return impl_.get_ptr(); }
       cref_t get() const          { return impl_.get(); }
       cref_t operator * () const  { return impl_.get(); }
       cref_t get_value_or(cref_t def) const { if (impl_) return get(); else return def; }

   };

 }

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-07-01 (金) 19:02:09 (2491d)