#include <algorithm>
#include <functional> // C++11 or C++14 std::mem_fn
#include <vector>
#include <iostream>
#define OVERLOAD_SET(func)\
static struct { template<typename... Args> \
auto operator()(Args&&...args) -> decltype(func(std::forward<Args>(args)...)) const { \
return func(std::forward<Args>(args)...); \
} \
}
#define APPLY_ON_WRAPPER(func) \
template<class Containter, typename... Args> \
auto func ##_on(Containter& c, Args... args) \
-> decltype(apply_on(c, func, args...)) \
{ \
return apply_on(c, func, args...); \
}
namespace stx {
OVERLOAD_SET(std::all_of) all_of;
OVERLOAD_SET(std::any_of) any_of;
OVERLOAD_SET(std::none_of) none_of;
OVERLOAD_SET(std::for_each) for_each;
OVERLOAD_SET(std::find) find;
OVERLOAD_SET(std::find_if) find_if;
OVERLOAD_SET(std::find_if_not) find_if_not;
OVERLOAD_SET(std::find_end) find_end;
OVERLOAD_SET(std::find_first_of)find_first_of;
OVERLOAD_SET(std::adjacent_find)adjacent_find;
OVERLOAD_SET(std::count) count;
OVERLOAD_SET(std::count_if) count_if;
OVERLOAD_SET(std::mismatch) mismatch;
OVERLOAD_SET(std::equal) equal;
OVERLOAD_SET(std::is_permutation)is_permutation;
OVERLOAD_SET(std::search) search;
OVERLOAD_SET(std::search_n) search_n;
OVERLOAD_SET(std::copy) copy;
OVERLOAD_SET(std::copy_n) copy_n;
OVERLOAD_SET(std::copy_if) copy_if;
OVERLOAD_SET(std::copy_backward)copy_backward;
OVERLOAD_SET(std::move) move;
OVERLOAD_SET(std::move_backward)move_backward;
OVERLOAD_SET(std::swap) swap;
OVERLOAD_SET(std::swap_ranges) swap_ranges;
OVERLOAD_SET(std::iter_swap) iter_swap;
OVERLOAD_SET(std::transform) transform;
OVERLOAD_SET(std::replace) replace;
OVERLOAD_SET(std::replace_if) replace_if;
OVERLOAD_SET(std::replace_copy) replace_copy;
OVERLOAD_SET(std::replace_copy_if)replace_copy_if;
OVERLOAD_SET(std::fill) fill;
OVERLOAD_SET(std::fill_n) fill_n;
OVERLOAD_SET(std::generate) generate;
OVERLOAD_SET(std::generate_n) generate_n;
OVERLOAD_SET(std::remove) remove;
OVERLOAD_SET(std::remove_if) remove_if;
OVERLOAD_SET(std::remove_copy) remove_copy;
OVERLOAD_SET(std::remove_copy_if)remove_copy_if;
OVERLOAD_SET(std::unique) unique;
OVERLOAD_SET(std::unique_copy) unique_copy;
OVERLOAD_SET(std::reverse) reverse;
OVERLOAD_SET(std::reverse_copy) reverse_copy;
OVERLOAD_SET(std::rotate) rotate;
OVERLOAD_SET(std::rotate_copy) rotate_copy;
OVERLOAD_SET(std::random_shuffle)random_shuffle;
OVERLOAD_SET(std::shuffle) shuffle;
OVERLOAD_SET(std::is_partitioned)is_partitioned;
OVERLOAD_SET(std::partition) partition;
OVERLOAD_SET(std::stable_partition)stable_partition;
OVERLOAD_SET(std::partition_copy)partition_copy;
OVERLOAD_SET(std::partition_point)partition_point;
OVERLOAD_SET(std::sort) sort;
OVERLOAD_SET(std::stable_sort) stable_sort;
OVERLOAD_SET(std::partial_sort) partial_sort;
OVERLOAD_SET(std::partial_sort_copy)partial_sort_copy;
OVERLOAD_SET(std::is_sorted) is_sorted;
OVERLOAD_SET(std::is_sorted_until)is_sorted_until;
OVERLOAD_SET(std::nth_element) nth_element;
OVERLOAD_SET(std::lower_bound) lower_bound;
OVERLOAD_SET(std::upper_bound) upper_bound;
OVERLOAD_SET(std::equal_range) equal_range;
OVERLOAD_SET(std::binary_search)binary_search;
OVERLOAD_SET(std::merge) merge;
OVERLOAD_SET(std::inplace_merge)inplace_merge;
OVERLOAD_SET(std::includes) includes;
OVERLOAD_SET(std::set_union) set_union;
OVERLOAD_SET(std::set_intersection)set_intersection;
OVERLOAD_SET(std::set_difference)set_difference;
OVERLOAD_SET(std::set_symmetric_difference)set_symmetric_difference;
OVERLOAD_SET(std::push_heap) push_heap;
OVERLOAD_SET(std::pop_heap) pop_heap;
OVERLOAD_SET(std::make_heap) make_heap;
OVERLOAD_SET(std::sort_heap) sort_heap;
OVERLOAD_SET(std::is_heap) is_heap;
OVERLOAD_SET(std::is_heap_until)is_heap_until;
OVERLOAD_SET(std::min) min;
OVERLOAD_SET(std::max) max;
OVERLOAD_SET(std::minmax) minmax;
OVERLOAD_SET(std::min_element) min_element;
OVERLOAD_SET(std::max_element) max_element;
OVERLOAD_SET(std::minmax_element)minmax_element;
OVERLOAD_SET(std::lexicographical_compare)lexicographical_compare;
OVERLOAD_SET(std::next_permutation) next_permutation;
OVERLOAD_SET(std::prev_permutation) prev_permutation;
template<class Containter, typename Func, typename... Args>
auto apply_on(Containter& c, Func func, Args... args)
-> decltype(func(c.begin(), c.end(), args...))
{
return func(c.begin(), c.end(), args...);
}
APPLY_ON_WRAPPER(all_of);
APPLY_ON_WRAPPER(any_of);
APPLY_ON_WRAPPER(none_of);
APPLY_ON_WRAPPER(for_each);
APPLY_ON_WRAPPER(find);
APPLY_ON_WRAPPER(find_if);
APPLY_ON_WRAPPER(find_if_not);
APPLY_ON_WRAPPER(find_end);
APPLY_ON_WRAPPER(find_first_of);
APPLY_ON_WRAPPER(adjacent_find);
APPLY_ON_WRAPPER(count);
APPLY_ON_WRAPPER(count_if);
APPLY_ON_WRAPPER(mismatch);
APPLY_ON_WRAPPER(equal);
APPLY_ON_WRAPPER(is_permutation);
APPLY_ON_WRAPPER(search);
APPLY_ON_WRAPPER(search_n);
APPLY_ON_WRAPPER(copy);
APPLY_ON_WRAPPER(copy_n);
APPLY_ON_WRAPPER(copy_if);
APPLY_ON_WRAPPER(copy_backward);
APPLY_ON_WRAPPER(move);
APPLY_ON_WRAPPER(move_backward);
APPLY_ON_WRAPPER(swap);
APPLY_ON_WRAPPER(swap_ranges);
APPLY_ON_WRAPPER(iter_swap);
APPLY_ON_WRAPPER(transform);
APPLY_ON_WRAPPER(replace);
APPLY_ON_WRAPPER(replace_if);
APPLY_ON_WRAPPER(replace_copy);
APPLY_ON_WRAPPER(replace_copy_if);
APPLY_ON_WRAPPER(fill);
APPLY_ON_WRAPPER(fill_n);
APPLY_ON_WRAPPER(generate);
APPLY_ON_WRAPPER(generate_n);
APPLY_ON_WRAPPER(remove);
APPLY_ON_WRAPPER(remove_if);
APPLY_ON_WRAPPER(remove_copy);
APPLY_ON_WRAPPER(remove_copy_if);
APPLY_ON_WRAPPER(unique);
APPLY_ON_WRAPPER(unique_copy);
APPLY_ON_WRAPPER(reverse);
APPLY_ON_WRAPPER(reverse_copy);
APPLY_ON_WRAPPER(rotate);
APPLY_ON_WRAPPER(rotate_copy);
APPLY_ON_WRAPPER(random_shuffle);
APPLY_ON_WRAPPER(shuffle);
APPLY_ON_WRAPPER(is_partitioned);
APPLY_ON_WRAPPER(partition);
APPLY_ON_WRAPPER(stable_partition);
APPLY_ON_WRAPPER(partition_copy);
APPLY_ON_WRAPPER(partition_point);
APPLY_ON_WRAPPER(sort);
APPLY_ON_WRAPPER(stable_sort);
APPLY_ON_WRAPPER(partial_sort);
APPLY_ON_WRAPPER(partial_sort_copy);
APPLY_ON_WRAPPER(is_sorted);
APPLY_ON_WRAPPER(is_sorted_until);
APPLY_ON_WRAPPER(nth_element);
APPLY_ON_WRAPPER(lower_bound);
APPLY_ON_WRAPPER(upper_bound);
APPLY_ON_WRAPPER(equal_range);
APPLY_ON_WRAPPER(binary_search);
APPLY_ON_WRAPPER(merge);
APPLY_ON_WRAPPER(inplace_merge);
APPLY_ON_WRAPPER(includes);
APPLY_ON_WRAPPER(set_union);
APPLY_ON_WRAPPER(set_intersection);
APPLY_ON_WRAPPER(set_difference);
APPLY_ON_WRAPPER(set_symmetric_difference);
APPLY_ON_WRAPPER(push_heap);
APPLY_ON_WRAPPER(pop_heap);
APPLY_ON_WRAPPER(make_heap);
APPLY_ON_WRAPPER(sort_heap);
APPLY_ON_WRAPPER(is_heap);
APPLY_ON_WRAPPER(is_heap_until);
APPLY_ON_WRAPPER(min);
APPLY_ON_WRAPPER(max);
APPLY_ON_WRAPPER(minmax);
APPLY_ON_WRAPPER(min_element);
APPLY_ON_WRAPPER(max_element);
APPLY_ON_WRAPPER(minmax_element);
APPLY_ON_WRAPPER(lexicographical_compare);
APPLY_ON_WRAPPER(next_permutation);
APPLY_ON_WRAPPER(prev_permutation);
}
#undef APPLY_ON_WRAPPER
#undef OVERLOAD_SET
struct Bob {
void stuff()
{
std::cout << "stuffing..." << std::endl;
}
};
int main()
{
std::vector<Bob> bobs(3);
stx::apply_on(bobs, stx::for_each, std::mem_fn(&Bob::stuff));
stx::for_each_on(bobs, std::mem_fn(&Bob::stuff));
std::vector<int> ints{3,4,1,6};
auto min_el = stx::apply_on(ints, stx::min_element);
std::cout << *min_el << std::endl;
auto max_el = stx::max_element_on(ints);
std::cout << *max_el << std::endl;
return 0;
}