github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/3rd_party/fflib/include/ff/functionflow/para/para.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 #pragma once 25 #include "ff/functionflow/common/common.h" 26 #include "ff/functionflow/para/bin_wait_func_deducer.h" 27 #include "ff/functionflow/para/exception.h" 28 #include "ff/functionflow/para/is_wait_compatible_with_then.h" 29 #include "ff/functionflow/para/para_helper.h" 30 #include "ff/functionflow/para/para_impl.h" 31 #include "ff/functionflow/para/para_wait_traits.h" 32 #include "ff/functionflow/runtime/rtcmn.h" 33 #include "ff/util/function_traits.h" 34 35 namespace ff { 36 37 using namespace ff::util; 38 namespace internal { 39 template <typename DT, typename RT> 40 class para_common { 41 public: 42 typedef RT ret_type; 43 44 public: 45 #include "ff/functionflow/para/para_accepted_wait.h" 46 para_common() : m_pImpl(nullptr){}; 47 ~para_common() {} 48 template <class WT> 49 auto operator[](WT &&cond) -> typename std::enable_if< 50 is_para_or_wait<typename std::remove_reference<WT>::type>::value, 51 para_accepted_wait<DT, WT>>::type { 52 if (cond.get_state() == exe_state::exe_empty) 53 throw empty_para_exception(); 54 return para_accepted_wait<DT, WT>(*(static_cast<DT *>(this)), 55 std::forward<WT>(cond)); 56 } 57 template <class WT> 58 auto operator[](WT &&cond) -> typename std::enable_if< 59 !is_para_or_wait<typename std::remove_reference<WT>::type>::value, 60 para_accepted_wait<DT, para<void>>>::type { 61 static_assert(Please_Check_The_Assert_Msg<WT>::value, 62 FF_EM_WRONG_USE_SQPAREN); 63 } 64 template <class F> auto exe(F &&f) -> para_accepted_call<DT, ret_type> { 65 if (m_pImpl) 66 throw used_para_exception(); 67 auto pp = make_para_impl<ret_type>(std::forward<F>(f)); 68 m_pImpl = std::dynamic_pointer_cast<para_impl_base<ret_type>>(pp); 69 schedule(m_pImpl); 70 return para_accepted_call<DT, ret_type>(*(static_cast<DT *>(this))); 71 } 72 template <class F> 73 auto operator()(F &&f) -> typename std::enable_if< 74 std::is_same<typename ::ff::util::function_res_traits<F>::ret_type, 75 ret_type>::value, 76 para_accepted_call<DT, ret_type>>::type { 77 return exe(std::forward<F>(f)); 78 } 79 80 template <class F> 81 auto operator()(F &&f) -> typename std::enable_if< 82 !std::is_same<typename ::ff::util::function_res_traits<F>::ret_type, 83 ret_type>::value, 84 para_accepted_call<DT, ret_type>>::type { 85 static_assert(Please_Check_The_Assert_Msg<F>::value, 86 FF_EM_CALL_WITH_TYPE_MISMATCH); 87 } 88 exe_state get_state() { 89 if (m_pImpl) 90 return m_pImpl->get_state(); 91 return exe_state::exe_empty; 92 } 93 bool check_if_over() { 94 if (m_pImpl) 95 return m_pImpl->check_if_over(); 96 return false; 97 } 98 99 ::ff::internal::para_impl_base_ptr<ret_type> get_internal_impl() { 100 return m_pImpl; 101 } 102 103 template <class F> void then(const F &) { 104 static_assert(Please_Check_The_Assert_Msg<F>::value, 105 FF_EM_CALL_THEN_WITHOUT_CALL_PAREN); 106 } 107 108 protected: 109 ::ff::internal::para_impl_base_ptr<ret_type> m_pImpl; 110 }; // end class para_common 111 112 } // end namespace internal 113 114 template <typename RT = void> 115 class para : public ::ff::internal::para_common<para<RT>, RT> { 116 public: 117 typedef RT ret_type; 118 auto get() -> typename std::enable_if<!std::is_void<RT>::value, RT>::type & { 119 return ::ff::internal::para_common<para<RT>, RT>::m_pImpl->get(); 120 } 121 template <class FT> 122 auto internal_then(FT &&f) -> typename std::enable_if< 123 std::is_void<typename function_res_traits<FT>::ret_type>::value && 124 is_function_with_arg_type<FT, ret_type>::value, 125 void>::type { 126 f(m_pImpl->get()); 127 } 128 129 template <class FT> 130 auto internal_then(FT &&f) -> typename std::enable_if< 131 is_function_with_arg_type<FT, RT>::value, 132 typename std::remove_reference< 133 typename function_res_traits<FT>::ret_type>::type &&>::type { 134 return std::move(f(m_pImpl->get())); 135 } 136 137 protected: 138 using ::ff::internal::para_common<para<RT>, RT>::m_pImpl; 139 }; // end class para; 140 141 template <> 142 class para<void> : public ::ff::internal::para_common<para<void>, void> { 143 public: 144 typedef void ret_type; 145 template <class FT> 146 auto internal_then(FT &&f) -> typename std::enable_if< 147 std::is_void<typename function_res_traits<FT>::ret_type>::value && 148 is_function_with_arg_type<FT, void>::value, 149 void>::type { 150 f(); 151 } 152 153 template <class FT> 154 auto internal_then(FT &&f) -> typename std::enable_if< 155 is_function_with_arg_type<FT, void>::value && 156 !std::is_void<typename function_res_traits<FT>::ret_type>::value, 157 typename std::remove_reference< 158 typename function_res_traits<FT>::ret_type>::type>::type { 159 return f(); 160 } 161 }; // end class para; 162 163 template <class T> 164 class para<para<T>> { 165 public: 166 para() { 167 static_assert(Please_Check_The_Assert_Msg<para<T>>::value, 168 FF_EM_CALL_NO_SUPPORT_FOR_PARA); 169 }; 170 }; // end class para; 171 172 } // end namespace ff