18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef META_API_FUTURE_H 178bf80f4bSopenharmony_ci#define META_API_FUTURE_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <base/containers/type_traits.h> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <meta/interface/detail/any.h> 228bf80f4bSopenharmony_ci#include <meta/interface/interface_helpers.h> 238bf80f4bSopenharmony_ci#include <meta/interface/intf_future.h> 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_ci/** 288bf80f4bSopenharmony_ci * @brief Callable implementation for continuation functions used with futures. 298bf80f4bSopenharmony_ci */ 308bf80f4bSopenharmony_citemplate<typename Func> 318bf80f4bSopenharmony_ciclass ContinuationFunction : public IntroduceInterfaces<IFutureContinuation> { 328bf80f4bSopenharmony_ci META_INTERFACE( 338bf80f4bSopenharmony_ci IntroduceInterfaces<IFutureContinuation>, ContinuationFunction, "f4736552-7365-4c8f-bbe9-a065e2c30382"); 348bf80f4bSopenharmony_ci 358bf80f4bSopenharmony_cipublic: 368bf80f4bSopenharmony_ci ContinuationFunction(Func func) : func_(BASE_NS::move(func)) {} 378bf80f4bSopenharmony_ci 388bf80f4bSopenharmony_ci IAny::Ptr Invoke(const IAny::Ptr& value) override 398bf80f4bSopenharmony_ci { 408bf80f4bSopenharmony_ci using Result = BASE_NS::remove_reference_t<decltype(func_(value))>; 418bf80f4bSopenharmony_ci if constexpr (!BASE_NS::is_same_v<Result, void>) { 428bf80f4bSopenharmony_ci return IAny::Ptr(new Any<Result>(func_(value))); 438bf80f4bSopenharmony_ci } else { 448bf80f4bSopenharmony_ci func_(value); 458bf80f4bSopenharmony_ci return nullptr; 468bf80f4bSopenharmony_ci } 478bf80f4bSopenharmony_ci } 488bf80f4bSopenharmony_ci 498bf80f4bSopenharmony_ciprivate: 508bf80f4bSopenharmony_ci Func func_; 518bf80f4bSopenharmony_ci}; 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ci/** 548bf80f4bSopenharmony_ci * @brief Create continuation function from callable entity (e.g. lambda). 558bf80f4bSopenharmony_ci * The callable entity has to take IAny::Ptr as parameter which is the value from the future. 568bf80f4bSopenharmony_ci */ 578bf80f4bSopenharmony_citemplate<typename Func> 588bf80f4bSopenharmony_ciIFutureContinuation::Ptr CreateContinuation(Func func) 598bf80f4bSopenharmony_ci{ 608bf80f4bSopenharmony_ci return IFutureContinuation::Ptr(new ContinuationFunction(BASE_NS::move(func))); 618bf80f4bSopenharmony_ci} 628bf80f4bSopenharmony_ci 638bf80f4bSopenharmony_citemplate<typename Param> 648bf80f4bSopenharmony_cistruct ContinuationTypedFuntionTypeImpl { 658bf80f4bSopenharmony_ci using Type = void(Param); 668bf80f4bSopenharmony_ci}; 678bf80f4bSopenharmony_ci 688bf80f4bSopenharmony_citemplate<> 698bf80f4bSopenharmony_cistruct ContinuationTypedFuntionTypeImpl<void> { 708bf80f4bSopenharmony_ci using Type = void(); 718bf80f4bSopenharmony_ci}; 728bf80f4bSopenharmony_ci 738bf80f4bSopenharmony_citemplate<typename Param> 748bf80f4bSopenharmony_ciusing ContinuationTypedFuntionType = typename ContinuationTypedFuntionTypeImpl<Param>::Type; 758bf80f4bSopenharmony_ci 768bf80f4bSopenharmony_citemplate<typename Type> 778bf80f4bSopenharmony_ciclass Future { 788bf80f4bSopenharmony_cipublic: 798bf80f4bSopenharmony_ci using StateType = IFuture::StateType; 808bf80f4bSopenharmony_ci 818bf80f4bSopenharmony_ci Future(IFuture::Ptr fut) : fut_(BASE_NS::move(fut)) {} 828bf80f4bSopenharmony_ci 838bf80f4bSopenharmony_ci StateType GetState() const 848bf80f4bSopenharmony_ci { 858bf80f4bSopenharmony_ci return fut_ ? fut_->GetState() : IFuture::ABANDONED; 868bf80f4bSopenharmony_ci } 878bf80f4bSopenharmony_ci StateType Wait() const 888bf80f4bSopenharmony_ci { 898bf80f4bSopenharmony_ci return fut_ ? fut_->Wait() : IFuture::ABANDONED; 908bf80f4bSopenharmony_ci } 918bf80f4bSopenharmony_ci StateType WaitFor(const TimeSpan& time) const 928bf80f4bSopenharmony_ci { 938bf80f4bSopenharmony_ci return fut_ ? fut_->WaitFor(time) : IFuture::ABANDONED; 948bf80f4bSopenharmony_ci } 958bf80f4bSopenharmony_ci IFuture::Ptr Then(const IFutureContinuation::Ptr& func, const BASE_NS::shared_ptr<ITaskQueue>& queue) 968bf80f4bSopenharmony_ci { 978bf80f4bSopenharmony_ci return fut_ ? fut_->Then(func, queue) : nullptr; 988bf80f4bSopenharmony_ci } 998bf80f4bSopenharmony_ci template<typename Func, typename = EnableIfCanInvokeWithArguments<Func, IFutureContinuation::FunctionType>> 1008bf80f4bSopenharmony_ci auto Then(Func func, const BASE_NS::shared_ptr<ITaskQueue>& queue) 1018bf80f4bSopenharmony_ci { 1028bf80f4bSopenharmony_ci return Future<decltype(func(nullptr))>(fut_->Then(CreateContinuation(func), queue)); 1038bf80f4bSopenharmony_ci } 1048bf80f4bSopenharmony_ci template<typename Func, typename = EnableIfCanInvokeWithArguments<Func, ContinuationTypedFuntionType<Type>>> 1058bf80f4bSopenharmony_ci auto Then(Func func, const BASE_NS::shared_ptr<ITaskQueue>& queue, int = 0) 1068bf80f4bSopenharmony_ci { 1078bf80f4bSopenharmony_ci using ReturnType = decltype(func(Type {})); 1088bf80f4bSopenharmony_ci return Future<ReturnType>(fut_->Then(CreateContinuation([f = BASE_NS::move(func)](const IAny::Ptr& v) { 1098bf80f4bSopenharmony_ci if (v) { 1108bf80f4bSopenharmony_ci Type value {}; 1118bf80f4bSopenharmony_ci if (v->GetValue(value)) { 1128bf80f4bSopenharmony_ci return f(value); 1138bf80f4bSopenharmony_ci } 1148bf80f4bSopenharmony_ci CORE_LOG_W("Type mismatch for future then"); 1158bf80f4bSopenharmony_ci } 1168bf80f4bSopenharmony_ci if constexpr (!BASE_NS::is_same_v<ReturnType, void>) { 1178bf80f4bSopenharmony_ci return ReturnType {}; 1188bf80f4bSopenharmony_ci } 1198bf80f4bSopenharmony_ci }), 1208bf80f4bSopenharmony_ci queue)); 1218bf80f4bSopenharmony_ci } 1228bf80f4bSopenharmony_ci 1238bf80f4bSopenharmony_ci Type GetResult() const 1248bf80f4bSopenharmony_ci { 1258bf80f4bSopenharmony_ci if (fut_) { 1268bf80f4bSopenharmony_ci return fut_->GetResultOr<Type>(Type {}); 1278bf80f4bSopenharmony_ci } 1288bf80f4bSopenharmony_ci return Type {}; 1298bf80f4bSopenharmony_ci } 1308bf80f4bSopenharmony_ci IFuture::Ptr GetFuture() const 1318bf80f4bSopenharmony_ci { 1328bf80f4bSopenharmony_ci return fut_; 1338bf80f4bSopenharmony_ci } 1348bf80f4bSopenharmony_ci 1358bf80f4bSopenharmony_ci operator IFuture::Ptr() const 1368bf80f4bSopenharmony_ci { 1378bf80f4bSopenharmony_ci return fut_; 1388bf80f4bSopenharmony_ci } 1398bf80f4bSopenharmony_ci 1408bf80f4bSopenharmony_ci explicit operator bool() const 1418bf80f4bSopenharmony_ci { 1428bf80f4bSopenharmony_ci return fut_ != nullptr; 1438bf80f4bSopenharmony_ci } 1448bf80f4bSopenharmony_ci 1458bf80f4bSopenharmony_ciprivate: 1468bf80f4bSopenharmony_ci IFuture::Ptr fut_; 1478bf80f4bSopenharmony_ci}; 1488bf80f4bSopenharmony_ci 1498bf80f4bSopenharmony_citemplate<typename Type> 1508bf80f4bSopenharmony_ciType GetResultOr(const Future<Type>& f, NonDeduced_t<Type> def) 1518bf80f4bSopenharmony_ci{ 1528bf80f4bSopenharmony_ci auto fut = f.GetFuture(); 1538bf80f4bSopenharmony_ci if (fut) { 1548bf80f4bSopenharmony_ci if (auto p = fut->GetResult()) { 1558bf80f4bSopenharmony_ci return GetValue<Type>(*p, BASE_NS::move(def)); 1568bf80f4bSopenharmony_ci } 1578bf80f4bSopenharmony_ci } 1588bf80f4bSopenharmony_ci return BASE_NS::move(def); 1598bf80f4bSopenharmony_ci} 1608bf80f4bSopenharmony_ci 1618bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_ci#endif 164