1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 namespace android::ftl { 20 21 template <typename, template <typename> class> 22 class Future; 23 24 namespace details { 25 26 template <typename T> 27 struct future_result { 28 using type = T; 29 }; 30 31 template <typename T> 32 struct future_result<std::future<T>> { 33 using type = T; 34 }; 35 36 template <typename T> 37 struct future_result<std::shared_future<T>> { 38 using type = T; 39 }; 40 41 template <typename T, template <typename> class FutureImpl> 42 struct future_result<Future<T, FutureImpl>> { 43 using type = T; 44 }; 45 46 template <typename T> 47 using future_result_t = typename future_result<T>::type; 48 49 struct ValueTag {}; 50 51 template <typename, typename T, template <typename> class> 52 class BaseFuture; 53 54 template <typename Self, typename T> 55 class BaseFuture<Self, T, std::future> { 56 using Impl = std::future<T>; 57 58 public: 59 Future<T, std::shared_future> share() { 60 if (T* value = std::get_if<T>(&self())) { 61 return {ValueTag{}, std::move(*value)}; 62 } 63 64 return std::get<Impl>(self()).share(); 65 } 66 67 protected: 68 T get() { 69 if (T* value = std::get_if<T>(&self())) { 70 return std::move(*value); 71 } 72 73 return std::get<Impl>(self()).get(); 74 } 75 76 private: 77 auto& self() { return static_cast<Self&>(*this).future_; } 78 }; 79 80 template <typename Self, typename T> 81 class BaseFuture<Self, T, std::shared_future> { 82 using Impl = std::shared_future<T>; 83 84 protected: 85 const T& get() const { 86 if (const T* value = std::get_if<T>(&self())) { 87 return *value; 88 } 89 90 return std::get<Impl>(self()).get(); 91 } 92 93 private: 94 const auto& self() const { return static_cast<const Self&>(*this).future_; } 95 }; 96 97 } // namespace details 98 } // namespace android::ftl 99