ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
for_each_pair.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef CORE_UTILS_FOR_EACH_PAIR_HPP
21#define CORE_UTILS_FOR_EACH_PAIR_HPP
22
23#include <iterator>
24
25namespace Utils {
26
27/**
28 * @brief Execute op for each pair of elements in [first, last) once.
29 *
30 * Diagonal elements are excluded. Pairs are traversed ordered, so that
31 * for op(*it, *jt), it holds that distance(it - first) < distance(jt - first),
32 * and distance(it_n - first) < distance(it_n+1 - first) for consecutive calls.
33 */
34template <typename ForwardIterator, typename BinaryOp>
35void for_each_pair(ForwardIterator first, ForwardIterator last, BinaryOp op) {
36 while (first != last) {
37 for (auto it = std::next(first); it != last; ++it) {
38 op(*first, *it);
39 }
40
41 ++first;
42 }
43}
44
45/** @overload */
46template <typename ForwardRange, typename BinaryOp>
47void for_each_pair(ForwardRange &&rng, BinaryOp &&op) {
48 using std::begin;
49 using std::end;
50 for_each_pair(begin(rng), end(rng), std::forward<BinaryOp>(op));
51}
52
53/**
54 * @brief Execute op for each pair of elements between [first1, last1) and
55 * [first2, last2).
56 *
57 * Diagonal elements are *not* excluded. Pairs are traversed ordered, so that
58 * for op(*it, *jt), it holds that distance(it - first) < distance(jt - first),
59 * and distance(it_n - first) < distance(it_n+1 - first) for consecutive calls.
60 */
61template <typename ForwardIterator, typename BinaryOp>
62void for_each_cartesian_pair(ForwardIterator first1, ForwardIterator last1,
63 ForwardIterator first2, ForwardIterator last2,
64 BinaryOp op) {
65 while (first1 != last1) {
66 for (auto it = first2; it != last2; ++it) {
67 op(*first1, *it);
68 }
69
70 ++first1;
71 }
72}
73
74/** @overload */
75template <typename ForwardRange, typename BinaryOp>
76void for_each_cartesian_pair(ForwardRange &&rng1, ForwardRange &&rng2,
77 BinaryOp &&op) {
78 using std::begin;
79 using std::end;
80 for_each_cartesian_pair(begin(rng1), end(rng1), begin(rng2), end(rng2),
81 std::forward<BinaryOp>(op));
82}
83
84/**
85 * @brief Execute op for each pair of elements between [first1, last1) and
86 * [first2, last2) if a condition is satisfied.
87 *
88 * Diagonal elements are *not* excluded. Pairs are traversed ordered, so that
89 * for op(*it, *jt), it holds that distance(it - first) < distance(jt - first),
90 * and distance(it_n - first) < distance(it_n+1 - first) for consecutive calls.
91 */
92template <typename ForwardIterator, typename BinaryOp, typename BinaryCmp>
93void for_each_cartesian_pair_if(ForwardIterator first1, ForwardIterator last1,
94 ForwardIterator first2, ForwardIterator last2,
95 BinaryOp op, BinaryCmp cmp) {
96 while (first1 != last1) {
97 for (auto it = first2; it != last2; ++it) {
98 if (cmp(*first1, *it)) {
99 op(*first1, *it);
100 }
101 }
102
103 ++first1;
104 }
105}
106
107/** @overload */
108template <typename ForwardRange, typename BinaryOp, typename BinaryCmp>
109void for_each_cartesian_pair_if(ForwardRange &&rng1, ForwardRange &&rng2,
110 BinaryOp &&op, BinaryCmp cmp) {
111 using std::begin;
112 using std::end;
113 for_each_cartesian_pair_if(begin(rng1), end(rng1), begin(rng2), end(rng2),
114 std::forward<BinaryOp>(op),
115 std::forward<BinaryCmp>(cmp));
116}
117} // namespace Utils
118#endif
void for_each_pair(ForwardIterator first, ForwardIterator last, BinaryOp op)
Execute op for each pair of elements in [first, last) once.
void for_each_cartesian_pair(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryOp op)
Execute op for each pair of elements between [first1, last1) and [first2, last2).
void for_each_cartesian_pair_if(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryOp op, BinaryCmp cmp)
Execute op for each pair of elements between [first1, last1) and [first2, last2) if a condition is sa...