1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2013
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
22 #include <lemon/concepts/path.h>
23 #include <lemon/concepts/digraph.h>
24 #include <lemon/concept_check.h>
26 #include <lemon/path.h>
27 #include <lemon/list_graph.h>
29 #include "test_tools.h"
32 using namespace lemon;
34 template <typename GR>
35 void checkConcepts() {
36 checkConcept<concepts::Path<GR>, concepts::Path<GR> >();
37 checkConcept<concepts::Path<GR>, Path<GR> >();
38 checkConcept<concepts::Path<GR>, SimplePath<GR> >();
39 checkConcept<concepts::Path<GR>, StaticPath<GR> >();
40 checkConcept<concepts::Path<GR>, ListPath<GR> >();
43 // Conecpt checking for path structures
44 void checkPathConcepts() {
45 checkConcepts<concepts::Digraph>();
46 checkConcepts<ListDigraph>();
49 // Check if proper copy consructor is called (use valgrind for testing)
50 template <typename GR, typename P1, typename P2>
51 void checkCopy(typename GR::Arc a) {
62 // Tests for copy constructors and assignment operators of paths
63 void checkPathCopy() {
65 ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());
67 typedef Path<ListDigraph> Path1;
68 typedef SimplePath<ListDigraph> Path2;
69 typedef ListPath<ListDigraph> Path3;
70 typedef StaticPath<ListDigraph> Path4;
71 checkCopy<ListDigraph, Path1, Path2>(a);
72 checkCopy<ListDigraph, Path1, Path3>(a);
73 checkCopy<ListDigraph, Path1, Path4>(a);
74 checkCopy<ListDigraph, Path2, Path1>(a);
75 checkCopy<ListDigraph, Path2, Path3>(a);
76 checkCopy<ListDigraph, Path2, Path4>(a);
77 checkCopy<ListDigraph, Path3, Path1>(a);
78 checkCopy<ListDigraph, Path3, Path2>(a);
79 checkCopy<ListDigraph, Path3, Path4>(a);
82 // Class for testing path functions
83 class CheckPathFunctions {
84 typedef ListDigraph GR;
95 CheckPathFunctions() : cgr(gr) {
100 a1 = gr.addArc(n1, n2);
101 a2 = gr.addArc(n2, n3);
102 a3 = gr.addArc(n3, n4);
103 a4 = gr.addArc(n4, n1);
107 checkBackAndFrontInsertablePath<Path<GR> >();
108 checkBackAndFrontInsertablePath<ListPath<GR> >();
109 checkBackInsertablePath<SimplePath<GR> >();
111 checkSubscriptOperator<Path<GR> >();
112 checkSubscriptOperator<SimplePath<GR> >();
113 checkSubscriptOperator<StaticPath<GR> >();
114 checkSubscriptOperator<ListPath<GR> >();
116 checkListPathSplitAndSplice();
121 template <typename P>
122 void checkBackInsertablePath() {
124 // Create and check empty path
127 check(cp.empty(), "The path is not empty");
128 check(cp.length() == 0, "The path is not empty");
129 // check(cp.front() == INVALID, "Wrong front()");
130 // check(cp.back() == INVALID, "Wrong back()");
131 typename P::ArcIt ai(cp);
132 check(ai == INVALID, "Wrong ArcIt");
133 check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()");
134 check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()");
135 check(checkPath(cgr, cp), "Wrong checkPath()");
136 PathNodeIt<P> ni(cgr, cp);
137 check(ni == INVALID, "Wrong PathNodeIt");
139 // Check single-arc path
141 check(!cp.empty(), "Wrong empty()");
142 check(cp.length() == 1, "Wrong length");
143 check(cp.front() == a1, "Wrong front()");
144 check(cp.back() == a1, "Wrong back()");
145 check(cp.nth(0) == a1, "Wrong nth()");
147 check((tmp_a = ai) == a1, "Wrong nthIt()");
148 check(++ai == INVALID, "Wrong nthIt()");
149 typename P::ArcIt ai2(cp);
150 check((tmp_a = ai2) == a1, "Wrong ArcIt");
151 check(++ai2 == INVALID, "Wrong ArcIt");
152 check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
153 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
154 check(checkPath(cgr, cp), "Wrong checkPath()");
155 PathNodeIt<P> ni2(cgr, cp);
156 check((tmp_n = ni2) == n1, "Wrong PathNodeIt");
157 check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt");
158 check(++ni2 == INVALID, "Wrong PathNodeIt");
160 // Check adding more arcs
163 check(!cp.empty(), "Wrong empty()");
164 check(cp.length() == 3, "Wrong length");
165 check(cp.front() == a1, "Wrong front()");
166 check(cp.back() == a3, "Wrong back()");
167 check(cp.nth(0) == a1, "Wrong nth()");
168 check(cp.nth(1) == a2, "Wrong nth()");
169 check(cp.nth(2) == a3, "Wrong nth()");
170 typename P::ArcIt ai3(cp);
171 check((tmp_a = ai3) == a1, "Wrong ArcIt");
172 check((tmp_a = ++ai3) == a2, "Wrong nthIt()");
173 check((tmp_a = ++ai3) == a3, "Wrong nthIt()");
174 check(++ai3 == INVALID, "Wrong nthIt()");
176 check((tmp_a = ai) == a1, "Wrong nthIt()");
177 check((tmp_a = ++ai) == a2, "Wrong nthIt()");
179 check((tmp_a = ai) == a3, "Wrong nthIt()");
180 check(++ai == INVALID, "Wrong nthIt()");
181 check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
182 check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()");
183 check(checkPath(cgr, cp), "Wrong checkPath()");
184 PathNodeIt<P> ni3(cgr, cp);
185 check((tmp_n = ni3) == n1, "Wrong PathNodeIt");
186 check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt");
187 check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt");
188 check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt");
189 check(++ni3 == INVALID, "Wrong PathNodeIt");
191 // Check arc removal and addition
195 check(!cp.empty(), "Wrong empty()");
196 check(cp.length() == 2, "Wrong length");
197 check(cp.front() == a1, "Wrong front()");
198 check(cp.back() == a2, "Wrong back()");
199 check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
200 check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
201 check(checkPath(cgr, cp), "Wrong checkPath()");
205 check(cp.empty(), "The path is not empty");
206 check(cp.length() == 0, "The path is not empty");
208 // Check inconsistent path
212 check(!cp.empty(), "Wrong empty()");
213 check(cp.length() == 3, "Wrong length");
214 check(cp.front() == a4, "Wrong front()");
215 check(cp.back() == a1, "Wrong back()");
216 check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
217 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
218 check(!checkPath(cgr, cp), "Wrong checkPath()");
221 template <typename P>
222 void checkBackAndFrontInsertablePath() {
224 // Include back insertable test cases
225 checkBackInsertablePath<P>();
227 // Check front and back insertion
233 check(!cp.empty(), "Wrong empty()");
234 check(cp.length() == 3, "Wrong length");
235 check(cp.front() == a3, "Wrong front()");
236 check(cp.back() == a1, "Wrong back()");
237 check(cp.nth(0) == a3, "Wrong nth()");
238 check(cp.nth(1) == a4, "Wrong nth()");
239 check(cp.nth(2) == a1, "Wrong nth()");
240 typename P::ArcIt ai(cp);
241 check((tmp_a = ai) == a3, "Wrong ArcIt");
242 check((tmp_a = ++ai) == a4, "Wrong nthIt()");
243 check((tmp_a = ++ai) == a1, "Wrong nthIt()");
244 check(++ai == INVALID, "Wrong nthIt()");
246 check((tmp_a = ai) == a3, "Wrong nthIt()");
247 check((tmp_a = ++ai) == a4, "Wrong nthIt()");
249 check((tmp_a = ai) == a1, "Wrong nthIt()");
250 check(++ai == INVALID, "Wrong nthIt()");
251 check(pathSource(cgr, cp) == n3, "Wrong pathSource()");
252 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
253 check(checkPath(cgr, cp), "Wrong checkPath()");
255 // Check eraseFront()
258 check(!cp.empty(), "Wrong empty()");
259 check(cp.length() == 3, "Wrong length");
260 check(cp.front() == a4, "Wrong front()");
261 check(cp.back() == a2, "Wrong back()");
262 check(cp.nth(0) == a4, "Wrong nth()");
263 check(cp.nth(1) == a1, "Wrong nth()");
264 check(cp.nth(2) == a2, "Wrong nth()");
265 typename P::ArcIt ai2(cp);
266 check((tmp_a = ai2) == a4, "Wrong ArcIt");
267 check((tmp_a = ++ai2) == a1, "Wrong nthIt()");
268 check((tmp_a = ++ai2) == a2, "Wrong nthIt()");
269 check(++ai2 == INVALID, "Wrong nthIt()");
271 check((tmp_a = ai) == a4, "Wrong nthIt()");
272 check((tmp_a = ++ai) == a1, "Wrong nthIt()");
274 check((tmp_a = ai) == a2, "Wrong nthIt()");
275 check(++ai == INVALID, "Wrong nthIt()");
276 check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
277 check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
278 check(checkPath(cgr, cp), "Wrong checkPath()");
281 template <typename P>
282 void checkSubscriptOperator() {
288 check(!p.empty(), "Wrong empty()");
289 check(p.length() == 3, "Wrong length");
290 check(p.front() == a1, "Wrong front()");
291 check(p.back() == a2, "Wrong back()");
292 check(p.nth(0) == a1, "Wrong nth()");
293 check(p.nth(1) == a3, "Wrong nth()");
294 check(p.nth(2) == a2, "Wrong nth()");
295 check(p[0] == a1, "Wrong operator[]");
296 check(p[1] == a3, "Wrong operator[]");
297 check(p[2] == a2, "Wrong operator[]");
300 void checkListPathSplitAndSplice() {
302 // Build a path with spliceFront() and spliceBack()
303 ListPath<GR> p1, p2, p3, p4;
310 check(p1.length() == 4, "Wrong length");
311 check(p1.front() == a1, "Wrong front()");
312 check(p1.back() == a4, "Wrong back()");
313 ListPath<GR>::ArcIt ai(p1);
314 check((tmp_a = ai) == a1, "Wrong ArcIt");
315 check((tmp_a = ++ai) == a2, "Wrong nthIt()");
316 check((tmp_a = ++ai) == a3, "Wrong nthIt()");
317 check((tmp_a = ++ai) == a4, "Wrong nthIt()");
318 check(++ai == INVALID, "Wrong nthIt()");
319 check(checkPath(cgr, p1), "Wrong checkPath()");
322 p1.split(p1.nthIt(2), p2);
323 check(p1.length() == 2, "Wrong length");
325 check((tmp_a = ai) == a1, "Wrong ArcIt");
326 check((tmp_a = ++ai) == a2, "Wrong nthIt()");
327 check(++ai == INVALID, "Wrong nthIt()");
328 check(checkPath(cgr, p1), "Wrong checkPath()");
329 check(p2.length() == 2, "Wrong length");
331 check((tmp_a = ai) == a3, "Wrong ArcIt");
332 check((tmp_a = ++ai) == a4, "Wrong nthIt()");
333 check(++ai == INVALID, "Wrong nthIt()");
334 check(checkPath(cgr, p2), "Wrong checkPath()");
336 // Check split() and splice()
338 p1.split(p1.nthIt(2), p2);
339 p2.split(p2.nthIt(1), p3);
341 p2.splice(p2.nthIt(1), p3);
342 check(p2.length() == 4, "Wrong length");
343 check(p2.front() == a1, "Wrong front()");
344 check(p2.back() == a4, "Wrong back()");
346 check((tmp_a = ai) == a1, "Wrong ArcIt");
347 check((tmp_a = ++ai) == a2, "Wrong nthIt()");
348 check((tmp_a = ++ai) == a3, "Wrong nthIt()");
349 check((tmp_a = ++ai) == a4, "Wrong nthIt()");
350 check(++ai == INVALID, "Wrong nthIt()");
351 check(checkPath(cgr, p2), "Wrong checkPath()");
359 CheckPathFunctions cpf;