9 namespace honey {
namespace future
22 template<class Range, class Clock, class Dur, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
25 template<class Range, class Rep, class Period, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
28 template<class Range, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
43 void operator()(StateBase& src);
50 vector<StateBase*> states;
53 static mt_global((thread::Local<ThreadData>), threadData,);
56 StateBase* readyState;
61 template<
class Future,
class... Futures,
typename mt::disable_if<mt::isRange<Future>::value,
int>::type=0>
66 array<
const FutureBase*,
sizeof...(Futures)+1> futures = {&f, &fs...};
67 for (
auto& e : futures) waiter.add(*e);
68 return waiter.
wait(MonoClock::TimePoint::max());
72 template<class Range, class Clock, class Dur, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
76 for (
auto& e :
range) waiter.add(e);
77 int index = waiter.wait(time);
78 return index >= 0 ? next(begin(range), index) : end(range);
81 template<class Range, class Rep, class Period, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
84 template<class Range, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0>
97 Task(Func&& f) : f(forward<Func>(f)) {}
100 void operator()() { f();
delete_(
this); }
105 virtual bool traceEnabled()
const;
109 template<
class R,
class Func,
class... Args>
112 Bind(Func&& f, Args&&... args) : f(forward<Func>(f)), args(forward<Args>(args)...) {}
114 Bind(
const Bind& rhs) : Bind(move(const_cast<Bind&>(rhs))) {}
115 Bind(Bind&&) =
default;
119 R func(mt::idxseq<Seq...>) {
return f(forward<Args>(get<Seq>(args))...); }
125 template<
class Func,
class... Args>
126 struct Bind<void, Func, Args...>
128 Bind(Func&& f, Args&&... args) : f(forward<Func>(f)), args(forward<Args>(args)...) {}
129 Bind(
const Bind& rhs) : Bind(move(const_cast<Bind&>(rhs))) {}
130 Bind(Bind&&) =
default;
134 void func(mt::idxseq<Seq...>) { f(forward<Args>(get<Seq>(args))...); }
140 template<
class Func,
class... Args,
class R =
typename std::result_of<Func(Args...)>::type>
141 Bind<R, Func, Args...> bind(Func&& f, Args&&... args) {
return Bind<R, Func, Args...>(forward<Func>(f), forward<Args>(args)...); }
151 AsyncSched(
int workerCount,
int workerTaskMax) : thread::
Pool(workerCount, workerTaskMax) {}
162 #ifndef future_async_createSingleton
172 template<
class Sched,
class Func,
class... Args,
typename std::enable_if<mt::is_base_of<AsyncSched_tag, Sched>::value,
int>::type=0>
174 Future<
typename std::result_of<Func(Args...)>::type>
175 async(Sched&& sched, Func&& f, Args&&... args)
177 typedef typename std::result_of<Func(Args...)>::type R;
179 auto future = task.future();
188 template<
class Func,
class... Args>
189 Future<
typename std::result_of<Func(Args...)>::type>
198 template<
class Sub
class,
class R>
199 template<
class Sched,
class Func>
202 using namespace future::priv;
204 typedef typename std::result_of<Func(Subclass)>::type R2;
206 auto future = promise.future();
210 onReady(Subclass&& cont,
Promise<R2>&& promise, Sched&& sched, Func&& f) :
211 cont(move(cont)), promise(move(promise)), sched(forward<Sched>(sched)), f(forward<Func>(f)) {}
213 void operator()(StateBase& src)
219 this->sched(move(task));
230 subc()._state->addOnReady(*
new onReady(move(subc()), move(promise), forward<Sched>(sched), forward<Func>(f)));
234 template<
class Sub
class,
class R>
249 template<
class Func,
class Futures,
szt... Seq>
253 template<
class Result>
254 struct whenAll_onReady
256 template<
class Futures,
szt... Seq>
257 static void func(Promise<Result>& promise, Futures& fs, mt::idxseq<Seq...>)
258 { promise.setValue(make_tuple(get<Seq>(fs).__state().result()...)); }
259 template<
class Range>
260 static void func(Promise<Result>& promise, Range&
range)
261 { Result res;
for (
auto& e : range) res.push_back(e.__state().result()); promise.setValue(res); }
265 struct whenAll_onReady<void>
267 template<
class Futures,
szt... Seq>
268 static void func(Promise<void>& promise, Futures&, mt::idxseq<Seq...>)
269 { promise.setValue(); }
270 template<
class Range>
271 static void func(Promise<void>& promise, Range&)
272 { promise.setValue(); }
275 template<
class Futures,
szt... Seq>
276 int whenAny_valIndex(StateBase& src, Futures& fs, mt::idxseq<Seq...>)
277 {
return mt::valIndex(&src, &get<Seq>(fs).__state()...); }
278 template<
class Range>
279 int whenAny_valIndex(StateBase& src, Range& range) {
int i = -1;
return find(range, [&](
auto& e) {
return ++i, &src == &e.__state(); }) != end(range) ? i : -1; }
281 template<
class Result_>
282 struct whenAny_onReady
284 template<
class Futures,
szt... Seq,
class Result = tuple<int, Result_>>
285 static void func(Promise<Result>& promise, Futures& fs, mt::idxseq<Seq...>,
int i)
286 { promise.setValue(make_tuple(i,
mt::valAt(i, get<Seq>(fs)...).__state().result())); }
287 template<class Range, class Result = tuple<typename mt::iterOf<Range>::type, Result_>>
288 static void func(Promise<Result>& promise, Range& range,
int i)
289 {
auto it = next(begin(range), i); promise.setValue(make_tuple(it, it->__state().result())); }
293 struct whenAny_onReady<void>
295 template<
class Futures,
szt... Seq>
296 static void func(Promise<int>& promise, Futures&, mt::idxseq<Seq...>,
int i)
297 { promise.setValue(i); }
298 template<class Range, class Result = typename mt::iterOf<Range>::type>
299 static void func(Promise<Result>& promise, Range& range,
int i)
300 { promise.setValue(next(begin(range), i)); }
308 template<
class... Futures,
310 class Result =
typename std::conditional< std::is_same<Result_, void>::value,
312 tuple<typename std::decay<typename mt::removeRef<Futures>::type::Result>::type...>>::type>
315 using namespace future::priv;
317 auto future = promise.future();
322 promise(move(promise)), fs(forward<Futures>(fs)...), count(0),
ready(0), max(
sizeof...(fs)) {}
324 void operator()(StateBase& src)
327 if (src.ready && !this->promise.__state().ready)
330 this->promise.setException(src.ex);
331 else if (++this->
ready == this->max)
332 priv::whenAll_onReady<Result>::func(this->promise, this->fs,
mt::make_idxseq<
sizeof...(Futures)>());
334 if (++this->count == this->max) { _.
unlock();
delete_(
this); }
338 tuple<Futures...> fs;
345 auto& func = *
new onReady(move(promise), forward<Futures>(fs)...);
351 template< class Range, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0,
352 class Result_ =
typename std::decay<typename mt::elemOf<Range>::type::Result>::type,
353 class Result =
typename std::conditional< std::is_same<Result_, void>::value,
355 vector<Result_>>::type>
358 using namespace future::priv;
360 auto future = promise.future();
365 promise(move(promise)),
range(forward<Range>(range)), count(0),
ready(0), max(
countOf(range)) {}
367 void operator()(StateBase& src)
370 if (src.ready && !this->promise.__state().ready)
373 this->promise.setException(src.ex);
374 else if (++this->
ready == this->max)
375 priv::whenAll_onReady<Result>::func(this->promise, this->range);
377 if (++this->count == this->max) { _.
unlock();
delete_(
this); }
388 auto& func = *
new onReady(move(promise), forward<Range>(range));
389 for (
auto& e : func.range) e.__state().addOnReady(func);
394 template<
class... Futures,
395 class Result_ =
typename std::decay<
typename mt::removeRef<mt::typeAt<0, Futures...>>::type::Result>::type,
396 class Result =
typename std::conditional< std::is_same<Result_, void>::value,
398 tuple<int, Result_>>::type>
401 using namespace future::priv;
403 auto future = promise.future();
408 promise(move(promise)), fs(forward<Futures>(fs)...), count(0), max(
sizeof...(fs)) {}
410 void operator()(StateBase& src)
413 if (src.ready && !this->promise.__state().ready)
416 this->promise.setException(src.ex);
420 priv::whenAny_onReady<Result_>::func(this->promise, this->fs, seq, whenAny_valIndex(src, this->fs, seq));
423 if (++this->count == this->max) { _.
unlock();
delete_(
this); }
427 tuple<Futures...> fs;
433 auto& func = *
new onReady(move(promise), forward<Futures>(fs)...);
439 template< class Range, typename std::enable_if<mt::isRange<Range>::value,
int>::type=0,
440 class Result_ =
typename std::decay<typename mt::elemOf<Range>::type::Result>::type,
441 class Result =
typename std::conditional< std::is_same<Result_, void>::value,
443 tuple<typename mt::iterOf<Range>::type, Result_>>::type>
446 using namespace future::priv;
448 auto future = promise.future();
453 promise(move(promise)),
range(forward<Range>(range)), count(0), max(
countOf(range)) {}
455 void operator()(StateBase& src)
458 if (src.ready && !this->promise.__state().ready)
461 this->promise.setException(src.ex);
463 priv::whenAny_onReady<Result_>::func(this->promise, this->range, whenAny_valIndex(src, this->range));
465 if (++this->count == this->max) { _.
unlock();
delete_(
this); }
475 auto& func = *
new onReady(move(promise), forward<Range>(range));
476 for (
auto& e : func.range) e.__state().addOnReady(func);
TimePoint represented by a duration since a clock's epoch time.
Definition: TimePoint.h:11
static TimePoint now()
Get current time.
Definition: Clock.h:48
Future< typename std::result_of< Func(Subclass)>::type > then(Sched &&sched, Func &&f)
Append a continuation function that will be called when this future is ready. The ready future is pas...
Unique future, guarantees sole access to a future function result.
Definition: Future.h:53
A thread lock where the lock is acquired through a busy wait loop.
Definition: Spin.h:17
Combined intrusive/non-intrusive smart pointer. Can reference and share any object automatically...
Definition: SharedPtr.h:175
AsyncSched(int workerCount, int workerTaskMax)
Definition: Util.h:151
Pool(szt workerCount, szt workerTaskMax)
Definition: Pool.cpp:24
Iter find(Range &&, Seqs &&..., Func &&pred)
Find an element in a series of sequences.
static AsyncSched & inst()
Definition: Util.h:153
int valIndex(Val &&val, Ts &&...ts)
Get index of first matching value in parameter pack, returns -1 if not found.
Definition: Range.h:71
void delete_(T *&p)
Destruct object, free memory and set pointer to null.
Definition: Allocator.h:75
Super::TimePoint TimePoint
Definition: Clock.h:40
AsyncSched * async_createSingleton()
Default implementation.
Definition: Util.h:164
the future result is ready
Container to hold a delayed function result.
Definition: Promise.h:181
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
static auto _
Definition: Module.cpp:8
Lock that is bound to a single condition. This is the common usage case of condition variables...
Definition: Lock.h:33
std::decay< decltype(honey::begin(declval< Range >)))>::type type
Definition: Range.h:31
Objects that inherit from this class will use Alloc for new/delete ops.
Definition: Allocator.h:129
#define mt_iterOf(Range)
iterOf for values
Definition: Range.h:33
void unlock()
Definition: Unique.h:103
Future< R > FutureCreate(T &&val)
Create a future that is immediately ready with the value.
Definition: Future.h:211
szt countOf(Range &&range)
Count number of elements in range.
Definition: Range.h:424
static constexpr Duration max()
Maximum duration (positive reps)
Definition: Duration.h:86
A container that wraps a function so that its result is stored in a future when invoked.
Definition: PackagedTask.h:10
std::conditional< std::is_same< Result, void >::value, mt::typeAt< 0, Ts... >, Result >::type valAt(int i, Ts &&...ts)
Get value at index of parameter pack. All types must be convertible to Result, which defaults to the ...
Definition: Range.h:63
All tasks must inherit from this class. std::function is not used here to avoid the operator() virtua...
Definition: Pool.h:16
Duration represented by repetitions of a period. The period must be a ratio.
Definition: Duration.h:7
#define throw_
Use in place of throw keyword to throw a honey::Exception object polymorphically and provide debug in...
Definition: Exception.h:11
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
int waitAny(Future &&f, Futures &&...fs)
Wait until any futures are ready, returns index of ready future.
Definition: Util.h:63
void operator()(Func &&f)
Definition: Util.h:156
Global allocator for small memory blocks. To provide a custom pool define SmallAllocator_createSingle...
Definition: SmallAllocator.h:23
Future< tuple<> > whenAll()
Definition: Util.h:305
static bool trace
Whether to log task execution flow.
Definition: Util.h:159
void enqueue(Task &&task)
Schedule a task for execution.
Definition: Pool.h:35
void wait() const
Wait until result is ready.
Definition: Future.h:31
auto waitAny(Range &&range) -> mt_iterOf(range)
Wait until any futures in a range are ready, returns iterator to ready future.
Definition: Util.h:85
Future< typename std::result_of< Func(Args...)>::type > async(Sched &&sched, Func &&f, Args &&...args)
Call a function asynchronously, returns a future with the result of the function call.
Definition: Util.h:175
Base class for Future types.
Definition: Future.h:20
Inherit to enable non-virtual functor calling.
Definition: Meta.h:231
void waitAll()
Definition: Util.h:16
Future< Result > whenAny(Futures &&...fs)
Returns a future to a tuple of the index of the ready future and its result.
Definition: Util.h:399
Global Honeycomb namespace.
Spreads task execution across a pool of re-usable threads. Uses a lock-free work-stealing queue to en...
Definition: Pool.h:12