19 #include "../../core/thread_pool_aspects.hpp"
29 template<
class Conts,
typename CtrPred>
inline void
31 const typename operation_type::result_type::value_type intermediate=
std::count_if(beg, end, fn.input().pred);
32 fn.get_results()+=intermediate;
35 template<
class Conts,
typename Fn>
inline void
37 const typename operation_type::result_type::value_type intermediate=
std::accumulate(beg, end, fn.input().init.get(), fn.input().binop);
38 fn.get_results().apply(intermediate, fn.input().binop);
41 template<
class Conts,
typename CtrPred>
inline constexpr
43 : beg(b), end(e), fn(w) {
46 template<
class Conts,
typename CtrPred>
inline void
48 if (!fn.get_results()) {
49 const typename operation_type::result_type::value_type intermediate=
std::find_if(beg, end, fn.input().pred)!=end;
51 fn.get_results()=
true;
56 template<
class Conts,
typename Fn>
68 return std::max(lhs, rhs, fn.input().binop);
75 template<
class Conts,
typename Fn>
inline constexpr
77 : beg(b), end(e), fn(w) {
80 template<
class Conts,
typename Fn>
inline void
82 const in_iterator max_in_subrange(
std::max_element(beg, end, fn.input().binop));
83 assert(max_in_subrange!=end);
84 const typename operation_type::result_type::value_type intermediate=*max_in_subrange;
85 fn.get_results().apply(intermediate, max(fn));
88 template<
class Conts,
typename Fn>
100 return std::min(lhs, rhs, fn.input().binop);
107 template<
class Conts,
typename Fn>
inline constexpr
109 : beg(b), end(e), fn(w) {
112 template<
class Conts,
typename Fn>
inline void
114 const in_iterator min_in_subrange(
std::min_element(beg, end, fn.input().binop));
115 assert(min_in_subrange!=end);
116 const typename operation_type::result_type::value_type intermediate=*min_in_subrange;
117 fn.get_results().apply(intermediate, min(fn));
120 template<
class Conts,
typename Fn>
inline constexpr
122 : beg_subrange(bs), end_subrange(es), fn(w), cont_size(
std::distance(fn.input().cont_beg(), fn.input().cont_end())) {
125 template<
class Conts,
typename Fn>
inline void
127 for (
in_iterator lhs(beg_subrange); lhs!=end_subrange; ++lhs) {
129 const typename std::iterator_traits<
in_iterator>::difference_type dist_from_beg=
std::distance(fn.input().cont_beg(), lhs);
130 const in_iterator rhs(
std::next(fn.input().cont_beg(), cont_size-dist_from_beg-1));
131 fn.input().binop(lhs, rhs);
135 template<
typename Conts,
class UniOp>
inline void
137 std::fill(beg, end, val.input().value);
140 template<
typename Conts,
class UniOp>
inline void
142 std::fill(beg, end, val.input().value);
145 template<
class Conts,
typename Pred>
inline void
147 auto const &op=fn.input().op;
148 for (; begin1!=end1; ++begin1, ++begin2) {
149 if (op.operator()(*begin1, *begin2)) {
150 std::iter_swap(begin1, begin2);
155 template<
class Comp,
class TPB>
156 template<
class CoreWk>
inline void
159 wk.work_complete()->containers().input1.size()+wk.work_complete()->containers().input2.size()
163 template<
direction Dir,
class out_iterator,
class Closure>
inline bool
168 template<
class Iter,
class operation_type,
direction LHSDir,
direction RHSDir,
class Dummy>
inline void merge_final_sorter<Iter, operation_type, LHSDir, RHSDir, Dummy>::
process(Dummy
const &,
out_iterator const begin,
out_iterator const end, operation_type
const &fn)
noexcept(
false) {
171 const out_sz_t size_of_portion=
std::distance(begin, end);
172 const out_sz_t half_size_of_portion=size_of_portion>>1;
174 std::vector<
typename out_iterator::value_type> out_colln;
175 out_colln.reserve(size_of_portion);
177 std::merge(begin, middle, rev_in(end), rev_in(middle), std::back_inserter(out_colln), arg3_type(swapper_t(fn)));
179 std::move(out_colln.begin(), out_colln.end(), begin);
181 std::move(rev_in(out_colln.end()), rev_in(out_colln.begin()), begin);
200 : sorter(sfn), begin(b), end(e), fn(f), clique(cl) {
208 typedef merge<lhs_dir, lhs_dir, FinalSort> lhs_sub_merge;
209 typedef merge<lhs_dir, lhs_dir==direction::ascending ? direction::descending : direction::ascending, FinalSort> rhs_sub_merge;
211 const out_sz_t size_of_portion=
std::distance(begin, end);
216 || clique<fn.input().pool.pool_size()
219 const out_sz_t half_size_of_portion=size_of_portion>>1;
222 assert(begin!=middle);
226 auto const &merge_lhs=fn.input().pool<<
joinable(
this,
lhs_merge_str)<<lhs_sub_merge(begin, middle, fn, sorter, clique<<1);
227 auto const &merge_rhs=fn.input().pool<<
joinable(
this,
rhs_merge_str)<<rhs_sub_merge(middle, end, fn, sorter, clique<<1);
232 final_sort::process(sorter, begin, end, fn);
236 constexpr bool __fastcall operator<(merge
const &)
const noexcept(
true)
FORCE_INLINE {
248 template<
class Conts,
typename Comp>
inline void
252 assert((conts.input1.size()+conts.input2.size())==conts.output.size());
254 auto const &first=fn.input().pool<<
joinable(
this,
combine1_str)<<
cliques(clique<<1)<<fn.input().pool.
template copy<
typename containers_type::input1_t::container_type,
typename containers_type::output_t::container_type>(conts.input1.begin(), conts.input1.end(), conts.output.begin());
255 const out_iterator middle(
std::next(conts.output.begin(), conts.input1.size()));
256 auto const &second=fn.input().pool<<
joinable(
this,
combine2_str)<<
cliques(clique<<1)<<fn.input().pool.
template copy<
typename containers_type::input2_t::container_type,
typename containers_type::output_t::container_type>(rev_in2(conts.input2.end()), rev_in2(conts.input2.begin()), middle);
261 template<
class Conts,
typename Comp>
inline
263 : conts(c), fn(w), clique(cl) {
266 template<
class Conts,
typename Comp>
inline void
268 typedef typename thread_pool_type::
template create_direct<init_merger_t> init_merger_creator_t;
270 if (conts.input1.size()!=conts.input2.size()) {
283 if ((conts.input1.size()+conts.input2.size())%2) {
297 auto sorter=[](
auto b,
auto e,
auto s) {
298 return std::stable_sort<
typename sort_fn_t::arg1_type,
typename sort_fn_t::arg3_type>(b, e, s);
300 typename init_merger_creator_t::closure_t all(init_merger_t(conts.output.begin(), conts.output.end(), fn, sorter, clique),
typename pool_traits_type::thread_wk_elem_type::cfg_details_type::params(fn.input().pool.cfg(),
this,
"init_merger"));
327 : begin(b), end(e), fn(f), clique(cl) {
337 typedef typename operation_type::argument_type::thread_pool_type::joinable joinable;
339 const typename in_iterator::difference_type size_of_portion=
std::distance(begin, end);
340 auto merge_sorter=[](
auto b,
auto e,
auto s) {
347 || clique<fn.input().pool.pool_size()
350 const typename in_iterator::difference_type half_size_of_portion=size_of_portion>>1;
355 *sort_rhs_descending;
356 auto const &bitonic_merge_all=fn.input().pool<<joinable(
this,
merge_str)<<
merge_in_dir_t(begin, end, fn, merge_sorter, clique);
363 constexpr bool __fastcall operator<(sort
const &)
const noexcept(
true)
FORCE_INLINE {
374 template<
typename Conts,
class Comp>
inline constexpr
376 : cont(c), fn(op), clique(cl) {
379 template<
typename Conts,
class Comp>
inline void
383 typename init_sort_creator_t::closure_t all(
init_sorter_t(cont.input1.begin(), cont.input1.end(), fn, clique),
typename pool_traits_type::thread_wk_elem_type::cfg_details_type::params(fn.input().pool.cfg(),
this,
"init_sorter"));
391 template<
class ArgT,
class UniFn,
class PT>
404 arg.process(r.result);
407 bool __fastcall operator<(arg_int_work_type
const &rhs)
const FORCE_INLINE {
411 operator<(Arg1
const &)
const noexcept(
true) {
419 template<
class ArgT,
class UniFn,
class PT>
420 struct unary_fun_work_type<ArgT, UniFn, PT>::arg_context_t :
public sp_counter_type<
long,
typename pool_type::os_traits::lock_traits> {
441 template<
class ArgT,
class UniFn,
class PT>
inline
446 template<
class ArgT,
class UniFn,
class PT>
inline void
448 assert(
dynamic_cast<arg_context_t *>(arg_cxt.get().get()));
449 r.result=op.operator()(arg_cxt->arg->result);
452 template<
class ArgT,
class UniFn,
class PT>
inline bool
454 return *arg_cxt->arg.wk_queue_item()<*rhs.arg_cxt->arg.wk_queue_item();
461 typedef Arg argument_type;
468 explicit constexpr __stdcall arg_int_work_type(argument_type &&a)
FORCE_INLINE
469 : arg(
std::forward<argument_type>(a)) {
472 arg.process(r.result);
475 bool __fastcall operator<(arg_int_work_type
const &rhs)
const FORCE_INLINE {
478 template<
class Arg1>
constexpr bool __fastcall FORCE_INLINE
479 operator<(Arg1
const &)
const noexcept(
true) {
487 template<
class ArgT1,
class ArgT2,
class BinFn,
class PT>
488 struct binary_fun_work_type<ArgT1, ArgT2, BinFn, PT>::arg_contexts_t :
public sp_counter_type<
long,
typename pool_type::os_traits::lock_traits> {
514 template<
class ArgT1,
class ArgT2,
class BinFn,
class PT>
inline
519 template<
class ArgT1,
class ArgT2,
class BinFn,
class PT>
inline void
521 assert(
dynamic_cast<arg_contexts_t *>(arg_cxts.get().get()));
522 r.result=op.operator()(arg_cxts->first_arg->result, arg_cxts->second_arg->result);
525 template<
class ArgT1,
class ArgT2,
class BinFn,
class PT>
inline bool
527 return *arg_cxts->first_arg.wk_queue_item()<*rhs.arg_cxts->second_arg.wk_queue_item() || (*arg_cxts->first_arg.wk_queue_item()==*rhs.arg_cxts->first_arg.wk_queue_item() && *arg_cxts->second_arg.wk_queue_item()<*rhs.arg_cxts->second_arg.wk_queue_item());