Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
list_templates.h
Go to the documentation of this file.
1
33#pragma once
34
35#include <ogdf/basic/Array.h>
36#include <ogdf/basic/basic.h>
37#include <ogdf/basic/comparer.h>
38
39#include <functional>
40
41namespace ogdf {
42
50template<typename CONTAINER>
51inline void safeForEach(CONTAINER& container,
52 std::function<void(typename CONTAINER::value_type)> func) {
53 for (auto it = container.begin(); it != container.end();) {
54 auto prev = it++;
55 func(*prev);
56 }
57}
58
65template<typename CONTAINER>
66inline bool safeTestForEach(CONTAINER& container,
67 std::function<bool(typename CONTAINER::value_type)> func) {
68 for (auto it = container.begin(); it != container.end();) {
69 auto prev = it++;
70 if (!func(*prev)) {
71 return false;
72 }
73 }
74 return true;
75}
76
77// sorts list L using quicksort
78template<class LIST>
79void quicksortTemplate(LIST& L) {
81 quicksortTemplate(L, comparer);
82}
83
84// sorts list L using quicksort and compare element comp
85template<class LIST, class COMPARER>
86void quicksortTemplate(LIST& L, const COMPARER& comp) {
87 const int n = L.size();
89
90 int i = 0;
91 for (const typename LIST::value_type& x : L) {
92 A[i++] = x;
93 }
94
95 A.quicksort(comp);
96
97 i = 0;
98 for (typename LIST::value_type& x : L) {
99 x = A[i++];
100 }
101}
102
103namespace internal {
104
110template<typename CONTAINER, typename TYPE, typename ITERATOR>
111ITERATOR chooseIteratorByFastTest(CONTAINER& container,
112 std::function<bool(const TYPE&)> includeElement) {
113 int nElements = 0;
114
115 for (const auto& e : container) {
116 nElements += includeElement(e) ? 1 : 0;
117 }
118
119 ITERATOR result = container.end();
120
121 if (nElements > 0) {
122 int chosenElement = randomNumber(1, nElements);
123 int elemCounter = 0;
124
125 for (ITERATOR it = container.begin(); result == container.end(); it++) {
126 if (includeElement(*it)) {
127 elemCounter++;
128
129 if (elemCounter == chosenElement) {
130 result = it;
131 }
132 }
133 }
134 }
135
136 return result;
137};
138
144template<typename CONTAINER, typename TYPE, typename ITERATOR>
145ITERATOR chooseIteratorBySlowTest(CONTAINER& container,
146 std::function<bool(const TYPE&)> includeElement, int size) {
147 Array<ITERATOR> other(size);
148
149 int i = 0;
150 for (ITERATOR it = container.begin(); it != container.end(); it++) {
151 other[i] = it;
152 i++;
153 }
154
155 other.permute();
156
157 ITERATOR result = container.end();
158
159 for (auto it : other) {
160 if (includeElement(*it)) {
161 result = it;
162 break;
163 }
164 }
165
166 return result;
167};
168
187template<typename CONTAINER, typename TYPE, typename ITERATOR>
188ITERATOR chooseIteratorFrom(CONTAINER& container, std::function<bool(const TYPE&)> includeElement,
189 bool isFastTest) {
190 ITERATOR result = container.begin();
191 int size = container.size();
192
193 if (size > 0) {
194 // let's try to pick *any* element
195 int index = randomNumber(0, size - 1);
196
197 for (int i = 0; i < index; i++) {
198 result++;
199 }
200
201 // the initially chosen element is not feasible?
202 if (!includeElement(*result)) {
203 if (isFastTest) {
204 result = chooseIteratorByFastTest<CONTAINER, TYPE, ITERATOR>(container,
205 includeElement);
206 } else {
207 result = chooseIteratorBySlowTest<CONTAINER, TYPE, ITERATOR>(container,
208 includeElement, size);
209 }
210 }
211 }
212
213 return result;
214}
215
216
217}
218
220template<typename CONTAINER, typename TYPE>
221typename CONTAINER::iterator chooseIteratorFrom(
222 CONTAINER& container,
223 std::function<bool(const TYPE&)> includeElement = [](const TYPE&) { return true; },
224 bool isFastTest = true) {
225 return internal::chooseIteratorFrom<CONTAINER, TYPE, typename CONTAINER::iterator>(container,
226 includeElement, isFastTest);
227}
228
230template<typename CONTAINER, typename TYPE>
231typename CONTAINER::const_iterator chooseIteratorFrom(
232 const CONTAINER& container,
233 std::function<bool(const TYPE&)> includeElement = [](const TYPE&) { return true; },
234 bool isFastTest = true) {
235 return internal::chooseIteratorFrom<const CONTAINER, TYPE, typename CONTAINER::const_iterator>(
236 container, includeElement, isFastTest);
237}
238
239}
Declaration and implementation of Array class and Array algorithms.
Basic declarations, included by all source files.
The parameterized class Array implements dynamic arrays of type E.
Definition Array.h:219
void permute(INDEX l, INDEX r)
Randomly permutes the subarray with index set [l..r].
Definition Array.h:521
Standard comparer (valid as a static comparer).
Definition comparer.h:63
Declarations for Comparer objects.
int randomNumber(int low, int high)
Returns random integer between low and high (including).
ITERATOR chooseIteratorByFastTest(CONTAINER &container, std::function< bool(const TYPE &)> includeElement)
ITERATOR chooseIteratorFrom(CONTAINER &container, std::function< bool(const TYPE &)> includeElement, bool isFastTest)
Returns an iterator to a random element in the container.
ITERATOR chooseIteratorBySlowTest(CONTAINER &container, std::function< bool(const TYPE &)> includeElement, int size)
The namespace for all OGDF objects.
bool safeTestForEach(CONTAINER &container, std::function< bool(typename CONTAINER::value_type)> func)
Like ogdf::safeForEach() but aborts if func returns false.
void safeForEach(CONTAINER &container, std::function< void(typename CONTAINER::value_type)> func)
Calls (possibly destructive) func for each element of container.
CONTAINER::iterator chooseIteratorFrom(CONTAINER &container, std::function< bool(const TYPE &)> includeElement=[](const TYPE &) { return true;}, bool isFastTest=true)
Returns an iterator to a random element in the container.
void quicksortTemplate(LIST &L)