<dfn id="7pnvb"><del id="7pnvb"><form id="7pnvb"></form></del></dfn>

      <form id="7pnvb"></form>

        <b id="7pnvb"><strike id="7pnvb"></strike></b>

          <form id="7pnvb"></form>
          現在的位置: 首頁 > 黃專家專欄 > 正文

          Boost – Function 分析

          2014年10月30日 黃專家專欄 ⁄ 共 7168字 ⁄ 字號 評論關閉

          本文假設了解 boost::function 相關用法

          首先需要包含的頭文件為 boost/function.hpp

          里面內容比較簡單

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          #  if BOOST_FUNCTION_MAX_ARGS >= 0
          #    include <boost/function/function0.hpp>
          #  endif
          #  if BOOST_FUNCTION_MAX_ARGS >= 1
          #    include <boost/function/function1.hpp>
          # endif
          #  if BOOST_FUNCTION_MAX_ARGS >= 2
          #    include <boost/function/function2.hpp>
          #  endif
          #  if BOOST_FUNCTION_MAX_ARGS >= 3
          #    include <boost/function/function3.hpp>
          #  endif
          ... ...

          默認的 BOOST_FUNCTION_MAX_ARGS 為 10,說明最大支持為10個參數

          那么,可以知道引入了function0 ~ function10 共11個文件

          第N個文件都是定義了支持 N 個參數的 function 類

          我們以參數 BOOST_FUNCTION_MAX_ARGS = 4 來看看定義

          boost/function/function4.hpp 頭文件里只有這樣幾行

          1
          2
          3
          #define BOOST_FUNCTION_NUM_ARGS 4
          #include <boost/function/detail/maybe_include.hpp>
          #undef BOOST_FUNCTION_NUM_ARGS

          boost/function/detail/maybe_include.hpp 里面其實就定義了 BOOST_FUNCTION_N

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          #if BOOST_FUNCTION_NUM_ARGS == 0
          #  ifndef BOOST_FUNCTION_0
          #    define BOOST_FUNCTION_0
          #    include <boost/function/function_template.hpp>
          #  endif
          #elif BOOST_FUNCTION_NUM_ARGS == 1
          #  ifndef BOOST_FUNCTION_1
          #    define BOOST_FUNCTION_1
          #    include <boost/function/function_template.hpp>
          #  endif
          #elif BOOST_FUNCTION_NUM_ARGS == 2
          #  ifndef BOOST_FUNCTION_2
          #    define BOOST_FUNCTION_2
          #    include <boost/function/function_template.hpp>
          #  endif
          ... ...

          boost/function/function_template.hpp 首先看兩個宏定義

          1
          2
          #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
          #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)

          BOOST_FUNCTION_NUM_ARGS 就是當前文件支持的參數個數,當前是4 BOOST_FUNCTION_TEMPLATE_PARMS 是宏自身擴展,展開時可能如下:

          1
          2
          3
          4
          #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
            // typename T0 , typename T1 , typename T2 , typename T3
            // 同樣 BOOST_FUNCTION_TEMPLATE_ARGS 展開如下
            // T0 , T1 , T2 , T3

          可以看到,我們用宏展開后的結果,function里都是一些構造函數和賦值函數,所以應該主要工作都在基類中

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          template<typename R , typename T0 , typename T1 , typename T2 , typename T3>
          class function<R ( T0 , T1 , T2 , T3)> : public function4<R , T0 , T1 , T2 , T3> {
            typedef function4<R , T0 , T1 , T2 , T3> base_type;
            typedef function self_type;
            struct clear_type {};
            public:
            function() : base_type() {}
          
            // 模板的 sfinae 原則,避免整數被選入
            template<typename Functor>
              function(Functor f,
                  typename enable_if_c<
                  (boost::type_traits::ice_not<
                   (is_integral<Functor>::value)>::value),
                  int>::type = 0) : base_type(f) {}
            template<typename Functor,typename Allocator>
          
              // 同上
              function(Functor f, Allocator a,
                  typename enable_if_c<(
                    boost::type_traits::ice_not<(
                      is_integral<Functor>::value)>::value),int>::type = 0) :
                base_type(f,a) {}
            function(clear_type*) : base_type() {}
            function(const self_type& f) : base_type(static_cast<const base_type&>(f)) {}
            function(const base_type& f) : base_type(static_cast<const base_type&>(f)) {}
            self_type& operator=(const self_type& f) {
              self_type(f).swap(*this);
              return *this;
            }
            template<typename Functor>
              typename enable_if_c<(boost::type_traits::ice_not<
                  (is_integral<Functor>::value)>::value),
                       self_type&>::type
                         operator=(Functor f) {
                           self_type(f).swap(*this);
                           return *this;
                         }
            self_type& operator=(clear_type*) {
              this->clear();
              return *this;
            }
            self_type& operator=(const base_type& f) {
              self_type(f).swap(*this);
              return *this;
            }
          }

          所看看它基類的內容

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          template<typename R , typename T0 , typename T1 , typename T2 , typename T3>
          class function4 : public function_base
          {
            public:
              typedef R result_type;
              typedef boost::detail::function::basic_vtable4<R , T0 , T1 , T2 , T3> vtable_type;
          
              struct clear_type {};
              template<typename Functor>
                function4(Functor f,
                    typename enable_if_c<(boost::type_traits::ice_not<
                      (is_integral<Functor>::value)>::value), int>::type = 0) {
                  this->assign_to(f);
                }
          
              // 主要賦值在這個函數
              template<typename Functor>
                void assign_to(Functor f) {
                  using detail::function::vtable_base;
          
                  // 以下兩行是得到 Functor 的類型
                  // 這個是由 tag 做萃取器的
                  typedef typename detail::function::get_function_tag<Functor>::type tag;
                  typedef detail::function::get_invoker4<tag> get_invoker;
                  typedef typename handler_type::invoker_type invoker_type;
                  typedef typename get_invoker::template apply<Functor, R ,T0 , T1 , T2 , T3> handler_type;
          
                  // vtable_type 負責實際 Functor 映射到內部 function_buffer 的管理
                  // 這里之所以用靜態的是因為同一種類型的 assign_to都是一樣的策略
                  // 不同 Functor 自然生成不同的 assign_to,那么 stored_vtable 也自然不同了
                  static vtable_type stored_vtable =
                  { { &manager_type::manage }, &invoker_type::invoke };
                  if (stored_vtable.assign_to(f, functor)) {
                    std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
                    if (boost::has_trivial_copy_constructor<Functor>::value &&
                        boost::has_trivial_destructor<Functor>::value &&
                        detail::function::function_allows_small_object_optimization<Functor>::value) {
                      value |= (std::size_t)0x01;
                      vtable = reinterpret_cast<detail::function::vtable_base *>(value);
                    } else {
                      vtable = 0;
                    }
                  }
                }
              ... ...
          }

          上面看有兩個成員變量是比較重要的,一個是 vtable, 一個是 function

          他們都在基類 function_base 中被描述

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          class function_base {
            ... ...
              detail::function::vtable_base* vtable;
            // 真正存儲的指針
            mutable detail::function::function_buffer functor;
          };
          
          union function_buffer {
            mutable void* obj_ptr;  // 對象指針類型
            mutable void (*func_ptr)(); // 函數指針類型
          
            // 指針本身的類型, 比如是const約束? volite約束?
            struct type_t {
              const detail::sp_typeinfo* type;
              bool const_qualified;
              bool volatile_qualified;
            } type;
          
            // 成員函數指針的結構
            struct bound_memfunc_ptr_t {
              void (X::*memfunc_ptr)(int);
              void* obj_ptr;
            } bound_memfunc_ptr;
          
            // 對象引用類型
            struct obj_ref_t {
              mutable void* obj_ptr;
              bool is_const_qualified;
              bool is_volatile_qualified;
            } obj_ref;
          
            // 小函數對象的優化
            // 如果是小函數對象,那么直接構造在這個 union 上
            mutable char data;
          };
          
          // 這個是干嘛用的現在還不清楚
          struct vtable_base {
            void (*manager)(const function_buffer& in_buffer,
                function_buffer& out_buffer,
                functor_manager_operation_type op);
          };

          萃取器的 tag 代碼如下

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          struct function_ptr_tag {};
          struct function_obj_tag {};
          struct member_ptr_tag {};
          struct function_obj_ref_tag {};
          
          template<typename F>
          class get_function_tag {
            // 這是個依次迭代的關系
            // 巧妙啊,這樣解決了定義 type 為不同類型的問題
            // 其實是一個 if-else 的編譯期選擇綁定
            typedef typename mpl::if_c<(is_pointer<F>::value),
                    function_ptr_tag,
                    function_obj_tag>::type ptr_or_obj_tag;
            typedef typename mpl::if_c<(is_member_pointer<F>::value),
                    member_ptr_tag,
                    ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
            typedef typename mpl::if_c<(is_reference_wrapper<F>::value),
                    function_obj_ref_tag,
                    ptr_or_obj_or_mem_tag>::type or_ref_tag;
            public:
            typedef or_ref_tag type;
          };
          
          // vtable_type 大概代碼如下
          typedef boost::detail::function::basic_vtable0<R> vtable_type;
          template<typename R >
          struct basic_vtable4
          {
            template<typename F>
              bool assign_to(F f, function_buffer& functor) {
                typedef typename get_function_tag<F>::type tag;
                return assign_to(f, functor, tag());
              }
          
            // 以下重載了幾種 tag
            // 普通指針對象
            template<typename FunctionPtr>
              bool assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) {
                this->clear(functor);
                if (f) {
                  // 普通函數指針都是轉換成 (void (*)())(f) 指針
                  functor.func_ptr = (void (*)())(f);
                  return true;
                } else {
                  return false;
                }
              }
          
            // 仿函數對象
            template<typename FunctionObj>
              bool assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) {
                if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
                  // 小對象優化
                  assign_functor(f, functor,
                      mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
                  return true;
                } else {
                  return false;
                }
              }
          
            // 具體的小對象優化
            template<typename FunctionObj>
              void assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) {
                functor.obj_ptr = new FunctionObj(f);
              }
          
            template<typename FunctionObj>
              void assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) {
                new ((void*)&functor.data) FunctionObj(f);
              }
          };

          最后調用一目了然了

          1
          2
          3
          4
          5
          6
          inline function4<R , T0 , T1 , T2 , T3>::operator()( T0 a0 , T1 a1 , T2 a2 , T3 a3) const {
            if (this->empty())
              boost::throw_exception(bad_function_call());
            return get_vtable()->invoker
              (this->functor , a0 , a1 , a2 , a3);
          }

          抱歉!評論已關閉.

          新婚之夜我被十几个男人一起_60歳の熟女セックス_肚兜下的浑圆被揉捏np_漂亮的小峓子4在钱免费

              <dfn id="7pnvb"><del id="7pnvb"><form id="7pnvb"></form></del></dfn>

              <form id="7pnvb"></form>

                <b id="7pnvb"><strike id="7pnvb"></strike></b>

                  <form id="7pnvb"></form>