13template <
class T1 =
void,
class T2 =
void>
15 constexpr T1 operator()(
const std::pair<T1, T2>& pair)
const {
23 template <
class T1,
class T2>
24 constexpr auto operator()(
const std::pair<T1, T2>& pair)
const
25 ->
decltype(
static_cast<const T1&
>(pair.first)) {
26 return static_cast<const T1&
>(pair.first);
31template <
class T1 =
void,
class T2 =
void>
33 constexpr T2 operator()(
const std::pair<T1, T2>& pair)
const {
41 template <
class T1,
class T2>
42 constexpr auto operator()(
const std::pair<T1, T2>& pair)
const
43 ->
decltype(
static_cast<const T2&
>(pair.second)) {
44 return static_cast<const T2&
>(pair.second);
56template<
typename ForwardIt,
typename T>
57T
min_value(ForwardIt first, ForwardIt last, T fallback) {
58 auto it = std::min_element(first, last);
59 return it != last ?
static_cast<T
>(*it) : fallback;
72template<
typename ForwardIt,
typename UnaryOp,
typename T>
73T
min_value(ForwardIt first, ForwardIt last, UnaryOp operation, T fallback) {
74 auto it = std::min_element(first, last, [&operation](
const auto& left,
const auto& right) {
75 return operation(left) < operation(right);
77 return it != last ?
static_cast<T
>(operation(*it)) : fallback;
88template<
typename ForwardIt,
typename T>
89T
max_value(ForwardIt first, ForwardIt last, T fallback) {
90 auto it = std::max_element(first, last);
91 return it != last ?
static_cast<T
>(*it) : fallback;
104template<
typename ForwardIt,
typename UnaryOp,
typename T>
105T
max_value(ForwardIt first, ForwardIt last, UnaryOp operation, T fallback) {
106 auto it = std::max_element(first, last, [&operation](
const auto& left,
const auto& right) {
107 return operation(left) < operation(right);
109 return it != last ?
static_cast<T
>(operation(*it)) : fallback;
122template <
class InputIt,
class UnaryOp>
123std::string
transform_join(
const InputIt first,
const InputIt last, UnaryOp operation,
const std::string& separator,
bool trailing_separator =
false) {
124 std::string res =
"";
126 for(
auto curr = first; curr != last; ++curr) {
127 res += operation(*curr);
128 if(last - curr > 1 || trailing_separator)
145template <
class InputIt>
146std::string
join(
const InputIt first,
const InputIt last,
const std::string& separator,
bool trailing_separator =
false) {
147 return transform_join(first, last, [](
const auto& val) {
return to_string(val); }, separator, trailing_separator);
160template<
class InputIt,
class OutputIt>
161OutputIt
pair_adjacent(
const InputIt first,
const InputIt last, OutputIt d_first) {
162 if(std::distance(first, last) > 1) {
163 return std::transform(first, std::prev(last), std::next(first), d_first, [](
const auto& a,
const auto& b) {
164 return std::make_pair(a, b);
178template<
class InputIt>
179std::vector<std::pair<typename InputIt::value_type, typename InputIt::value_type>>
pair_adjacent(
const InputIt first,
const InputIt last) {
180 std::vector<std::pair<typename InputIt::value_type, typename InputIt::value_type>> res;
198template<
typename InputIt1,
typename InputIt2,
typename OutputIt>
199OutputIt
zip(
const InputIt1 first1,
const InputIt1 last1,
const InputIt2 first2, OutputIt d_first) {
200 return std::transform(first1, last1, first2, d_first, [](
const auto& a,
const auto& b) {
201 return std::make_pair(a, b);
216template<
typename InputIt1,
typename InputIt2>
217std::vector<std::pair<typename InputIt1::value_type, typename InputIt2::value_type>>
zip(
const InputIt1 first1,
const InputIt1 last1,
const InputIt2 first2) {
218 std::vector<std::pair<typename InputIt1::value_type, typename InputIt2::value_type>> res;
219 zip(first1, last1, first2, std::back_inserter(res));
231template<
typename ParamT =
float,
typename OutputIt>
234 *output_first = ParamT(0.5) * (start + stop);
237 const ParamT size = stop - start;
238 const ParamT step = size /
static_cast<ParamT
>(n - 1);
239 for(
size_t i = 0; i < n; ++i) {
240 ParamT t = start + step *
static_cast<ParamT
>(i);
253template<
typename ParamT>
255 std::vector<ParamT> out;
267template<
class InputIt>
269 std::vector<size_t> indices(
static_cast<size_t>(std::distance(first, last)));
270 std::iota(indices.begin(), indices.end(), 0);
281template<
class RandomIt>
282std::vector<size_t>
sort_indices(
const RandomIt first,
const RandomIt last) {
284 std::sort(indices.begin(), indices.end(), [first](
size_t i1,
size_t i2) {
285 return first[i1] < first[i2];
297template<
class RandomIt>
300 std::stable_sort(indices.begin(), indices.end(), [first](
size_t i1,
size_t i2) {
301 return first[i1] < first[i2];
316template<
class RandomIt,
class Compare>
317std::vector<size_t>
sort_indices(
const RandomIt first,
const RandomIt last, Compare comp) {
319 std::sort(indices.begin(), indices.end(), [first, &comp](
size_t i1,
size_t i2) {
320 return comp(first[i1], first[i2]);
335template<
class RandomIt,
class Compare>
338 std::stable_sort(indices.begin(), indices.end(), [first, &comp](
size_t i1,
size_t i2) {
339 return comp(first[i1], first[i2]);
std::string join(const InputIt first, const InputIt last, const std::string &separator, bool trailing_separator=false)
Concatenate elements in the range [first, last) to a std::string.
std::vector< size_t > generate_index_sequence(const InputIt first, const InputIt last)
Return a sequence of monotonically increasing values from 0 to n = distance(first,...
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
std::string transform_join(const InputIt first, const InputIt last, UnaryOp operation, const std::string &separator, bool trailing_separator=false)
Transform elements in the range [first, last) and concatenate them to a std::string.
std::vector< size_t > sort_indices(const RandomIt first, const RandomIt last)
Return a sequence of indices corresponding to the sorted order of values in [first,...
OutputIt zip(const InputIt1 first1, const InputIt1 last1, const InputIt2 first2, OutputIt d_first)
Zip two sequences together to form a single sequene of pairs and store the results in an output range...
std::vector< size_t > stable_sort_indices(const RandomIt first, const RandomIt last)
Return a sequence of indices corresponding to the sorted order of values in [first,...
T min_value(ForwardIt first, ForwardIt last, T fallback)
Find the minimum value in the range [first, last) or return fallback if the range is empty.
void subdivision_sequence(OutputIt output_first, ParamT start, ParamT stop, size_t n)
Generate a sequence of n uniformly-spaced values in [start,stop] and store the result in an output ra...
OutputIt pair_adjacent(const InputIt first, const InputIt last, OutputIt d_first)
Transform the elements in the range [first, last) to adjacent pairs and store the results in an outpu...
T max_value(ForwardIt first, ForwardIt last, T fallback)
Find the maximum value in the range [first, last) or return fallback if the range is empty.
this header is dependency free
Return std::pair::second.