blob: df1323e8be9c120abd4b7487cbe03972422dace8 [file] [log] [blame]
Dominik Laskowskib17c6212022-05-09 09:36:19 -07001/*
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
19namespace android::ftl {
20
21template <typename, template <typename> class>
22class Future;
23
24namespace details {
25
26template <typename T>
27struct future_result {
28 using type = T;
29};
30
31template <typename T>
32struct future_result<std::future<T>> {
33 using type = T;
34};
35
36template <typename T>
37struct future_result<std::shared_future<T>> {
38 using type = T;
39};
40
41template <typename T, template <typename> class FutureImpl>
42struct future_result<Future<T, FutureImpl>> {
43 using type = T;
44};
45
46template <typename T>
47using future_result_t = typename future_result<T>::type;
48
49struct ValueTag {};
50
51template <typename, typename T, template <typename> class>
52class BaseFuture;
53
54template <typename Self, typename T>
55class 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
80template <typename Self, typename T>
81class 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