github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/3rd_party/fflib/include/ff/functionflow/para/wait_impl.h (about)

     1  /***********************************************
     2  The MIT License (MIT)
     3  
     4  Copyright (c) 2012 Athrun Arthur <athrunarthur@gmail.com>
     5  
     6  Permission is hereby granted, free of charge, to any person obtaining a copy
     7  of this software and associated documentation files (the "Software"), to deal
     8  in the Software without restriction, including without limitation the rights
     9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    10  copies of the Software, and to permit persons to whom the Software is
    11  furnished to do so, subject to the following conditions:
    12  
    13  The above copyright notice and this permission notice shall be included in
    14  all copies or substantial portions of the Software.
    15  
    16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    22  THE SOFTWARE.
    23  *************************************************/
    24  #ifndef FF_PARA_WAIT_IMPL_H_
    25  #define FF_PARA_WAIT_IMPL_H_
    26  #include "ff/functionflow/common/common.h"
    27  #include "ff/functionflow/para/bin_wait_func_deducer.h"
    28  #include "ff/functionflow/para/para.h"
    29  #include "ff/functionflow/para/paracontainer.h"
    30  #include "ff/util/tuple_type.h"
    31  
    32  namespace ff {
    33  template <class RT>
    34  class para;
    35  namespace internal {
    36  template <class T1, class T2>
    37  class wait_and {
    38   public:
    39    typedef typename std::remove_reference<T1>::type T1_t;
    40    typedef typename std::remove_reference<T2>::type T2_t;
    41    typedef typename T1_t::ret_type RT1_t;
    42    typedef typename T2_t::ret_type RT2_t;
    43    typedef bin_wait_func_deducer<typename T1_t::ret_type,
    44                                  typename T2_t::ret_type> deduct_t;
    45    typedef typename deduct_t::and_type ret_type;
    46  
    47   public:
    48    wait_and(T1&& t1, T2&& t2) : m_1(t1), m_2(t2), m_iES(exe_state::exe_init) {}
    49  
    50    template <class FT>
    51    auto then(FT &&f) -> typename std::enable_if<
    52        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
    53            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and &&
    54            !util::function_args_traits<FT>::is_no_args,
    55        void>::type {
    56      if (!check_if_over()) {
    57        ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
    58      }
    59      deduct_t::void_func_and(std::forward<FT>(f), m_1, m_2);
    60    }
    61  
    62    template <class FT>
    63    auto then(FT &&f) -> typename std::enable_if<
    64        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
    65            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and &&
    66            !util::function_args_traits<FT>::is_no_args,
    67        typename std::remove_reference<
    68            typename function_res_traits<FT>::ret_type>::type>::type {
    69      if (!check_if_over())
    70        ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
    71      return deduct_t::ret_func_and(std::forward<FT>(f), m_1, m_2);
    72    }
    73  
    74    template <class FT>
    75    auto then(FT &&f) -> typename std::enable_if<
    76        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
    77            util::function_args_traits<FT>::is_no_args,
    78        void>::type {
    79      bool b = check_if_over();
    80      if (!b)
    81        ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
    82      f();
    83    }
    84  
    85    template <class FT>
    86    auto then(FT &&f) -> typename std::enable_if<
    87        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
    88            util::function_args_traits<FT>::is_no_args,
    89        typename std::remove_reference<
    90            typename function_res_traits<FT>::ret_type>::type>::type {
    91      bool b = check_if_over();
    92      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
    93      return f();
    94    }
    95  
    96    template <class FT>
    97    auto then(FT &&f) -> typename std::enable_if<
    98        !util::function_args_traits<FT>::is_no_args &&
    99            !is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and,
   100        typename std::remove_reference<
   101            typename function_res_traits<FT>::ret_type>::type>::type {
   102      static_assert(Please_Check_The_Assert_Msg<FT>::value,
   103                    FF_EM_THEN_FUNC_TYPE_MISMATCH);
   104    }
   105  
   106    template <class FT>
   107    auto internal_then(FT &&f) -> typename std::enable_if<
   108        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   109            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and &&
   110            !util::function_args_traits<FT>::is_no_args,
   111        void>::type {
   112      deduct_t::void_func_and(std::forward<FT>(f), m_1, m_2);
   113    }
   114  
   115    template <class FT>
   116    auto internal_then(FT &&f) -> typename std::enable_if<
   117        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   118            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_and &&
   119            !util::function_args_traits<FT>::is_no_args,
   120        typename std::remove_reference<
   121            typename function_res_traits<FT>::ret_type>::type>::type {
   122      return deduct_t::ret_func_and(std::forward<FT>(f), m_1, m_2);
   123    }
   124  
   125    template <class FT>
   126    auto internal_then(FT &&f) -> typename std::enable_if<
   127        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   128            util::function_args_traits<FT>::is_no_args,
   129        void>::type {
   130      f();
   131    }
   132  
   133    template <class FT>
   134    auto internal_then(FT &&f) -> typename std::enable_if<
   135        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   136            util::function_args_traits<FT>::is_no_args,
   137        typename std::remove_reference<
   138            typename function_res_traits<FT>::ret_type>::type>::type {
   139      return f();
   140    }
   141  
   142    auto get() -> typename deduct_t::and_type {
   143      return deduct_t::wrap_ret_for_and(m_1, m_2);
   144    }
   145  
   146    exe_state get_state() {
   147      if (m_iES != exe_state::exe_over)
   148        m_iES = exe_state_and(m_1.get_state(), m_2.get_state());
   149      return m_iES;
   150    }
   151    bool check_if_over() {
   152      if (m_iES == exe_state::exe_over) return true;
   153      m_iES = exe_state_and(m_1.get_state(), m_2.get_state());
   154      if (m_iES == exe_state::exe_over) return true;
   155      return false;
   156    }
   157  
   158   protected:
   159    T1_t m_1;
   160    T2_t m_2;
   161    exe_state m_iES;
   162  };  // end class wait_and
   163  
   164  template <class T1, class T2>
   165  class wait_or {
   166   public:
   167    typedef typename std::remove_reference<T1>::type T1_t;
   168    typedef typename std::remove_reference<T2>::type T2_t;
   169    typedef typename T1_t::ret_type RT1_t;
   170    typedef typename T2_t::ret_type RT2_t;
   171    typedef bin_wait_func_deducer<typename T1_t::ret_type,
   172                                  typename T2_t::ret_type> deduct_t;
   173    typedef typename deduct_t::or_type ret_type;
   174  
   175   public:
   176    wait_or(T1&& t1, T2&& t2) : m_1(t1), m_2(t2), m_iES(exe_state::exe_init) {}
   177  
   178    template <class FT>
   179    auto then(FT &&f) -> typename std::enable_if<
   180        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   181            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or &&
   182            !util::function_args_traits<FT>::is_no_args,
   183        void>::type {
   184      bool b = check_if_over();
   185      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   186      deduct_t::void_func_or(std::forward<FT>(f), m_1, m_2);
   187    }
   188  
   189    template <class FT>
   190    auto then(FT &&f) -> typename std::enable_if<
   191        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   192            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or &&
   193            !util::function_args_traits<FT>::is_no_args,
   194        typename std::remove_reference<
   195            typename function_res_traits<FT>::ret_type>::type>::type {
   196      bool b = check_if_over();
   197      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   198      return deduct_t::ret_func_or(std::forward<FT>(f), m_1, m_2);
   199    }
   200  
   201    template <class FT>
   202    auto then(FT &&f) -> typename std::enable_if<
   203        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   204            util::function_args_traits<FT>::is_no_args,
   205        void>::type {
   206      bool b = check_if_over();
   207      if (!b)
   208        ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   209      f();
   210    }
   211  
   212    template <class FT>
   213    auto then(FT &&f) -> typename std::enable_if<
   214        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   215            util::function_args_traits<FT>::is_no_args,
   216        typename std::remove_reference<
   217            typename function_res_traits<FT>::ret_type>::type>::type {
   218      bool b = check_if_over();
   219      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   220      return f();
   221    }
   222  
   223    template <class FT>
   224    auto then(FT &&f) -> typename std::enable_if<
   225        !util::is_no_args_function<FT>::value &&
   226            !is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or,
   227        typename std::remove_reference<
   228            typename function_res_traits<FT>::ret_type>::type>::type {
   229      static_assert(Please_Check_The_Assert_Msg<FT>::value,
   230                    FF_EM_THEN_FUNC_TYPE_MISMATCH);
   231    }
   232  
   233    template <class FT>
   234    auto internal_then(FT &&f) -> typename std::enable_if<
   235        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   236            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or &&
   237            !util::function_args_traits<FT>::is_no_args,
   238        void>::type {
   239      deduct_t::void_func_or(std::forward<FT>(f), m_1, m_2);
   240    }
   241  
   242    template <class FT>
   243    auto internal_then(FT &&f) -> typename std::enable_if<
   244        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   245            is_compatible_then<FT, RT1_t, RT2_t>::is_cpt_with_or &&
   246            !util::function_args_traits<FT>::is_no_args,
   247        typename std::remove_reference<
   248            typename function_res_traits<FT>::ret_type>::type>::type {
   249      return deduct_t::ret_func_or(std::forward<FT>(f), m_1, m_2);
   250    }
   251  
   252    template <class FT>
   253    auto internal_then(FT &&f) -> typename std::enable_if<
   254        std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   255            util::function_args_traits<FT>::is_no_args,
   256        void>::type {
   257      f();
   258    }
   259  
   260    template <class FT>
   261    auto internal_then(FT &&f) -> typename std::enable_if<
   262        !std::is_void<typename function_res_traits<FT>::ret_type>::value &&
   263            util::function_args_traits<FT>::is_no_args,
   264        typename std::remove_reference<
   265            typename function_res_traits<FT>::ret_type>::type>::type {
   266      return f();
   267    }
   268  
   269    auto get() -> typename deduct_t::or_type {
   270      return deduct_t::wrap_ret_for_or(m_1, m_2);
   271    }
   272  
   273    exe_state get_state() {
   274      if (m_iES != exe_state::exe_over)
   275        m_iES = exe_state_or(m_1.get_state(), m_2.get_state());
   276      return m_iES;
   277    }
   278    bool check_if_over() {
   279      if (m_iES == exe_state::exe_over) return true;
   280      m_iES = exe_state_or(m_1.get_state(), m_2.get_state());
   281      if (m_iES == exe_state::exe_over) return true;
   282      return false;
   283    }
   284  
   285   protected:
   286    T1_t m_1;
   287    T2_t m_2;
   288    exe_state m_iES;
   289  };  // end class wait_or
   290  
   291  class wait_all {
   292   public:
   293    typedef void ret_type;
   294    wait_all(std::shared_ptr<::ff::internal::paras_with_lock> ps);
   295  
   296    template <class FT>
   297    auto then(FT&& f) -> void {
   298      bool b = check_if_over();
   299      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   300      f();
   301    }
   302  
   303    exe_state get_state();
   304    bool check_if_over();
   305  
   306   protected:
   307     std::shared_ptr<::ff::internal::paras_with_lock> all_ps;
   308     exe_state m_iES;
   309  };  // end class wait_all
   310  
   311  class wait_any {
   312   public:
   313    typedef void ret_type;
   314    wait_any(std::shared_ptr<::ff::internal::paras_with_lock> ps);
   315  
   316    template <class FT>
   317    auto then(FT&& f) -> void {
   318      bool b = check_if_over();
   319      if (!b) ::ff::rt::yield_and_ret_until([this]() { return check_if_over(); });
   320      f();
   321    }
   322    exe_state get_state();
   323    bool check_if_over();
   324  
   325   protected:
   326     std::shared_ptr<::ff::internal::paras_with_lock> all_ps;
   327     exe_state m_iES;
   328  };  // end class wait_any
   329  
   330  }  // end namespace internal
   331  }  // end namespace ff
   332  
   333  #endif