1 //  Copyright (c) 2007-2017 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(HPX_TRAITS_FUTURE_ACCESS_JUN_24_2015_0930AM)
7 #define HPX_TRAITS_FUTURE_ACCESS_JUN_24_2015_0930AM
8 
9 #include <hpx/config.hpp>
10 #include <hpx/traits/future_traits.hpp>
11 
12 #include <boost/intrusive_ptr.hpp>
13 
14 #include <type_traits>
15 #include <utility>
16 #include <vector>
17 
18 namespace hpx { namespace lcos
19 {
20     template <typename R> class future;
21     template <typename R> class shared_future;
22 
23     namespace detail
24     {
25         template <typename Result> struct future_data_base;
26     }
27 }}
28 
29 namespace hpx { namespace traits
30 {
31     ///////////////////////////////////////////////////////////////////////////
32     namespace detail
33     {
34         struct future_data_void {};
35 
36         template <typename Result>
37         struct shared_state_ptr_result
38         {
39             typedef Result type;
40         };
41 
42         template <typename Result>
43         struct shared_state_ptr_result<Result&>
44         {
45             typedef Result& type;
46         };
47 
48         template <>
49         struct shared_state_ptr_result<void>
50         {
51             typedef future_data_void type;
52         };
53 
54         template <typename R>
55         struct shared_state_ptr
56         {
57             typedef typename shared_state_ptr_result<R>::type result_type;
58             typedef boost::intrusive_ptr<
59                 lcos::detail::future_data_base<result_type>>
60                 type;
61         };
62 
63         template <typename Future, typename Enable = void>
64         struct shared_state_ptr_for
65           : shared_state_ptr<typename traits::future_traits<Future>::type>
66         {};
67 
68         template <typename Future>
69         struct shared_state_ptr_for<Future const>
70           : shared_state_ptr_for<Future>
71         {};
72 
73         template <typename Future>
74         struct shared_state_ptr_for<Future&>
75           : shared_state_ptr_for<Future>
76         {};
77 
78         template <typename Future>
79         struct shared_state_ptr_for<Future &&>
80           : shared_state_ptr_for<Future>
81         {};
82 
83         template <typename Future>
84         struct shared_state_ptr_for<std::vector<Future> >
85         {
86             typedef std::vector<
87                     typename shared_state_ptr_for<Future>::type
88                 > type;
89         };
90 
91         ///////////////////////////////////////////////////////////////////////
92         template <typename SharedState, typename Allocator>
93         struct shared_state_allocator;
94     }
95 
96     ///////////////////////////////////////////////////////////////////////////
97     template <typename T, typename Enable = void>
98     struct is_shared_state
99       : std::false_type
100     {};
101 
102     template <typename R>
103     struct is_shared_state<
104             boost::intrusive_ptr<lcos::detail::future_data_base<R> > >
105       : std::true_type
106     {};
107 
108     ///////////////////////////////////////////////////////////////////////////
109     namespace detail
110     {
111         template <typename T, typename Enable = void>
112         struct future_access_customization_point;
113     }
114 
115     template <typename T>
116     struct future_access
117       : detail::future_access_customization_point<T>
118     {};
119 
120     template <typename R>
121     struct future_access<lcos::future<R> >
122     {
123         template <typename SharedState>
124         static lcos::future<R>
createhpx::traits::future_access125         create(boost::intrusive_ptr<SharedState> const& shared_state)
126         {
127             return lcos::future<R>(shared_state);
128         }
129 
130         template <typename T = void>
131         static lcos::future<R>
createhpx::traits::future_access132         create(typename detail::shared_state_ptr_for<
133             lcos::future<lcos::future<R>>>::type const& shared_state)
134         {
135             return lcos::future<lcos::future<R>>(shared_state);
136         }
137 
138         template <typename SharedState>
createhpx::traits::future_access139         static lcos::future<R> create(
140             boost::intrusive_ptr<SharedState>&& shared_state)
141         {
142             return lcos::future<R>(std::move(shared_state));
143         }
144 
145         template <typename T = void>
createhpx::traits::future_access146         static lcos::future<R> create(typename detail::shared_state_ptr_for<
147             lcos::future<lcos::future<R>>>::type&& shared_state)
148         {
149             return lcos::future<lcos::future<R>>(std::move(shared_state));
150         }
151 
152         template <typename SharedState>
153         static lcos::future<R>
createhpx::traits::future_access154         create(SharedState* shared_state, bool addref = true)
155         {
156             return lcos::future<R>(
157                 boost::intrusive_ptr<SharedState>(shared_state, addref));
158         }
159 
160         HPX_FORCEINLINE static
161         typename traits::detail::shared_state_ptr<R>::type const&
get_shared_statehpx::traits::future_access162         get_shared_state(lcos::future<R> const& f)
163         {
164             return f.shared_state_;
165         }
166 
167         HPX_FORCEINLINE static
168         typename traits::detail::shared_state_ptr<R>::type::element_type*
detach_shared_statehpx::traits::future_access169         detach_shared_state(lcos::future<R> && f)
170         {
171             return f.shared_state_.detach();
172         }
173     };
174 
175     template <typename R>
176     struct future_access<lcos::shared_future<R> >
177     {
178         template <typename SharedState>
179         static lcos::shared_future<R>
createhpx::traits::future_access180         create(boost::intrusive_ptr<SharedState> const& shared_state)
181         {
182             return lcos::shared_future<R>(shared_state);
183         }
184 
185         template <typename T = void>
createhpx::traits::future_access186         static lcos::shared_future<R> create(
187             typename detail::shared_state_ptr_for<
188                 lcos::shared_future<lcos::future<R>>>::type const& shared_state)
189         {
190             return lcos::shared_future<lcos::future<R>>(shared_state);
191         }
192 
193         template <typename SharedState>
194         static lcos::shared_future<R>
createhpx::traits::future_access195         create(boost::intrusive_ptr<SharedState> && shared_state)
196         {
197             return lcos::shared_future<R>(std::move(shared_state));
198         }
199 
200         template <typename T = void>
createhpx::traits::future_access201         static lcos::shared_future<R> create(
202             typename detail::shared_state_ptr_for<
203                 lcos::shared_future<lcos::future<R>>>::type&& shared_state)
204         {
205             return lcos::shared_future<lcos::future<R>>(
206                 std::move(shared_state));
207         }
208 
209         template <typename SharedState>
210         static lcos::shared_future<R>
createhpx::traits::future_access211         create(SharedState* shared_state, bool addref = true)
212         {
213             return lcos::shared_future<R>(
214                 boost::intrusive_ptr<SharedState>(shared_state, addref));
215         }
216 
217         HPX_FORCEINLINE static
218         typename traits::detail::shared_state_ptr<R>::type const&
get_shared_statehpx::traits::future_access219         get_shared_state(lcos::shared_future<R> const& f)
220         {
221             return f.shared_state_;
222         }
223 
224         HPX_FORCEINLINE static
225         typename traits::detail::shared_state_ptr<R>::type::element_type*
detach_shared_statehpx::traits::future_access226         detach_shared_state(lcos::shared_future<R> const& f)
227         {
228             return f.shared_state_.get();
229         }
230     };
231 
232     ///////////////////////////////////////////////////////////////////////////
233     template <typename SharedState, typename Allocator>
234     struct shared_state_allocator
235       : detail::shared_state_allocator<SharedState, Allocator>
236     {};
237 }}
238 
239 #endif
240 
241