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