[[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